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⊙)?



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM