nginx: Как обрабатывать 404 напрямую в обратном прокси-сервере только для некоторых имен файлов (*.txt)?

nginx: Как обрабатывать 404 напрямую в обратном прокси-сервере только для некоторых имен файлов (*.txt)?

У меня сложная nginxконфигурация, в которой фронт nginxна портах 80 и 443 обрабатывает весь внешний доступ, включая TLS.

Для файлов во /textsфронтенде nginx должен перенаправлять запросы на второй бэкенд nginx, который изменяет существующие текстовые файлы «на лету» в ходе сложного процесса, используя ресурсы ЦП и другие ресурсы.

Для тех файлов *.txt, которые не существуют (404), я хочу вообще не беспокоить бэкенд, а вместо этого предоставить клиенту файл по умолчанию /texts/default.txtнапрямую. Однако в настоящее время несуществующие файлы по-прежнему обрабатываются только в строке бэкенда error_page 404. Существующие файлы обслуживаются без проблем, прокси работает.

Вот моя конфигурация:

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

У меня есть бесполезное выражение в файле конфигурации интерфейса, которое, как мне кажется, может обрабатывать перенаправления 404, default.txtно когда я это делаю

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

Я получаю перенаправление только внутри бэкэнда (т.е. проксирование происходит).

решение1

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

Обратите внимание на правильное регулярное выражение для locationоператора. proxy_set_headerОператоры будут унаследованы, но proxy_passоператор должен быть повторен во вложенном location.

Оператор try_filesпроверит существование файла и изменит URI, если он не существует.

Файл по умолчанию имеет выделенный файл location, поэтому его можно обслуживать как статический файл из правильного корня.

Путь к файлу формируется путем объединения значения rootс URI, поэтому файл /texts/default.txtнаходится по адресу /path/to/root/texts/default.txt.

Связанный контент