From 39c0c5cb45c76c101c757e21b80491790469ee7e Mon Sep 17 00:00:00 2001 From: Axetroy Date: Sat, 8 Jan 2022 02:13:28 +0800 Subject: [PATCH] feat: support cusom proxy --- README.md | 11 +++++++++++ README_en-US.md | 11 +++++++++++ proxy.go | 25 ++++++++++++++++++++++--- 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 92200a0..91230dc 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,17 @@ openssl req -new -x509 -sha256 -key server.key -out server.pem -days 3650 forward --tls-cert-file=server.pem --tls-key-file=server.key http://example.com ``` +2. 自定义代理请求 + +```bash +# 代理 https://github.com +forward https://github.com +# 发起请求 +curl http://0.0.0.0:80/api # 实际请求 https://github.com/api +# 发起自定义代理 +curl -H "X-Proxy-Target: https://www.google.com" http://0.0.0.0/api # 实际请求 https://www.google.com/api +``` + ### 开源许可 The [MIT License](LICENSE) diff --git a/README_en-US.md b/README_en-US.md index bdd715c..c97129d 100644 --- a/README_en-US.md +++ b/README_en-US.md @@ -82,6 +82,17 @@ openssl req -new -x509 -sha256 -key server.key -out server.pem -days 3650 forward --tls-cert-file=server.pem --tls-key-file=server.key http://example.com ``` +2. Custom proxy + +```bash +# proxy https://github.com +forward https://github.com +# send request +curl http://0.0.0.0:80/api # request https://github.com/api +# send custom request +curl -H "X-Proxy-Target: https://www.google.com" http://0.0.0.0/api # request https://www.google.com/api +``` + ### License The [MIT License](LICENSE) diff --git a/proxy.go b/proxy.go index 86db4f0..63b1b80 100644 --- a/proxy.go +++ b/proxy.go @@ -27,6 +27,12 @@ var ( regIntegrity = regexp.MustCompile(`\sintegrity="[^"]+"`) ) +const ( + headerXProxyTarget = "X-Proxy-Target" + headerXOriginHost = "X-Origin-Host" + headerXProxyClient = "X-Proxy-Client" +) + type ProxyServer struct { *ProxyServerOptions proxy *httputil.ReverseProxy @@ -149,9 +155,22 @@ func (p *ProxyServer) modifyRequest(req *http.Request) { target = *u } } + } else if req.Header.Get(headerXProxyTarget) != "" { + targetUrl := req.Header.Get(headerXProxyTarget) + + if u, err := url.Parse(targetUrl); err == nil { + if u.Scheme == "" { + if p.UseSSL { + u.Scheme = "https" + } else { + u.Scheme = "http" + } + } + target = *u + } } - req.Header.Set("X-Origin-Host", req.Host) + req.Header.Set(headerXOriginHost, req.Host) req.Host = target.Host if isProxyUrl { req.URL = &target @@ -205,7 +224,7 @@ func (p *ProxyServer) modifyResponse(res *http.Response) error { } } - proxyHost := res.Request.Header.Get("X-Origin-Host") // localhost:8080 or localhost + proxyHost := res.Request.Header.Get(headerXOriginHost) // localhost:8080 or localhost var hostName string @@ -221,7 +240,7 @@ func (p *ProxyServer) modifyResponse(res *http.Response) error { hostName = proxyHost } - res.Header.Set("X-Proxy-Client", "Forward-Cli") + res.Header.Set(headerXProxyClient, "Forward-Cli") res.Header.Del("Expect-CT") // disable cache