获取 HTTP 响应的所有标头并在下一个 HTTP 请求中将其发回

vij*_*jay 8 http go http-headers

Go 版本:go1.8.1 windows/amd64

HTTP 请求的示例代码是:

func (c *Client) RoundTripSoap12(action string, in, out Message) error {
    fmt.Println("****************************************************************")
    headerFunc := func(r *http.Request) {
        r.Header.Add("Content-Type", fmt.Sprintf("text/xml; charset=utf-8"))
        r.Header.Add("SOAPAction", fmt.Sprintf(action))
        r.Cookies()
    }
    return doRoundTrip(c, headerFunc, in, out)
}

func doRoundTrip(c *Client, setHeaders func(*http.Request), in, out Message) error {
    req := &Envelope{
        EnvelopeAttr: c.Envelope,
        NSAttr:       c.Namespace,
        Header:       c.Header,
        Body:         Body{Message: in},
    }

    if req.EnvelopeAttr == "" {
        req.EnvelopeAttr = "http://schemas.xmlsoap.org/soap/envelope/"
    }
    if req.NSAttr == "" {
        req.NSAttr = c.URL
    }
    var b bytes.Buffer
    err := xml.NewEncoder(&b).Encode(req)
    if err != nil {
        return err
    }
    cli := c.Config
    if cli == nil {
        cli = http.DefaultClient
    }
    r, err := http.NewRequest("POST", c.URL, &b)
    if err != nil {
        return err
    }
    setHeaders(r)
    if c.Pre != nil {
        c.Pre(r)
    }
    fmt.Println("*************", r)
    resp, err := cli.Do(r)
    if err != nil {
        fmt.Println("error occured is as follows ", err)
        return err
    }
    fmt.Println("response headers are: ", resp.Header.Get("sprequestguid"))
    defer resp.Body.Close()
    if resp.StatusCode != http.StatusOK {
        // read only the first Mb of the body in error case
        limReader := io.LimitReader(resp.Body, 1024*1024)
        body, _ := ioutil.ReadAll(limReader)
        return fmt.Errorf("%q: %q", resp.Status, body)
    }
    return xml.NewDecoder(resp.Body).Decode(out)
Run Code Online (Sandbox Code Playgroud)

我将RoundTripSoap12在相应的 HTTP 客户端上调用该函数。当我第一次发送请求时,我会在 HTTP 响应中得到一些标头,所以这些 HTTP 响应标头应该在我的下一个 HTTP 请求中按原样发送。

Ken*_*ant 8

如果您希望透明地代理请求,您可能对 httputil 包和提供的反向代理示例感兴趣:

https://golang.org/src/net/http/httputil/reverseproxy.go

您可以很容易地将标头从一个请求复制到另一个请求 - 标头是一个单独的对象,如果 r 和 rc 是 http.Requests 并且您不介意它们共享标头(如果您想要独立,您可能需要克隆要求):

rc.Header = r.Header // note shallow copy
fmt.Println("Headers", r.Header, rc.Header)
Run Code Online (Sandbox Code Playgroud)

https://play.golang.org/p/q2KUHa_qiP

或者您可以查看键和值并仅复制某些标头,和/或进行克隆以确保您不共享内存。有关此示例,请参阅此处的 http util 包 - 请参阅上面链接的 reverseproxy.go 中的功能 cloneHeader 和 copyHeader。