一 修改发往上游的请求
重点: 利用指令'更改'转发给上游服务器的'HTTP报文'的内容
1) 请求'行' --> 'proxy_method'、'url'、'proxy_http_version'
2)请求'头' --> 'proxy_set_header'、'proxy_pass_request_headers'
3)请求'体' --> 'proxy_pass_request_body'、'proxy_set_body'
思考: 有'哪些'指令?
(1)生成发往上游的请求行
① proxy_method
场景: 上游服务器可能'不支持'某些请求方法,需要nginx进行'转换'下
② 关于最终发往上游的url参见
③ proxy_http_version
1) http1.0'不支持'长连接
2) http1.0 短连接'有'大量的TIME_WAIT'
upstream sent invalid chunked response while reading upstream
Transfer-encoding chunked 分块编码传输
(2)生成发往上游的请求头
① proxy_set_header
1)基本描述
proxy_set_header 就是'设置请求头',并将头信息'传递'到'后端服务器';
重点:'子域'要么'全部继承',要么'全部覆盖'
场景: 允许'修改'、'新增'、'删除'转发给'上游'请求头
2)官方解读
说明: nginx默认会修改'Host'头,很显然'不符合'我们的要求
注意: proxy_set_header有'上下文',会'覆盖'父作用域的'proxy_set_header'
补充: 经常出现'proxy_set_header'作用域覆盖,导致'不生效'的场景
3)请求头的问题
proxy_set_header Host $http_host;
1)如果客户端请求头中没有携带'Host'这个头部,那么传递到后端服务器的请求也'不含'这个头部
proxy_set_header Host $host;
2) 这种情况下,'更好的方式'是使用'$host变量'
特点:它的值在'请求包含Host请求头'时为"Host"字段的值;在请求"未携带Host请求"时为虚拟主机的'server_name'
说明:一般用'$host'代替'$http_host'变量,避免http请求中在'丢失Host'头的情况下,Host不被重写的失误
4)长连接
proxy_http_version 1.1;
proxy_set_header Connection ""; -->"等价" proxy_set_header Connection "keepalive"
特点: HTTP1.1'默认(不传递Connection)'就是'长'连接
5)长连接的应用
nginx支持websocket配置
1) nginx 'websocket配置' 配置
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
2)chunk'分块'传输
6)最佳实践
proxy_set_header Host $host:$server_port; # '重写'请求头
proxy_set_header X-Real-IP $remote_addr; # '添加新请求头'
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # '添加新请求头'
备注: $proxy_add_x_forwarded_for = $http_x_forwarded_for, $remote_addr
proxy_set_header权威参考
注意事项
② proxy_pass_request_headers
proxy_pass_request_headers off与ngx.req.set_header结合的坑
proxy_force_ranges应用场景
③ ignore_invalid_headers
说明: nginx 默认'识别' 请求header filed为'英文字母、数字、连接符',这些是'有效'的
备注: 这个是'nginx'在处理原始'请求头'阶段,不是'content'阶段的'proxy'模块指令
补充: 放到这里是因为也是'请求头'相关的
特点: 该配置值为'off'时,nginx会丢弃'不合法(带有下划线)'的HTTP请求头
④ underscores_in_headers
++++++++++ '历史背景' ++++++++++
nginx会'默认删除带下划线'的HTTP请求头,这样做是为了避免将标头'映射到CGI变量'时出现'歧义'
nginx反向代理导致请求header头信息丢失
请求头带下划线导致原始请求头丢失
(3)生成发往上游的请求体
① proxy_pass_request_body
功能:是否将'客户端请求体'发送给'代理'服务器
② proxy_set_body
细节点: 如果'proxy_pass_request_body off'则'proxy_set_body'无效
关注: value的形式,尤其是符合'json、yaml、xml'格式
强调: 会'覆盖'原始的,'重新'生成'新的'请求体
生成json的案例