Nginx proxy_cache_key and HEAD->GET request

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/cbmljs/article/details/102726311

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

猜你喜欢

转载自blog.csdn.net/cbmljs/article/details/102726311