问题:直接在Header中设置Host是否可以生效?
问题背景:需要区分Host调用不同环境的接口,但Host设置有问题导致接口调用失败
服务端代码示例
func StartServer(addr string) error {
http.HandleFunc("/hello", SayHello)
if err := http.ListenAndServe(addr, nil); err != nil {
return err
}
return nil
}
func SayHello(rsp http.ResponseWriter, req *http.Request) {
fmt.Printf("get request %s to %s \n", req.RemoteAddr, req.Host)
// response
rsp.WriteHeader(200)
if _, err := rsp.Write([]byte("request received")); err != nil {
// deal with "write" error
}
}
客户端代码示例
func DoRequest(url string) (*http.Response, error) {
client := &http.Client{}
request, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
return nil, err
}
// request.Header.Set("Host", "specific-host") //错误方式
request.Host = "specific-host"
rsp, err := client.Do(request)
if err != nil {
return nil, err
}
return rsp, nil
}
尝试以下两种方式设置Host字段并发起请求
request.Header.Set("Host", "specific-host")
// 响应结果:get request 127.0.0.1:40280 to 127.0.0.1:11010
// 不符合预期
request.Host = "specific-host"
// 响应结果:get request 127.0.0.1:40293 to specific-host
// 符合预期
结论:直接通过header设置Host无法生效,需要设置Request中的Host成员
扫一下源码:
Request将Host从Header中独立出来
type Request struct {
// For client requests, certain headers such as Content-Length
// and Connection are automatically written when needed and
// values in Header may be ignored. See the documentation
// for the Request.Write method.
Header Header
// For client requests, Host optionally overrides the Host
// header to send. If empty, the Request.Write method uses
// the value of URL.Host. Host may contain an international
// domain name.
Host string
}
调用do方法时,根据req内容设置Host字段;服务端接收到的request可以读到Host,如上响应内容部分的“127.0.0.1:11010”和“specific-host”
func (c *Client) do(req *Request) (retres *Response, reterr error) {
...
host := ""
if req.Host != "" && req.Host != req.URL.Host {
// If the caller specified a custom Host header and the
// redirect location is relative, preserve the Host header
// through the redirect. See issue #22233.
if u, _ := url.Parse(loc); u != nil && !u.IsAbs() {
host = req.Host
}
}
ireq := reqs[0]
req = &Request{
Host: host,
...
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)