Go 如何调试httputil.NewSingleHostReverseProxy
问题:Go 如何调试httputil.NewSingleHostReverseProxy,go,https,proxy,reverse-proxy,Go,Https,Proxy,Reverse Proxy,问题: 我正转向一个HTTPS地址 我想知道为什么要搬走 req.Host=req.URL.Host导致它失败。而不是返回{“code”:“OBRI.FR.Request.Invalid”,“Id”:“c37baec213dd1227”,“Message”:“解析请求参数时出错”,“Errors”:[{“ErrorCode”:“UK.OBIE.Header.Missing”,“Message”:“Missing Request Header'x-fapi-financial-Id'用于字符串类型
req.Host=req.URL.Host
导致它失败。而不是返回{“code”:“OBRI.FR.Request.Invalid”,“Id”:“c37baec213dd1227”,“Message”:“解析请求参数时出错”,“Errors”:[{“ErrorCode”:“UK.OBIE.Header.Missing”,“Message”:“Missing Request Header'x-fapi-financial-Id'用于字符串类型的方法参数”,“Url”:”"https://docs.ob.forgerock.financial/errors#UK.OBIE.Header.Missing“}]}
它返回一个404
req.Host=req.URL.Host
时,httputil.NewSingleHostReverseProxy正在生成$ curl http://localhost:8989/open-banking/v2.0/accounts
下面的代码(main.go
):
将proxy.Transport字段设置为在委托给默认传输之前转储请求的实现:
package main
import (
"fmt"
"log"
"net/http"
"net/http/httputil"
"net/url"
)
type DebugTransport struct{}
func (DebugTransport) RoundTrip(r *http.Request) (*http.Response, error) {
b, err := httputil.DumpRequestOut(r, false)
if err != nil {
return nil, err
}
fmt.Println(string(b))
return http.DefaultTransport.RoundTrip(r)
}
func main() {
target, _ := url.Parse("https://example.com:443")
log.Printf("forwarding to -> %s\n", target)
proxy := httputil.NewSingleHostReverseProxy(target)
proxy.Transport = DebugTransport{}
http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
req.Host = req.URL.Host
proxy.ServeHTTP(w, req)
})
log.Fatal(http.ListenAndServe(":8989", nil))
}
此程序的输出如下所示:
2018/10/26 13:06:35 forwarding to -> https://example.com:443
GET / HTTP/1.1
Host: example.com:443
User-Agent: HTTPie/0.9.4
Accept: */*
Accept-Encoding: gzip, deflate
X-Forwarded-For: 127.0.0.1
或者,在删除请求主机分配后:
2018/10/26 13:06:54 forwarding to -> https://example.com:443
GET / HTTP/1.1
Host: localhost:8989
User-Agent: HTTPie/0.9.4
Accept: */*
Accept-Encoding: gzip, deflate
X-Forwarded-For: 127.0.0.1
由于Web服务器经常使用主机头将请求路由到正确的虚拟主机或后端服务器,因此,意外的主机头(“上例中的localhost:8989”)会导致服务器以404响应是有道理的
使用httputil.ReverseProxy设置主机头通常通过Director
功能完成:
target, err := url.Parse("https://example.com:443")
if err != nil {
log.Fatal(err)
}
log.Printf("forwarding to -> %s\n", target)
proxy := httputil.NewSingleHostReverseProxy(target)
d := proxy.Director
proxy.Director = func(r *http.Request) {
d(r) // call default director
r.Host = target.Host // set Host header as expected by target
}
log.Fatal(http.ListenAndServe(":8989", proxy))
target, err := url.Parse("https://example.com:443")
if err != nil {
log.Fatal(err)
}
log.Printf("forwarding to -> %s\n", target)
proxy := httputil.NewSingleHostReverseProxy(target)
d := proxy.Director
proxy.Director = func(r *http.Request) {
d(r) // call default director
r.Host = target.Host // set Host header as expected by target
}
log.Fatal(http.ListenAndServe(":8989", proxy))