前言##

笔者最近时间一直在学习和写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⊙)?


golang中设置Host Header的小Tips的更多相关文章

  1. Golang中设置函数默认参数的优雅实现

    在Golang中,我们经常碰到要设置一个函数的默认值,或者说我定义了参数值,但是又不想传递值,这个在python或php一类的语言中很好实现,但Golang中好像这种方法又不行.今天在看Grpc源码时 ...

  2. lumen中间件中设置响应header

    <?php namespace App\Http\Middleware; use Closure; class BeforeMiddleware { public function handle ...

  3. 原创:C sharp 中 Enum的几点小 Tips

    (1)为什么要使用Enum? ♥ enums枚举是值类型,数据直接存储在栈中,而不是使用引用和真实数据的隔离方式来存储.enum student{a,b,c,d,e},其中enum代表student为 ...

  4. 关于Calendar中设置月份比实际小1的问题

    有如下程序,转化两个字符串数字为date类型,并判断是历史上的星期几,是否同为星期一 代码如下: public static void main(String[] args) throws Parse ...

  5. [转]Golang 中使用 JSON 的小技巧

    taowen是json-iterator的作者. 序列化和反序列化需要处理JSON和struct的关系,其中会用到一些技巧. 原文 Golang 中使用 JSON 的小技巧是他的经验之谈,介绍了一些s ...

  6. 转 jquery怎么在header中设置请求信息

    jquery是js的类库,js本身不能操作header,因为js是在浏览器加载页面过程中才开始执行的 header需要服务器端执行操作 如果是ajax,是可以设置header $.ajax({ url ...

  7. vue2.5.2版本 :MAC设置应用在127.0.0.1:80端口访问; 并将127.0.0.1指向www.yours.com ;问题“ Invalid Host header”

    0.设置自己的host文件,将127.0.0.1指向自己想要访问的域名 127.0.0.1 www.yours.com 1.MAC设置应用在127.0.0.1:80端口访问: config/index ...

  8. Confluence 6 外部小工具在其他应用中设置可信关系

    为了在你的 Confluence 中与其他应用建立外部小工具,我们建议你在 2 个应用之间设置 OAuth 或者信任的应用连接关系.在这个例子中,外部应用为小工具的服务器(服务器提供者)和 Confl ...

  9. Emacs中Golang的设置

    欲善其事,先利其器.下面记录一些使用Emacs24做golang开发中的一些有用设置,备忘用. 一,golang中的代码跳转 emacs24的go-mode中默认用godef-describe,god ...

随机推荐

  1. WebService基于SoapHeader实现安全认证(一)

    本文转载:http://www.cnblogs.com/houleixx/archive/2009/08/22/webservice-soapheader-security.html WebServi ...

  2. 用JAX-WS在Tomcat中公布WebService

    JDK中已经内置了Webservice公布,只是要用Tomcat等Webserver公布WebService,还须要用第三方Webservice框架. Axis2和CXF是眼下最流行的Webservi ...

  3. FragmentStatePagerAdapter.notifyDataSetChanged不刷新页面的解决的方法

    公司做医疗产品的,显示操作用的是android.所以我就用上下两个部分大致是固定的,仅仅有中间会有6个页面的切换,当中会有两个用户的切换.即普通用户和管理员用户,图片能够大致展示一下 其他页面是同样的 ...

  4. Hadoop的辉煌还能延续多久?

    摘要:Hadoop已经成为大数据的代名词.短短几年间,Hadoop从一种边缘技术成为事实上的标准.而另一方面,MapReduce在谷歌已不再显赫.当企业瞩目MapReduce的时候,谷歌好像早已进入到 ...

  5. Excel异常Cannot get a text value from a numeric cell

    POI操作Excel时数据Cell有不同的类型,当我们试图从一个数字类型的Cell读取出一个字符串并写入数据库时,就会出现Cannot get a text value from a numeric ...

  6. C# richTextBox编辑器

    附件:http://files.cnblogs.com/xe2011/CSHARP_RichTextBoxEditor.rar 完整的转到这里 http://www.cnblogs.com/xe201 ...

  7. bash if 表达式

    .bash把[[ $a -lt $b ]]看作一个单独的元素,并且返回一个退出码.退出码0为真,非零为假 例如: a= b=c [[ $a -lt $b ]] echo $? # a小于b为真 [[ ...

  8. linux下安装memcached过程

    前一次已经安装过memcached,没有做记录,太久没有操作了也没有记录有点生疏,做一下笔记,已背后用. 下载文件                            下载memcached服务端, ...

  9. JQuery判断子Iframe 加载完成的技术解决

    当需要我们给当前页面动态创建Iframe子框架的时候,并且同时需要操作子Iframe里的方法的时候,我们发现无法成功实现.这是为什么呢?经小程总结,发现子Iframe还没有来的及加载完成,就去执行里面 ...

  10. js获取元素transform参数得出的个人理解

    之前写页面的时候有试过想用js获取某些元素的translate的数值什么的,但是translate又是transform的子样式(勉强说说),理所当然就是先获取transform样式,再读里面的值. ...