nginx が proxy_pass リダイレクト中にパスの一部を切断する

nginx が proxy_pass リダイレクト中にパスの一部を切断する

フェデレーション認証サーバーからリクエストを受信し、バックエンド アプリに転送するリバース プロキシを設定しています。リクエストに末尾のスラッシュがない場合、nginx はデフォルトの 301 リダイレクトを実行しますが、リダイレクト先のアドレスには、ロケーション ブロックで一致するパスが含まれていません。アイデアは、 Gunicorn のupstream.com/myAppルート URL にリクエストをプロキシすることですbackend.com/。私の設定は次のとおりです。

geo $allow {
    default 0;
    <upstream ip> 1;
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;

    set_real_ip_from <backend ip>;
    real_ip_header X-Forwarded-For;

    if ($allow = 0) {
        return 444;
    }

    server_name backend.com;
    underscores_in_headers on;

    include snippets/<ssl-conf>;
    include snippets/<ssl-params>;

    location /<myApp>/static/ {
        root /<path>/<myApp>/static;
    }

    location /<myApp>/ {

        include proxy_params;
        proxy_pass_request_headers on;
        proxy_pass http://unix:/<path>/<myApp>/<myApp>.sock:/;
    }

    location = /<myApp> {

        include proxy_params;
        proxy_pass_request_headers on;
        proxy_pass 
        http://unix:/<path>/<myApp>/<myApp>.sock:/;
    }

}

当初は最初の location ブロックのみを含めていましたが、 からのリクエストupstream.com/myApp(末尾のスラッシュなし) が発生すると、nginx は にリダイレクトしbackend.com/myApp/、元のリクエストのヘッダーを転送しませんでした。リダイレクトを防ぐために 2 番目の location ブロックを追加することで、この問題は修正されました。

ただし、upstream.com/myApp/search(これも末尾のスラッシュなし) のようなリクエストを受信すると、upstream.com/search/(末尾のスラッシュが追加されますが、その部分は消えてしまいます。nginx がリダイレクトを実行した後、URL 内のその部分をどのように保持すればよいでしょうか?

答え1

さらにデバッグしてみたところ、これは Nginx の問題ではないことがわかりました。むしろ、これは Django が nginx プロキシによってフィルタリングされたパスをリダイレクトに追加しないという問題です。

答え2

これは Nginx の問題ではなく、Nginx の機能です。Nginx がロケーション ブロックに一致するパスの部分を削除しないようにするには、proxy_pass ディレクティブで server:port または socket の後にパスを指定しないでください。

これには末尾のスラッシュのみが含まれます。指定したパスはロケーションブロックの一致する部分を置き換えます。スラッシュのみを指定すると、一致する部分を削除する効果があります。

関連情報