• golang中设置Host Header的小Tips


    前言##

    笔者最近时间一直在学习和写Ruby和Go,尤其是Go,作为云计算时代的标准语言,写起来还是相当有感觉的,难过其会越来越火。

    不过写的过程中,也遇到了一些小问题,本文就是分享关于go语言设置 HTTP请求当中 Host Header的一个小注意事项。

    常规做法##

    通常我们在设置HTTP的Header请求时,一般都是这么做:

    Header.Add("Authentization", "TOKEN")
    Header.Add("Content-Type", "application/json")
    ...
    

    Java, Ruby, Go 都是如此,区别的只是语法不同。但是对于Host Header的处理就不同了。在Go中,如果我们这么写:

    header.Add("Host", "XXXXXXXXX")
    

    那么问题就出来了 —— 也许从请求发送的log中,你看不到任何的错误,但是如果查看服务端的log,你会发现,服务端接受到Host Header并不是你想发送的,而仍然是URL中的Host。

    这是为什么呢?

    为什么Go中Host Header不能这么加?##

    原来Go的设计上是用一个单独的HOST属性来定义此Request属性,参考net/http包中Request.go文件定义的Request结构体:

     	// For server requests Host specifies the host on which the
    // URL is sought. Per RFC 2616, this is either the value of
    // the "Host" header or the host name given in the URL itself.
    // It may be of the form "host:port".
    //
    // For client requests Host optionally overrides the Host
    // header to send. If empty, the Request.Write method uses
    // the value of URL.Host.
    Host string
    

    那么在使用上,如果我们想传一个特定的Host,应该这么做:

    Req.Host="XXXX"
    

    但是,为啥Go就如此特殊呢?

    Go为啥如此特殊?##

    原来从HTTP Spec角度,是不大希望让Host Header可以修改,这里的HOST应该是从URL得到,而不是任意的指定。

    但是考虑到很多场景,尤其是Client Requests,很多时候我们希望能够修改这个HOST参数,来模拟我们的需求,如果Go能响应修改其源码就好了?

    搜一下,发现这个问题也确实有人提过,如下:
    [net/http: Setting custom "Host" request header doesn't have effect #7682](net/http: Setting custom "Host" request header doesn't have effect #7682)

    而结论是:

     I don't think we can safely change the behavior at this point.
    

    最好也只是更新了文档,去掉了关于HOST参数的歧义。

    对Go实现的第三方工具的影响##

    既然go语言没有更改这个需求,为了适应大家的习惯,如果有必要,我们可以这样做一个Workaround:

    if host := header.Get("Host"); host != "" {
    	req.Host = host
    }
    

    而且这也是很多用Go写的工具的通用做法,比如:

    surf

    vegeta

    Contact me ?

    Email: jinsdu@outlook.com

    Blog: http://www.cnblogs.com/jinsdu/

    Github: https://github.com/CarlJi


    童鞋,如果觉得本文还算用心,还算有用,何不点个赞呢(⊙o⊙)?


  • 相关阅读:
    sql语言复习:学院-学生-教师-课程-学习-授课表上的一些操作
    JZOJ6358. 【NOIP2019模拟2019.9.15】小ω的仙人掌
    JZOJ6353. 【NOIP2019模拟】给(ca)
    【CSP-S2019模拟】09.13比赛总结
    【CSP-S2019模拟】09.11比赛总结
    JZOJ6341. 【NOIP2019模拟2019.9.4】C
    JZOJ6344. 【NOIP2019模拟2019.9.7】Huge Counting
    JZOJ6343. 【NOIP2019模拟2019.9.7】Medium Counting
    【随机编号】【 2019 Multi-University Training Contest 8】1008.Andy and Maze
    【吉如一线段树】JZOJ6270. 【省赛模拟8.10】序列
  • 原文地址:https://www.cnblogs.com/jinsdu/p/5161962.html
Copyright © 2020-2023  润新知