nginx: 一部のファイル名 (*.txt) のみに対してリバース プロキシで 404 を直接処理するにはどうすればよいですか?

nginx: 一部のファイル名 (*.txt) のみに対してリバース プロキシで 404 を直接処理するにはどうすればよいですか?

ポート 80 と 443 のnginxフロントがTLS を含むすべての外部アクセスを処理する複雑な設定があります。nginx

フロントエンド nginx内のファイルの場合、/textsリクエストは 2 番目のバックエンド 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;
}

ステートメントの正しい正規表現に注意してくださいlocationproxy_set_headerステートメントは継承されますが、proxy_passステートメントはネストされた 内で繰り返す必要がありますlocation

このtry_filesステートメントはファイルの存在を確認し、存在しない場合は URI を変更します。

デフォルト ファイルには専用の があるlocationため、正しいルートから静的ファイルとしてファイルを提供できます。

ファイルへのパスは の値rootと URI を連結することによって構築されるため、ファイルは/texts/default.txtに配置されます/path/to/root/texts/default.txt

関連情報