英文:
Understand Go proxy failures when routing
问题
我有一个简单的Go代理,像这样。我想通过代理将请求转发到它,并修改某些网站的响应。这些网站在TLS上运行,但我的代理只是一个本地服务器。
func main() {
target, _ := url.Parse("https://www.google.com")
proxy := httputil.NewSingleHostReverseProxy(target)
proxy.ModifyResponse = rewriteBody
http.Handle("/", proxy)
http.ListenAndServe(":80", proxy)
}
根据我的理解,代理服务器会发起请求并关闭请求,然后在修改后返回响应。我不确定这里会出现什么问题。关于转发标头,我是否遗漏了一些内容?
编辑
我已经使路由工作正常。最初,我对修改响应感兴趣,但除了看到Magical
标头外,没有看到任何变化。
func modifyResponse() func(*http.Response) error {
return func(resp *http.Response) error {
resp.Header.Set("X-Proxy", "Magical")
b, _ := ioutil.ReadAll(resp.Body)
b = bytes.Replace(b, []byte("About"), []byte("Modified String Test"), -1) // replace html
body := ioutil.NopCloser(bytes.NewReader(b))
resp.Body = body
resp.ContentLength = int64(len(b))
resp.Header.Set("Content-Length", strconv.Itoa(len(b)))
resp.Body.Close()
return nil
}
}
func main() {
target, _ := url.Parse("https://www.google.com")
proxy := httputil.NewSingleHostReverseProxy(target)
director := proxy.Director
proxy.Director = func(r *http.Request) {
director(r)
r.Host = r.URL.Hostname()
}
proxy.ModifyResponse = modifyResponse()
http.Handle("/", proxy)
http.ListenAndServe(":80", proxy)
}
英文:
I have a simple Go proxy like so. I want to proxy requests through to it and modify the responses of certain websites. These websites run over TLS, but my proxy is just a local server.
func main() {
target, _ := url.Parse("https://www.google.com")
proxy := httputil.NewSingleHostReverseProxy(target)
proxy.ModifyResponse = rewriteBody
http.Handle("/", proxy)
http.ListenAndServe(":80", proxy)
}
Result: 404 error as shown in the following screenshot:
From my understanding, the proxy server would initiate the request and close the request, then return the response after modification. I'm not sure what would fail here. Am I missing something w.r.t to forwarding headers to where this request is failing?
Edit
I've gotten the routing working. Originally, I was interested in modifying the response, but not seeing any change except I see the Magical
header.
func modifyResponse() func(*http.Response) error {
return func(resp *http.Response) error {
resp.Header.Set("X-Proxy", "Magical")
b, _ := ioutil.ReadAll(resp.Body)
b = bytes.Replace(b, []byte("About"), []byte("Modified String Test"), -1) // replace html
body := ioutil.NopCloser(bytes.NewReader(b))
resp.Body = body
resp.ContentLength = int64(len(b))
resp.Header.Set("Content-Length", strconv.Itoa(len(b)))
resp.Body.Close()
return nil
}
}
func main() {
target, _ := url.Parse("https://www.google.com")
proxy := httputil.NewSingleHostReverseProxy(target)
director := proxy.Director
proxy.Director = func(r *http.Request) {
director(r)
r.Host = r.URL.Hostname()
}
proxy.ModifyResponse = modifyResponse()
http.Handle("/", proxy)
http.ListenAndServe(":80", proxy)
}
答案1
得分: 1
关键问题在文档中提到,但从文档中并不清楚如何确切处理它:
> NewSingleHostReverseProxy不会重写Host标头。要重写Host标头,请直接使用ReverseProxy并使用自定义的Director策略。
https://pkg.go.dev/net/http/httputil#NewSingleHostReverseProxy
您不必直接使用ReverseProxy
。您仍然可以使用NewSingleHostReverseProxy
并调整Director
函数,如下所示:
func main() {
target, _ := url.Parse("https://www.google.com")
proxy := httputil.NewSingleHostReverseProxy(target)
director := proxy.Director
proxy.Director = func(r *http.Request) {
director(r)
r.Host = r.URL.Hostname() // 调整Host
}
http.Handle("/", proxy)
http.ListenAndServe(":80", proxy)
}
希望对您有所帮助!
英文:
The critical problem is mentioned in the documentation, but it's not clear from the documentation how to deal with it exactly:
> NewSingleHostReverseProxy does not rewrite the Host header. To rewrite
> Host headers, use ReverseProxy directly with a custom Director policy.
https://pkg.go.dev/net/http/httputil#NewSingleHostReverseProxy
You don't have the use ReverseProxy
directly. You can still use NewSingleHostReverseProxy
and adapt the Director
function like this:
func main() {
target, _ := url.Parse("https://www.google.com")
proxy := httputil.NewSingleHostReverseProxy(target)
director := proxy.Director
proxy.Director = func(r *http.Request) {
director(r)
r.Host = r.URL.Hostname() // Adjust Host
}
http.Handle("/", proxy)
http.ListenAndServe(":80", proxy)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论