How to cache a multipart POST request with NGINX reverse proxy

Viewed 1273

we have a NGINX reverse proxy in front of our web server, and we need it to cache responses based on the request body (for a detailed explanation of why see this other question).

The problem I have is that even though the POST data is the same, the multipart boundary is actually different every time (the boundaries are created by the web browser).

Here's a simplified example of what the request looks like (notice the browser-generated WebKitFormBoundaryV2BlneaIH1rGgo0w):

POST http://my-server/some-path HTTP/1.1
Content-Length: 383
Accept: application/json
Content-Type: multipart/form-data; boundary=----
WebKitFormBoundaryV2BlneaIH1rGgo0w

------WebKitFormBoundaryV2BlneaIH1rGgo0w
Content-Disposition: form-data; name="some-key"; filename="some-pseudo-file.json"
Content-Type: application/json

{ "values": ["value1", "value2", "value3"] }
------WebKitFormBoundaryV2BlneaIH1rGgo0w--

If it's useful to someone, here's a simplified example of the NGINX config we use

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

I have seen the LUA NGINX module which looks like it could work, but I don't see how I could use it to parse the request data to build the cache key, but still pass the original request, or if there's something I can use with the "stock" NGINX.

Thanks!

0 Answers
Related