nginx: Como lidar com 404 diretamente em um proxy reverso apenas para alguns nomes de arquivos (*.txt)?

nginx: Como lidar com 404 diretamente em um proxy reverso apenas para alguns nomes de arquivos (*.txt)?

Eu tenho uma nginxconfiguração complexa onde uma frente nginxnas portas 80 e 443 lida com todo o acesso externo, incluindo TLS.

Para arquivos no /textsfrontend-nginx, a solicitação de proxy será feita para um segundo backend-nginx que modifica os arquivos de texto existentes em tempo real em um processo complicado, usando CPU e outros recursos.

Para os arquivos *.txtque não existem (404), desejo não incomodar o back-end, mas fornecer /texts/default.txtdiretamente ao cliente um arquivo padrão. No entanto, os arquivos atualmente inexistentes ainda são tratados apenas na error_page 404linha do backend. Os arquivos existentes são servidos sem problemas, o proxy funciona.

Esta é minha configuração:

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

Eu tenho aquela declaração inútil no arquivo de configuração do frontend que me parece que poderia lidar com redirecionamentos 404, default.txtmas quando eu faço isso

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

Recebo um redirecionamento apenas dentro do back-end (para que o proxy ocorra).

Responder1

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 a expressão regular correta para a locationinstrução. As proxy_set_headerinstruções serão herdadas, mas a proxy_passinstrução precisa ser repetida no nested location.

A try_filesinstrução verificará a existência do arquivo e alterará o URI se ele não existir.

O arquivo padrão possui um dedicado locationpara que o arquivo possa ser servido como um arquivo estático da raiz correta.

O caminho para o arquivo é construído concatenando o valor de rootcom o URI, de forma que o arquivo /texts/default.txtesteja localizado em /path/to/root/texts/default.txt.

informação relacionada