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

时间:2017-09-19 10:26:08

标签: http go http-headers

转到版本: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)

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

1 个答案:

答案 0 :(得分:4)

如果您希望透明地代理请求,您可能会对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)

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

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