一次 Nginx proxy_set_header 故障问题解析和延升
2021-01-07 21:43
961 查看
目录二、扩展-各种情况对比 proxy_set_header 其他项等 三、扩展 ->脚本 python 获取请求所有数据信息脚本
本文会先由一个问题引入,然后再进行多种情况进行分析。
一、问题和排查步骤
1.1 问题基本信息
我们应用程序从代码层面收到的 Header 中的 Host 的值是
upstream的 名称。 我们程序是需要获取到实际的值。所以这里存在一个问题。
我们先看看我们的
nginx配置。
upstream open-hz8443{ server 10.60.6.184:8000 max_fails=1 fail_timeout=3s weight=10; } server{ server_name 192.168.80.132; listen 80; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 3s; proxy_read_timeout 120s; proxy_send_timeout 120s; proxy_next_upstream error timeout invalid_header http_404 http_502 http_504 http_500; location / { proxy_pass http://open-hz8443; } location ^~ /wss/v1 { proxy_pass http://open-hz8443; proxy_set_header Connection "upgrade"; proxy_set_header Upgrade $http_upgrade;tcp_nodelay on; } }
我们请求
http://192.168.80.132/wss/v1, 我们可以在后端(
10.60.6.184:8000)获取到 Host 的值为
open-hz8443。
这个是我们做了一个 脚本,用于获取请求的所有的数据的。 脚本具体内容在文末。
Connection: upgrade Host: open-hz8443 # 获取到的Host 是 open-hz8443 Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 FS Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 10.210.20.43 - - [04/Jan/2021 15:54:46] "GET /wss/v1 HTTP/1.0" 200 -
1.2 问题解析
首先这里有知识点:
-
我们在 Server 配了
proxy_set_header Host $host;
, 我们在 location 是只配置了proxy_set_header Connection "upgrade"; proxy_set_header Upgrade $http_upgrade;
我们的 Host 最初我认为是会继承 Server 配置的
proxy_set_header Host $host;
, 但是明显是没有继承的,而是直接拿的upstream
的名称。说明没有继承,那么这里是有一个什么规则? 我们往下看。 -
查询
Nginx
官方文档。http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_header
Allows redefining or appending fields to the request header passed to the proxied server. The value can contain text, variables, and their combinations. These directives are inherited from the previous configuration level if and only if there are no proxy_set_header directives defined on the current level. By default, only two fields are redefined:
大概意思就是当我们没有设置
proxy_set_header
才会从上一层级继承,当我们设置了proxy_set_header
,也就意味着我 56c 们不从上面 server 的proxy_set_header Host $host;
进行继承。那为什么会显示
open-hz8443
, 是因为有一个默认值proxy_set_header Host $proxy_host;
这个
proxy_host
,-
当我们设置了
upstream
的话,也就是上面的例子$proxy_host
就是 upstream的名称值. - 当我们直接使用的
proxy_pass http://10.60.6.184:8000
的话,那么$proxy_host
表示的就是10.60.6.184:8000
1.3、解决办法
在
location ^~ /wss/v1下面增加配置
proxy_set_header Host $host;。
location ^~ /wss/v1 { proxy_pass http://open-hz8443; proxy_set_header Host $host; proxy_set_header Connection "upgrade"; proxy_set_header Upgrade $http_upgrade;tcp_nodelay on; }
二、扩展-各种情况对比
默认两项
proxy_set_header Host $proxy_host;proxy_set_header Connection close;
proxy_set_header 其他项等
< 56c pre>proxy_set_header Connection "upgrade"; proxy_set_header Upgrade $http_upgrade;
Server 设置 proxy_set_header 其他项 | Server 设置 proxy_set_header 默认两项 | location 设置 proxy_set_header 默认两项 | location 设置 proxy_set_header 其他项 | 默认值生效 | 默认值不生效 | ||||||
---|---|---|---|---|---|---|---|---|---|---|---|
1 | 1 | 1 | 1 | 1 继承location | |||||||
1 | 1 | 0 | 1 | 1(不继承Server) | |||||||
1 | 1 | 1 | 0 | 1 继承location | |||||||
1 | 1 | 0 | 0 | 1 继承server | |||||||
1 | 0 | 1 | 0 | 1 继承location | |||||||
1 | 0 | 0 | 0 | 1 默认 | |||||||
1 | 0 | 0 | 11 | 1 默认 | |||||||
1 | 0 | 1 | 1 | 1 继承location | |||||||
0 | 1 | 0 | 0 | 1 继承server | |||||||
0 | 1 | 0 | 1 | 1 默认 | |||||||
0 | 1 | 1 | 0 | 1 继承location | 0 | 1 | 1 | 1 | 1 继承location | ||
0 | 0 | 0 | 1 | 1 默认 | |||||||
0 | 0 | 1 | 0 | 1 继承location | |||||||
0 | 0 | 1 | 1 | 1 继承location | |||||||
0 | 0 | 0 | 0 | 1 默认 |
总结
- location 设置了 proxy_set_header 就不继承,但继承默认值,默认值优先级低于 location设置。
- location 未设置了proxy_set_header ,就往上继承,直到默认值。
只要调用了 proxy_set_header,并没有设置 host 和 connection ,默认重写host、connection两个头。
三、扩展 ->脚本
proxy_set_header $host $proxy_host $http_host 各个变量含义
记录一次 Nginx 配置 proxy_pass 后 返回404问题
python 获取请求所有数据信息脚本
#!/usr/bin/env python import SimpleHTTPServer import SocketServer PORT = 8000 class GetHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): def do_GET(self): print(self.headers) self.send_response(200, "") def do_POST(self): print(self.headers) content_length = self.headers.getheaders('content-length') length = int(content_length[0]) if content_length else 0 print(self.rfile.read(length)) self.send_response(200, "") Handler = GetHandler httpd = SocketServer.TCPServer(("", PORT), Handler) httpd.serve_forever()
相关文章推荐
- NGINX proxy_set_header和X-Forwarded-For问题
- 一次RAC共享磁盘映射问题导致RAC异常重启的故障处理过程
- response.setHeader()下载中文文件名乱码问题
- response.setHeader()设置下载中文文件名乱码问题
- response.setHeader()下载中文文件名乱码问题
- nginx proxy_set_header
- 一次很容易忽略的问题解析json数据
- response.setHeader()下载中文文件名乱码问题
- Nginx proxy_set_header中$proxy_host,$host,$http_host的区别
- XMLHTTP中setRequestHeader参数问题
- XMLHTTP中setRequestHeader参数问题
- express 统一设置 res.setHeader 问题
- response.setHeader()下载中文文件名乱码问题
- nginx proxy_buffer_size 解决后端服务传输数据过多,其实是header过大的问题
- qt 5.0中HeaderView的setResiziMode无法使用的问题
- 记一次FastJSON和Jackson解析json时遇到的中括号问题
- response.setHeader(...)下载中文文件名乱码问题
- response.setHeader(...)下载中文文件名乱码问题(转于九万里——城市夜空‘s Blog)
- 文件下载 response.setHeader()下载中文文件名乱码问题 解决办法
- Nginx proxy_set_header 理解