概述
Nginx的配置中有一个参数:underscores_in_headers,这个参数默认值为:off,意思是默认忽略名称带下划线的 HTTP Header头部信息,也就是说带下划线的 HTTP Header会被Nginx直接忽略,不会向后端upstream转发。
这里面是不会出现带下划线的HTTP Header的,除非开发人员自定义。所以Nginx官方默认是关闭的。
但是总会有些开发人员不小心使用了带下划线的HTTP Header,就会碰触这个坑。
为了绕开这个坑,我们做如下的实验来验证。
验证
我们使用Python(Flask)写了一个小web程序,Flask代码如下
from flask import Flask, request, json
app = Flask(__name__)
@app.route('/post', methods=['POST'])
def register():
print('===request header: ')
print(request.headers)
if 'application/json' in request.headers['Content-Type']:
print('===recevied Content-Type: application/json')
print(request.json)
else:
print('===stream read')
print(request.stream.read())
print(request.data)
return 'OK'
if __name__ == '__main__':
app.run(host="0.0.0.0", port=15000, debug=True)
然后我们使用PostMan向Flask的15000端口发请求,HTTP Header头如下
输出如下
===request header:
X-Real-Ip: 202.102.134.68
My-Oc2: sbac_6
Myoc1: v_34
Content-Type: application/json
User-Agent: PostmanRuntime/7.28.4
Accept: */*
Postman-Token: 1e092bc1-075e-42f6-8d28-ff94bf95885a
Host: 10.140.100.22:16000
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Length: 28
===recevied Content-Type: application/json
{'name': 'abc', 'value': 14}
我们可以看到 X_REAL_IP 被转换成X-Real-Ip, 内容值没有变化;My_OC2被转换成My-Oc2,内容值也没有变化;MyOC1被转换成Myoc1,内容值没有变化。
然后我们套上nginx,默认情况不开启underscores_in_headers,得到如下结果:
===request header:
Host: 10.140.100.22
X-Forwarded-For: 10.255.204.21
Connection: close
Content-Length: 28
Myoc1: v_34
Content-Type: application/json
User-Agent: PostmanRuntime/7.28.4
Accept: */*
Postman-Token: c5cc127c-203b-4500-aeb6-3cada9b484df
Accept-Encoding: gzip, deflate, br
我们发现X_REAL_IP 、My_OC2 这两个Header直接被nginx删掉了,MyOC1传递到Flask被转换成Myoc1,内容值没有变化。
我们打开nginx中underscores_in_headers的开关,设置为on,结果如下:
===request header:
Host: 10.140.100.22
X-Forwarded-For: 10.255.204.21
Connection: close
Content-Length: 28
X-Real-Ip: 202.102.134.68
My-Oc2: sbac_6
Myoc1: Vv_34
Content-Type: application/json
User-Agent: PostmanRuntime/7.28.4
Accept: */*
Postman-Token: 729b414b-e4fb-46a7-88ed-ebf3825e2761
Accept-Encoding: gzip, deflate, br
我们看到这些字段又出现了。
结论
默认情况下underscores_in_headers是关闭的,nginx会自动删除HTTP Header头部字段中名称带下划线的字段。字段内容值出现下划线不受影响。
HTTP Header头部的结构为 (Name:Value),只有当Name包含下划线才会删除,Value中包含下划线不会删除。
资料
http://nginx.org/en/docs/http/ngx_http_core_module.html#underscores_in_headers