一 修改发往上游的请求
- 重点: 利用指令'更改'转发给上游服务器的'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)生成发往上游的请求行
场景: 上游服务器可能'不支持'某些请求方法,需要nginx进行'转换'下
- 1) http1.0'不支持'长连接
-
- 2) http1.0 短连接'有'大量的TIME_WAIT'
upstream sent invalid chunked response while reading upstream
Transfer-encoding chunked 分块编码传输
(2)生成发往上游的请求头
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)长连接的应用
- 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_pass_request_headers off与ngx.req.set_header结合的坑
- 说明: nginx 默认'识别' 请求header filed为'英文字母、数字、连接符',这些是'有效'的
-
- 备注: 这个是'nginx'在处理原始'请求头'阶段,不是'content'阶段的'proxy'模块指令
-
- 补充: 放到这里是因为也是'请求头'相关的
特点: 该配置值为'off'时,nginx会丢弃'不合法(带有下划线)'的HTTP请求头
- ++++++++++ '历史背景' ++++++++++
-
- nginx会'默认删除带下划线'的HTTP请求头,这样做是为了避免将标头'映射到CGI变量'时出现'歧义'
(3)生成发往上游的请求体
功能:是否将'客户端请求体'发送给'代理'服务器
- 细节点: 如果'proxy_pass_request_body off'则'proxy_set_body'无效
-
- 关注: value的形式,尤其是符合'json、yaml、xml'格式
-
- 强调: 会'覆盖'原始的,'重新'生成'新的'请求体