nginx: ¿Cómo manejar 404 directamente en un proxy inverso solo para algunos nombres de archivos (*.txt)?

nginx: ¿Cómo manejar 404 directamente en un proxy inverso solo para algunos nombres de archivos (*.txt)?

Tengo una nginxconfiguración compleja donde un frente nginxen los puertos 80 y 443 maneja todo el acceso externo, incluido TLS.

Para los archivos en /textsel frontend-nginx, se enviará una solicitud de proxy a un segundo backend-nginx que modifica los archivos de texto existentes sobre la marcha en un proceso complicado, consumiendo CPU y otros recursos.

Para aquellos archivos *.txtque no existen (404), no deseo molestar al backend en absoluto, sino proporcionar al cliente un archivo predeterminado /texts/default.txtdirectamente. Sin embargo, los archivos que actualmente no existen solo se manejan en la error_page 404línea del backend. Los archivos existentes se sirven sin problemas, el proxy funciona.

Esta es mi configuración:

frontend-nginx.conf:
http {
    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;
    include /etc/nginx/conf.d/*.conf;

    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  frontend.example.org;
        root         /srv/www;

        location /texts/ {

            location ~ \*.txt$ {
                root /srv/www/backend;

                ####### the next line has absolutely no effect
                try_files $uri /texts/default.txt;
            }

            proxy_pass          http://localhost:90;
            proxy_redirect      http://localhost:90/ /;
            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-Client-Verify  SUCCESS;
            proxy_set_header    Upgrade          $http_upgrade;
            proxy_set_header    Connection       "upgrade";
            proxy_http_version  1.1;

            proxy_redirect off;
        }
    }
    # https goes here, all the same except TLS
}
backend-nginx.conf:
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;

    server {
        listen       127.0.0.1:90;

        root /srv/www/backend;
        charset utf-8;

        expires -1;  # no-cache
        location ~ /..*\.txt$ {
            # longer cache time for text files
            expires 10m;

            # this actually works but only here in the backend
            error_page  404 @404;
        }

        location @404 {
            return 302 $scheme://frontend.example.org/texts/default.txt
        }
    }
}

Tengo esa declaración inútil en el archivo de configuración de la interfaz que me parece como si pudiera manejar redirecciones 404, default.txtpero cuando lo hago

wget -v http://frontend.example.org/texts/notexist.txt

Recibo una redirección solo dentro del backend (por lo que se realiza el proxy).

Respuesta1

location /texts/ {
    proxy_set_header ...;
    proxy_pass ...;

    location ~ \.txt$ {
        root /path/to/root;
        try_files $uri /texts/default.txt;
        proxy_pass ...;
    }
}
location = /texts/default.txt {
    root /path/to/root;
}

Observe la expresión regular correcta para la locationdeclaración. Las proxy_set_headerdeclaraciones se heredarán, pero proxy_passes necesario repetirlas en el archivo location.

La try_filesdeclaración verificará la existencia del archivo y cambiará el URI si no existe.

El archivo predeterminado tiene una sección dedicada locationpara que el archivo pueda servirse como un archivo estático desde la raíz correcta.

La ruta al archivo se construye concatenando el valor de rootcon el URI, por lo que el archivo /texts/default.txtse ubica en /path/to/root/texts/default.txt.

información relacionada