nginx:如何在反向代理中直接处理某些文件名(*.txt)的404?

nginx:如何在反向代理中直接处理某些文件名(*.txt)的404?

我有一个复杂的nginx设置,其中端口 80 和 443 的前端nginx处理包括 TLS 在内的所有外部访问。

对于 frontend-nginx 中的文件,/texts应将请求代理到第二个 backend-nginx,后者会在复杂的过程中动态修改现有文本文件,从而占用 CPU 和其他资源。

对于那些不存在的文件*.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

相关内容