类似于https://github.com/fenggolang/go-proxy,提供github代理转发服务,提供GitHub 文件 , Releases , archive , gist , raw.githubusercontent.com 文件代理加速下载服务.
package main import ( "fmt" "io" "io/ioutil" "net/http" "regexp" "strings" ) type Proxy struct{} func (p *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) { fmt.Println("Request:", r.URL.String()) if strings.Count(r.URL.String(), "http") == 0 { return } re1, _ := regexp.Compile("^/((https:|http:)//github\\.com)/") re2, _ := regexp.Compile("^/((https:|http:)//raw\\.(githubusercontent|github)\\.com)/") params1 := re1.FindStringSubmatch(r.URL.String()) params2 := re2.FindStringSubmatch(r.URL.String()) if len(params1) <= 0 && len(params2) <= 0 { return } // 第一步: 代理接受到客户端的请求,复制原来的请求对象,并根据数据配置新请求的各种参数(添加上X-Forward-For头部等) body, err := ioutil.ReadAll(r.Body) if err != nil { fmt.Print("io.ReadFull(r.Body, body) ", err.Error()) //return,没有数据也是可以的,不需要直接结束 } reqUrl := strings.Replace(r.URL.String(), "/", "", 1) // reqUrl = strings.Replace(reqUrl, ":/", "://", 1) fmt.Println(reqUrl) req, err := http.NewRequest(r.Method, reqUrl, strings.NewReader(string(body))) if err != nil { fmt.Print("http.NewRequest ", err.Error()) return } for k, v := range r.Header { req.Header.Set(k, v[0]) } reqHost := strings.Split(reqUrl, "//")[1] reqHost = strings.Split(reqHost, "/")[0] fmt.Println("reqHost:", reqHost) req.Host = reqHost req.URL.Host = reqHost // 第二步: 把新请求复制到服务器端,并接收到服务器端返回的响应 //transport := http.DefaultTransport // res, err := transport.RoundTrip(req) // if err != nil { // fmt.Println("transport err:" + err.Error()) // w.WriteHeader(http.StatusBadGateway) // 502 // return // } cli := &http.Client{} res, err := cli.Do(req) if err != nil { fmt.Print("cli.Do(req) ", err.Error()) return } // 第三步:代理服务器对响应做一些处理,然后返回给客户端 for key, value := range res.Header { for _, v := range value { w.Header().Add(key, v) } } w.WriteHeader(res.StatusCode) io.Copy(w, res.Body) res.Body.Close() } func main() { fmt.Println("Serve on :80") s := &http.Server{ Addr: "127.0.0.1:80", Handler: &Proxy{}, } s.ListenAndServe() }