Moh*_*ana 3 https proxy reverse-proxy go
问题:
req.Host = req.URL.Host会导致它失败。而不是返回{"Code":"OBRI.FR.Request.Invalid","Id":"c37baec213dd1227","Message":"An error happened when parsing the request arguments","Errors":[{"ErrorCode":"UK.OBIE.Header.Missing","Message":"Missing request header 'x-fapi-financial-id' for method parameter of type String","Url":"https://docs.ob.forgerock.financial/errors#UK.OBIE.Header.Missing"}]}
它返回一个404.httputil. NewSingleHostReverseProxy当我取消注释该行时,我想跟踪代理返回的调用
req.Host = req.URL.Host。鉴于这样的请求:
$ curl http://localhost:8989/open-banking/v2.0/accounts
Run Code Online (Sandbox Code Playgroud)
以及下面的代码 ( main.go):
package main
import (
"log"
"net/http"
"net/http/httputil"
"net/url"
)
func main() {
target, err := url.Parse("https://rs.aspsp.ob.forgerock.financial:443")
log.Printf("forwarding to -> %s%s\n", target.Scheme, target.Host)
if err != nil {
log.Fatal(err)
}
proxy := httputil.NewSingleHostReverseProxy(target)
http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
// /sf/ask/2661153421/
// https://forum.golangbridge.org/t/explain-how-reverse-proxy-work/6492/7
// /sf/ask/2432195811/
req.Host = req.URL.Host // if you remove this line the request will fail... I want to debug why.
proxy.ServeHTTP(w, req)
})
err = http.ListenAndServe(":8989", nil)
if err != nil {
panic(err)
}
}
Run Code Online (Sandbox Code Playgroud)
将 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))
}
Run Code Online (Sandbox Code Playgroud)
该程序的输出如下所示:
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
Run Code Online (Sandbox Code Playgroud)
或者,在删除 req.Host 分配后:
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
Run Code Online (Sandbox Code Playgroud)
由于 Web 服务器经常使用 Host 标头将请求路由到正确的虚拟主机或后端服务器,因此意外的 Host 标头(上例中的“localhost:8989”)导致服务器以 404 响应是有道理的。
使用 httputil.ReverseProxy 设置 Host 标头通常使用以下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))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2843 次 |
| 最近记录: |