Nginx proxy_cache_key and HEAD->GET request

解决Nginx中HEAD请求被错误地转换为GET请求的问题,通过正确配置proxy_cache_convert_head和proxy_cache_methods指令,确保HEAD请求正常处理并独立缓存。

Questions:

I have the following Nginx config:

http {
    ...    
    proxy_cache_path  /var/cache/nginx levels=1:2 keys_zone=one:8m max_size=3000m inactive=600m;
    proxy_temp_path /var/tmp;
    ...

    upstream webhook_staging {
        server 127.0.0.1:4001;
        keepalive 64;
    }    

    location /webhooks/incoming_mails {
        client_max_body_size 60m;
        proxy_set_header     X-Real-IP $remote_addr;
        proxy_set_header     X-Forwarded-For $remote_addr;
        proxy_set_header     X-Forwarded-Proto $scheme;
        proxy_set_header     Host $http_host;
        proxy_set_header     Connection "";
        proxy_http_version   1.1;

        # Does not work for HEAD requests
        #>> proxy_cache one;
        #>> proxy_cache_key      $scheme$host$request_uri;

        proxy_pass           http://webhook_staging;
    }
}

The upstream server is a regular Node.js process. If I activate the proxy_cache_* directives above, a HEAD request is passed a GET request to the upstream server. If I deactivate the directives the HEADrequest is passed as a HEAD request and everything is fine.

Answers:

This question is very old, but it is still relevant and unanswered. I just spend several hours finding a solution to this, Nginx from v .1.9.7, include a new feature which do exactly what you want.

Add this to your config:

proxy_cache_convert_head off;
proxy_cache_methods GET HEAD;
proxy_cache_key $scheme$request_method$proxy_host$request_uri;

The first line disables conversion of the http request, and the second line enables caching of the HEAD requests in addition to GET. Third line add $request_method to the proxy_cache_key, so head requests will be cached as a separate file.

Test:

head请求在proxy_cache_convert_head on情况下,会将请求变成GET请求,并且缓存的是GET的response,而不是HEAD的response。这个可以做一个实验:

8080端口redirect到8081端口

8081端口对应的路由如下:
方法  path  uri

HEAD  /  head.html

GET   /  get.html

分别用HEAD/GET方法请求8080端口,查看获取到的uri是哪个?并且查看缓存,可以知道HEAD请求实际缓存的是GET的response。

然后关闭proxy_cache_convert_head再实验一次。代码自己写。

注意:如果是请求的header中带有鉴权字段,需要注意一下,由于HEAD方法已经被转换成GET方法,所以,如果鉴权方法和请求method相关的话,会导致鉴权失败。之前在给ceph做代理缓存时没有考虑到这个问题,困扰了很久。一直不理解为什么鉴权失败了,原因就是鉴权方法中带有method字段。HEAD转换成GET,导致了鉴权的签名不一致,报403错误。

References:

https://serverfault.com/questions/530763/nginx-proxy-cache-key-and-head-get-request

 

#load_module /usr/share/nginx/modules/ngx_stream_module.so; #user appyw; worker_processes 1; error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; proxy_hide_header X-Powered-By; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log logs/host.access.log main; sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 65; client_max_body_size 10m; #gzip_static on; server { server_tokens off; autoindex off; allow 127.0.0.1; allow 172.23.16.0/24; allow 172.23.68.219; allow 172.23.228.56; allow 218.76.15.23; allow ::1; deny all; listen 18081; listen 443 ssl; server_name localhost; if ($request_method !~ ^(GET|HEAD|POST)$) { return 444; } ssl_certificate ../jason.crt; ssl_certificate_key ../jason-np.key; ssl_session_timeout 5m; ssl_prefer_server_ciphers on; #charset koi8-r; #access_log logs/host.access.log main; location / { root /home/appyw/app/car; index index.html index.htm; try_files $uri $uri/ /index.html; } #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } # proxy the PHP scripts to Apache listening on 127.0.0.1:80 # #location ~ \.php$ { # proxy_pass http://127.0.0.1; #} # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # location /dev-api/ { proxy_pass http://172.23.228.56:18081/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /netty/ { proxy_pass http://127.0.0.1:18099/; } location /document/ { proxy_pass http://hn-cwhdfwpt-test.oss-cn-changsha-wwy-d01-a.opswan.sgmc.sgcc.com.cn/; #proxy_set_header Host $host; #proxy_set_header X-Real-IP $remote_addr; #proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /v2g-platform-web { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; alias /home/appyw/app/ls/v2g-platform-web; index index.html; try_files $uri $uri/ /v2g-platform-web/index.html; } location /v2g-charging-web { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; alias /home/appyw/app/ls/v2g-charging-web; index index.html; try_files $uri $uri/ /v2g-charging-web/index.html; } location /v2g-tjtf-web { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; alias /home/appyw/app/ls/v2g-tjtf-web; index index.html; try_files $uri $uri/ /v2g-tjtf-web/index.html; } location /vehicle-grid-h5 { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; alias /home/appyw/app/ls/vehicle-grid-h5; index index.html; try_files $uri $uri/ /vehicle-grid-h5/index.html; } location /market/api/ { proxy_pass http://172.23.228.56:18081/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /vehicle-grid-admin/ { proxy_pass http://172.23.228.56:18081/vehicle-grid-admin/vehicle-grid-admin/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /vehicle-grid-mobile/ { proxy_pass http://172.23.228.56:18081/vehicle-grid-mobile/vehicle-grid-mobile/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /vehicle-charge-server/ { proxy_pass http://172.23.228.56:18081/charge-server/charge-server/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /vehicle-charging-admin/ { proxy_pass http://172.23.228.56:18081/vehicle-charging-admin/charging-admin/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /vehicle-grid-system/ { proxy_pass http://172.23.228.56:34509/vehicle-grid-system/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /twoBatterySwapping/ { proxy_pass http://172.23.228.56:18081/twoBatterySwapping/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /travel/ { proxy_pass http://172.23.228.56:18081/travel/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /vehicle-grid-client-interconnect/ { proxy_pass http://172.23.228.56:34510/charging-client-interconnect/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /iot/ { proxy_pass http://172.23.228.56:34530; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /newiot/ { proxy_pass http://172.23.228.56:34530; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /xxl-job-admin/ { proxy_pass http://172.23.228.56:18892/xxl-job-admin/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } #upstream dataide{ # server 172.23.228.33:34540; # check interval=5000 rise=2 fall=3 timeout=3000 type=http; # check_http_send "HEAD /dataide-server HTTP/1.0\r\n\r\n"; # check_http_expect_alive http_2xx http_3xx; # } location /dataide-server/ { #root html; index index.html index.htm; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host:$server_port; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Server $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://172.23.228.33:34540; } location ^~/dataide { alias /home/appyw/app/ls/ide; index index.html; try_files $uri $uri/ /dataide/index.html; } # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # #location ~ /\.ht { # deny all; #} } # another virtual host using mix of IP-, name-, and port-based configuration # #server { # listen 8000; # listen somename:8080; # server_name somename alias another.alias; # location / { # root html; # index index.html index.htm; # } #} # HTTPS server # #server { # listen 443 ssl; # server_name localhost; # ssl_certificate cert.pem; # ssl_certificate_key cert.key; # ssl_session_cache shared:SSL:1m; # ssl_session_timeout 5m; # ssl_ciphers HIGH:!aNULL:!MD5; # ssl_prefer_server_ciphers on; # location / { # root html; # index index.html index.htm; # } #} } 比如我的这个配置文件,我想把iot,newiot,xxl-job都导到另一个18085端口上,该怎么做
07-08
user nginx; worker_processes auto; error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; upstream gateway { server 10.2.96.171:8080; } map $http_upgrade $connection_upgrade { default upgrade; '' close; } #gzip on; server{ listen 8000; server_name _; location / { if ($request_method !~ ^(GET|POST|HEAD|PUT|DELETE|OPTIONS)$) { return 444; } proxy_pass http://10.2.96.171:18000; 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_set_header X-Forwarded-Proto $scheme; } } server{ listen 8001; server_name _; location / { proxy_pass http://10.2.96.171:18001; 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_set_header X-Forwarded-Proto $scheme; if ($request_method !~ ^(GET|POST|HEAD|PUT|DELETE|OPTIONS)$) { return 444; } } } server { listen 20443 ssl ; ssl_certificate /data/infra/nginx/gotion.com.cn.crt; server_name 10.2.96.171; ssl_certificate_key /data/infra/nginx/gotion.com.cn.key; ssl_prefer_server_ciphers on; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers HIGH:!aNULL:!MD5; ssl_buffer_size 4k; ssl_session_cache shared:SSL:50m; ssl_session_timeout 4h; root /data/infra/nginx/html; location / { add_header 'Access-Control-Allow-Origin' 'https://10.2.96.171'; try_files $uri /index.html; } location /api/ { proxy_pass http://10.2.96.171:8080/; add_header 'Access-Control-Allow-Origin' 'https://10.2.96.171'; proxy_cookie_path /oauth /; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Cookie $http_cookie; proxy_read_timeout 30000; proxy_send_timeout 30000; client_max_body_size 1024m; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; } location ~* ^/(mio) { proxy_buffering off; proxy_set_header X-Forwarded-Proto $scheme; client_max_body_size 1024m; proxy_http_version 1.1; proxy_set_header Connection ""; chunked_transfer_encoding off; proxy_pass http://10.2.96.171:9000; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $http_host; rewrite ^/mio/(.*)$ /$1 break; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } } 帮我修改这个配置 要求 不配置https证书
03-26
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值