nginxプロキシでURLデコードを無効にする


21

このURLを参照すると、http://localhost:8080/foo/%5B-%5Dサーバー(nc -l 8080)はそのまま受信します。

GET /foo/%5B-%5D HTTP/1.1

ただし、nginx(1.1.19)を介してこのアプリケーションをプロキシする場合:

location /foo {
        proxy_pass    http://localhost:8080/foo;
}

nginxポート経由でルーティングされた同じリクエストは、パスがデコードされて転送されます。

GET /foo/[-] HTTP/1.1

GETパス内のデコードされた角括弧は、エスケープされずに到着するため、ターゲットサーバーでエラー(HTTPステータス400-パス内の不正な文字...)を引き起こしています。

URLデコードを無効にする方法、またはエンコードして元に戻す方法はありますか?それにより、ターゲットサーバーがnginx経由でルーティングされたときにまったく同じパスを取得できるようになりますか?巧妙なURL書き換えルール?


nginxに報告されたバグ:trac.nginx.org/nginx/ticket/262
Tomasz Nurkiewicz

回答:


19

Valentin V. Bartenevを引用(この回答の全クレジットを取得する必要があります):

ドキュメントからの引用:

  • proxy_passがURIで指定されている場合、リクエストをサーバーに渡すときに、場所に一致する正規化されたリクエストURIの一部がディレクティブで指定されたURIに置き換えられます

  • URIなしproxy_passで指定された場合、リクエストURIは、元のリクエストを処理するときにクライアントが送信したのと同じ形式でサーバーに渡されます

あなたの場合の正しい構成は次のとおりです。

location /foo {
   proxy_pass http://localhost:8080;
}

8
誰かが私と同じ状況http://localhost:8080/になっhttp://localhost:8080た場合に備えて、変更しなければなりませんでした。
herrtim

4
NginxがURIをバックエンドサーバーに渡す前にデコードするのはなぜですか?URIをそのままにしておいた方が意味がありませんか?
カモノハシ14年

あなたが明示的置換の実行を開始するまで@platypus、それは、そのまま保たれている
CNST

2

nginxのドキュメントで一般的に$uri「正規化」として知られているURLデコードは、バックエンドIFFの前に発生することに注意してください。

  • proxy_pass末尾のスラッシュだけがすべて単独である場合でも、URIはそれ自体の内部で指定されます。

  • または、URIは処理中に変更されます(例:を通じて)rewrite


両方の条件は、http://nginx.org/r/proxy_pass(emphasis mine)で明示的に文書化されています。

  • 場合proxy_pass指令が指定されたURIと要求がサーバに渡されたとき、その後、一部の正規化された位置に一致するリクエストURIは、ディレクティブで指定されたURIに置き換えられ

  • 場合proxy_pass指定されるURIことなく、要求URIは、サーバに渡されるクライアントによって送信されたのと同じ形元の要求が処理されるとき、または完全な正規化されたリクエストURIが渡されたときの処理変更URIを


解決策は、OPの場合のようにURIを省略するか、実際に巧妙なrewriteルールを使用することです。

# map `/foo` to `/foo`:
location /foo {
    proxy_pass  http://localhost:8080;  # no URI -- not even just a slash
}

# map `/foo` to `/bar`:
location /foo {
    rewrite  ^  $request_uri;            # get original URI
    rewrite  ^/foo(/.*)  /bar$1  break;  # drop /foo, put /bar
    return 400;   # if the second rewrite won't match
    proxy_pass    http://localhost:8080$uri;
}

コントロールグループを含む、関連するStack Overflowアンサーでライブで確認できます


ここではドキュメントが混乱しています。どちらの形式にもURIが含まれています。これは、あるパスコンポーネントその他の内の1つの中に存在して行方不明です。
マイケルハンプトン

@MichaelHampton、私は同意しません— PATHは一般にURIと呼ばれるため、パスのないものにはURIが含まれていません。
cnst

もちろん、相対パスのみが有効なURLになることもあります。ポイントは、残りも有効なURI(例:)であるということですhttp://localhost:8080。あなたが同意しない場合は、RFC 3986の作者でそれを取ることができます
マイケル・ハンプトン

@MichaelHampton Unforturnately、それはスキームとパスフラグメントはオプションであり、引数URI、権威あることが必須でいるようだ
ノーマン徐
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.