起因
同事请求第三方接口,需要传送的header需要区分大小写。如:
然而第三方说接收到的header全部变成小写了,签名验证不通过。。。
于是找遍了各种有可能导致异常的情况,最后发现是请求协议的问题。如果不指定协议,双方连接会默认使用双方都支持的最高协议进行数据传输。
http1.* http/2 header区别
从上文可知,HTTP/2 和 HTTP/1.x 同样使用 ASCII 字符集,但 HTTP/2 头部必须使用小写,而不像 HTTP/1.x 大小写均可。也正是碰上终端业务代码实现不严谨,引发上述问题。
解决方法
由于go http请求如果不指定http.Transport,默认会检测服务端是否支持http2,如果支持的话会使用http2,所以请求的header会全部转为小写,导致了这个问题。
最后验证问题:
header := make(http.Header)
header[`accessToken`] = []string{"test"}
request, err := http.NewRequest("GET", "https://nghttp2.org", nil)
if err != nil {
panic(err)
}
//关键代码,如果没有这个设置,默认走的时候http2,有的话会走http1.1
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
request.Header = make(http.Header)
request.Header = header
request.Header.Set("Content-Type", "application/json;charset=UTF-8") //添加请求头
client := http.Client{
Timeout: time.Second * 10,
Transport: tr,
}
//创建客户端
resp, err := client.Do(request.WithContext(context.TODO())) //发送请求
if resp == nil && err != nil {
panic(err)
}
//_, _ := ioutil.ReadAll(resp.Body)
fmt.Println("====", resp.Proto)