Compare commits

2 Commits

Author SHA1 Message Date
fcc45b1b28 change reverse url 2022-03-08 16:50:15 +08:00
b8bce43354 gravatar reverse proxy test 2022-03-08 15:08:20 +08:00

130
main.go
View File

@@ -3,126 +3,26 @@ package main
import ( import (
"fmt" "fmt"
"net/http" "net/http"
"regexp" "net/http/httputil"
"strings" "net/url"
) )
const (
PREFIX = "/"
exp1 = `^(?:https?:\/\/)?github\.com\/.+?\/.+?\/(?:releases|archive)\/.*$`
exp2 = `^(?:https?:\/\/)?github\.com\/.+?\/.+?\/(?:blob|raw)\/.*$`
exp3 = `^(?:https?:\/\/)?github\.com\/.+?\/.+?\/(?:info|git-).*$`
exp4 = `^(?:https?:\/\/)?raw\.(?:githubusercontent|github)\.com\/.+?\/.+?\/.+?\/.+$`
exp5 = `^(?:https?:\/\/)?gist\.(?:githubusercontent|github)\.com\/.+?\/.+?\/.+$`
exp6 = `^(?:https?:\/\/)?github\.com\/.+?\/.+?\/tags.*$`
)
func checkUrl(u string) bool {
for _, exp := range []string{exp1, exp2, exp3, exp4, exp5, exp6} {
if ok, _ := regexp.MatchString(exp, u); ok {
return true
}
}
return false
}
func fetchHandler(w http.ResponseWriter, r *http.Request) { func fetchHandler(w http.ResponseWriter, r *http.Request) {
path := r.URL.Path path := r.URL.Path
if !strings.Contains(path, "/") {
w.WriteHeader(http.StatusNotFound) path = fmt.Sprintf("https://secure.gravatar.com%s", path)
return
fmt.Println("need reverse url: ", path)
rpURL, _ := url.Parse(path)
proxy := httputil.NewSingleHostReverseProxy(rpURL)
director := proxy.Director
proxy.Director = func(r *http.Request) {
director(r)
r.Host = "secure.gravatar.com"
} }
proxy.ServeHTTP(w, r)
path = strings.TrimPrefix(path, "/") // 获取到的URL
path = strings.Replace(path, "https:/", "https://", 1)
match1, _ := regexp.MatchString(exp1, path)
match2, _ := regexp.MatchString(exp2, path)
match3, _ := regexp.MatchString(exp3, path)
match4, _ := regexp.MatchString(exp4, path)
match5, _ := regexp.MatchString(exp5, path)
match6, _ := regexp.MatchString(exp6, path)
if match1 || match5 || match6 || match3 || match4 {
httpHandler(w, r, path)
return
} else if match2 {
path = strings.ReplaceAll(path, "/blob/", "/raw/")
httpHandler(w, r, path)
return
}
http.Error(w, fmt.Sprintf("%s is not support", path), http.StatusOK)
}
func httpHandler(w http.ResponseWriter, r *http.Request, pathname string) {
fmt.Println("Handle: ", pathname)
reqHdrRaw := r.Header
if r.Method == http.MethodOptions && reqHdrRaw.Get("Access-Control-Request-Headers") != "" {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, TRACE, DELETE, HEAD, OPTIONS")
w.Header().Set("Access-Control-Max-Age", "1728000")
w.WriteHeader(http.StatusNoContent)
return
}
if strings.HasPrefix(pathname, "github") {
pathname = "https://" + pathname
}
client := &http.Client{
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
},
}
proxy(w, r, client, pathname)
}
func proxy(w http.ResponseWriter, r *http.Request, client *http.Client, pathname string) {
fmt.Println("Proxy: ", pathname, "Method: ", r.Method)
req, _ := http.NewRequest(r.Method, pathname, r.Body)
for k, v := range r.Header {
req.Header.Set(k, strings.Join(v, ","))
fmt.Println("Header: ", k, ":", strings.Join(v, ","))
}
res, e := client.Do(req)
if e != nil {
fmt.Println("Proxy Error: ", pathname, e)
http.Error(w, e.Error(), http.StatusOK)
return
}
if res.Header.Get("Location") != "" {
location := res.Header.Get("Location")
fmt.Println("Location: ", location)
if checkUrl(location) {
res.Header.Set("Location", PREFIX+location)
} else {
newReq, _ := http.NewRequest(r.Method, location, res.Body)
client.CheckRedirect = nil
proxy(w, newReq, client, location)
return
}
}
res.Header.Set("Access-Control-Expose-Headers", "*")
res.Header.Set("Access-Control-Allow-Origin", "*")
res.Header.Del("Content-Security-Policy")
res.Header.Del("Content-Security-Policy-Report-Only")
res.Header.Del("Clear-Site-Data")
for k, v := range res.Header {
w.Header().Set(k, strings.Join(v, ","))
}
if err := res.Write(w); err != nil {
fmt.Println("Write Response Error: ", pathname, err)
}
fmt.Println("result: ", res.StatusCode)
} }
func main() { func main() {