GoLang|使用net/http的区分大小写的HTTP头信息

425 阅读2分钟

今天,亚马逊网络服务发布了他们服务的一些更新。 特别是,他们为API Gateway增加了一个名为 "使用计划"的功能。 不幸的是,他们似乎引入了一个与以前版本的服务不兼容的变化。

API Gateway允许使用api密钥认证。密钥将使用一个名为x-api-key 的HTTP头传入。 以前,这个头的大小写并不重要。x-api-key X-Api-Key X-API-KEY 然而,在最近的变化之后,API Gateway似乎只接受x-api-key

这对于使用Go的http.Client 的应用程序来说尤其令人沮丧,因为它是Go标准库net/http 的一部分。下面的代码片段可以用来在请求中添加x-api-key 头。

client := &http.Client{}
request, _ := http.NewRequest("GET", "https://someapi/someresource", nil)
request.Header.Set("x-api-key", "somelongapikey2349208759283")
response, _ := client.Do(request)

然而,request.Header.Set(...) 最终会在头的键上调用CanonicalMIMEHeaderKey,在这个例子中是"x-api-key" 。这就把"x-api-key" 转换为"X-Api-Key" 。请注意,request.Header.Add("x-api-key", "somelongapikey2349208759283") 也做了同样的事情。 虽然Go的这种行为很好,但我们需要这个头文件是小写的。

那么,我们怎样才能将标题设置为全小写呢?事实证明,request.Headermap[string][]string 类型的别名。因此,我们可以通过以下代码将头的键设置为小写(或任何我们想要的)。

client := &http.Client{}
request, _ := http.NewRequest("GET", "https://someapi/someresource", nil)
r.Header["x-api-key"] = []string{ "somelongapikey2349208759283" }
response, _ := client.Do(request)

tl;dr;AWS发布了一个向后兼容的API的变化,需要小写的HTTP头。Go标准库将头文件转换为规范的格式。

UPDATE: Reddit用户/u/mwholt指出,这可能与HTTP/2要求小写标头字段有关。

UPDATE: 似乎AWS已经修复了API Gateway的问题。https://forums.aws.amazon.com/thread.jspa?threadID=237153&tstart=0