Nginx ignores proxy_no_cache
Clima Gabriel
clima.gabrielphoto at gmail.com
Thu Jan 30 09:01:32 UTC 2025
Hello Maxim,
Hope this helps.
We encounter disk failures fairly often and what the kernel will do most of
the time is re-mount the disk as read-only.
What I did was add this check which checks if the disk is healthy before
hand and executes the proxy_no_cache path if it is.
It doesn't cover all the possible disk failures, like sometimes you'll just
get IO errors and still return 5XX to clients. But to cover all cases a
much cleverer reshuffling of the code is needed.
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index d7f427d50..839ed6c0d 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -8,6 +8,7 @@
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>
+#include <sys/statvfs.h>
#include <ngx_http_proxy_module.h>
@@ -3424,6 +3425,16 @@ ngx_http_upstream_send_response(ngx_http_request_t
*r, ngx_http_upstream_t *u)
break;
default: /* NGX_OK */
+ if (r->cache) {
+ struct statvfs fs;
+ if (statvfs((char *)r->cache->file_cache->path->name.data,
&fs) == -1) {
+ return NGX_ERROR;
+ }
+ if ((fs.f_flag & ST_RDONLY) != 0) {
+ u->cacheable = 0;
+ break;
+ }
+ }
if (u->cache_status == NGX_HTTP_CACHE_BYPASS) {
On Sun, Apr 7, 2024 at 4:56 PM Maxim Dounin <mdounin at mdounin.ru> wrote:
> Hello!
>
> On Sun, Apr 07, 2024 at 01:36:21PM +0200, Kirill A. Korinsky wrote:
>
> > Greetings,
> >
> > Let assume that I would like behavior on LB from the backend and force
> it to
> > cache only resposnes that have a X-No-Cache header with value NO.
> >
> > Nginx should cache a response with any code, if it has such headers.
> >
> > This works well until the backend is unavailable and nginx returns a
> > hardcoded 502 that doesn't have a control header, but such a response is
> > cached anyway.
> >
> > Here is the config that allows to reproduce the issue:
> >
> > http {
> > default_type application/octet-stream;
> >
> > proxy_cache_path /tmp/nginx_cache keys_zone=the_zone:1m;
> > proxy_cache the_zone;
> > proxy_cache_valid any 15m;
> > proxy_cache_methods GET HEAD POST;
> >
> > add_header X-Cache-Status $upstream_cache_status
> always;
> >
> > map $upstream_http_x_no_cache $no_cache {
> > default 1;
> > "NO" 0;
> > }
> >
> > proxy_no_cache $no_cache;
> >
> > upstream echo {
> > server 127.127.127.127:80;
> > }
> >
> > server {
> > listen 1234;
> > server_name localhost;
> >
> > location / {
> > proxy_pass http://echo;
> > }
> > }
> > }
> >
> > when I run:
> >
> > curl -D - http://127.0.0.1:1234/
> >
> > it returns MISS on the first request, and HIT on the second one.
> >
> > Here I expect both requests to return MISS.
>
> Thanks for the report.
>
> Indeed, proxy_no_cache is only checked for proper upstream
> responses, but not when caching errors, including internally
> generated 502/504 in ngx_http_upstream_finalize_request(), and
> intercepted errors in ngx_http_upstream_intercept_errors().
>
> Quick look suggests there will be also issues with caching errors
> after proxy_cache_bypass (errors won't be cached even if they
> should), as well as issues with proxy_cache_max_range_offset after
> proxy_cache_bypass (it will be ignored).
>
> This needs cleanup / fixes, added to my TODO list.
>
> --
> Maxim Dounin
> http://mdounin.ru/
> _______________________________________________
> nginx mailing list
> nginx at nginx.org
> https://mailman.nginx.org/mailman/listinfo/nginx
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://freenginx.org/pipermail/nginx/attachments/20250130/f421123f/attachment.htm>
More information about the nginx
mailing list