Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nginx proxy_cache_key $request_body is ignored for large request body

I use nginx as a reverse proxy and I would like it to cache POST requests. My back-end is correctly configured to return appropriate cache-control headers for POST requests. In nginx I have configured:

proxy_cache_methods POST;
proxy_cache_key "$request_method$request_uri$request_body";

This works great for small HTTP POST requests. However I started noticing that for large requests (e.g. file uploads) it seems like the $request_body is ignored in the proxy_cache_key. When a form containing a file upload is submitted twice with completely different data, nginx will return the cached result.

What could cause this? How can I configure nginx to use the $request_body (or a hash of $request_body) in the proxy_cache_key even for large POST requests?

like image 955
Jeroen Ooms Avatar asked Sep 13 '13 21:09

Jeroen Ooms


People also ask

How do I bypass Nginx cache?

You can get around this by telling Nginx to forward the request straight to Apache, which runs on port: 9080.

Should I enable nginx caching?

Enabling nginx caching is recommended only for websites with a specific profile (for example, popular blogs or news websites): High traffic. The content is updated every few seconds.

Does nginx support caching?

Cache both static and dynamic content from your proxied web and application servers, to speed delivery to clients and reduce the load on the servers.

What is Proxy_cache in nginx?

Some new directives are added, let's go through them one by one. Nginx caches the responses in the disk, proxy_cache_path specifies the path where the responses are to be stored. proxy_cache defines the shared memory zone used for storing the cache keys and other metadata. proxy_cache_key defines the caching key.


2 Answers

So it turns out that when $content_length > client_body_buffer_size, then the request body is written to a file and the variable $request_body == "".

See also http://mailman.nginx.org/pipermail/nginx/2013-September/040442.html

like image 133
Jeroen Ooms Avatar answered Oct 19 '22 13:10

Jeroen Ooms


Rather than using the $request_body within the proxy_cache_key, you may more simply use $content_length. Of course, it comes with its own limitation, but if you know which query you will receive, it can be also a very interesting workaround.

proxy_cache_key "$scheme$request_method$host$request_uri$content_length";

You may alternatively use $request_body as well to keep the desired behavior for smaller request payload:

proxy_cache_key "$scheme$request_method$host$request_uri$request_body$content_length";
like image 37
Cyril Avatar answered Oct 19 '22 15:10

Cyril