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'用于字符串类型

问题:

  • 我正转向一个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'用于字符串类型的方法参数”,“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))