Caching a POST response with nginx: Should I forwa

2019-07-07 02:17发布

问题:

Our system uses POST requests to preload a list of assets. Given the same list of assets identifiers, the server will respond with the same list of asset data. Since the list of identifiers can be very long (it's actually a multipart request containing a JSON list), we used POST instead of GET although it is idempotent.

We use NGINX as a reverse proxy in front of these server. I successfully configured it to work, but there's something that "feels" wrong; I return a Cache-Control: max-age=3600 header in the POST responses that I want cached, and I have NGINX strip them before returning them to the client.

The RFC 7234 says only the method and the uri will be used as a cache key; I could use the Vary header but it seems to be limited to other headers...

I'm not sure how reliable the browser will be. It "seems" that if I make an HTTP POST response cacheable, it will be cached for "future GET requests", which is NOT what I intend.

So, my choices seem to be:

  1. Return a Cache-Control header knowing (or hoping?) that there will be a reverse proxy in front of it stripping that header.
  2. Return a Cache-Control header and let it go through. If someone can explain why it's actually reliable, that would be simple (or if there's another similar header?)
  3. Do not use Cache-Control and instead "hardcode" all URLs directly in my NGINX configuration (I couldn't make this work yet though)

Is there a reliable approach I can use to achieve what I need here? Thanks a lot for your help.

Here's an excerpt of the NGINX configuration if that helps someone:

proxy_cache_path /path/to/nginx/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;

location /path/to/post/request {
  proxy_pass http://remote-server;
  proxy_cache my_cache;
  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;
  proxy_set_header proxy_http_version 1.1;
  proxy_set_header Connection "";
  proxy_cache_lock on;
  proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
  proxy_cache_methods POST;
  proxy_cache_key "$scheme$proxy_host$uri$is_args$args|$request_body";
  proxy_cache_valid 5m;
  client_max_body_size 1500k;
  proxy_hide_header Cache-Control;
}