Nginx proxy_cache_key 和 HEAD->GET 请求

Nginx proxy_cache_key 和 HEAD->GET 请求

我有以下 Nginx 配置:

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;
    }
}

上游服务器是一个常规的 Node.js 进程。如果我激活proxy_cache_*上述指令,HEAD请求就会被传递GET到上游服务器。如果我停用指令,请求HEAD就会作为HEAD请求传递,一切正常。

有什么建议么?

谢谢!

答案1

这个问题很老了,但仍然有意义且没有答案。我花了几个小时才找到解决方案,Nginx 从 v.1.9.7 开始包含一个新功能,可以完全满足您的要求。

将其添加到您的配置中:

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

第一行禁用 http 请求的转换,第二行除了 GET 请求外还启用 HEAD 请求的缓存。第三行将 $request_method 添加到 proxy_cache_key,因此 head 请求将作为单独的文件缓存。

答案2

要禁用 HEAD 请求的缓存,您必须使用一些额外的逻辑,例如:

server {
  ...

  resolver 127.0.0.1;

  location / {

    error_page 420 = @skip_cache;
    error_page 421 = @use_cache;

    if ( $request_method = 'GET' )
    {
      return 421;
    }

    return 420;
  }

  location @use_cache {
    internal;

    proxy_cache cache;
    proxy_cache_key "...";
    proxy_cache_valid 200 1h;
    proxy_buffering off;
    proxy_pass ...;
  }

  location @skip_cache {
    internal;
    proxy_buffering off;
    proxy_pass ...;
  }
}

我还没有找到一种方法来阻止 nginx 在启用缓存时将 HEAD 更改为 GET :-(。

相关内容