リクエストメソッドによるNginxプロキシ


17

リクエスト方法(GET / POSTなど)に応じて、異なるバックエンドにプロキシするようにNginxロケーションブロックを設定することは可能ですか?

その理由は、私は現在2つの異なるURL(1つはhttpプロキシ経由、もう1つはfcgi経由)で2つのメソッドを処理しており、リストを返すためにリソースをGETするのが理想的だからです。 、同じリソースへのPOSTはリストに追加する必要があります。

回答:


27

私はこの構成を使用しませんが、ここ例に基づいています

location /service  {
  if ($request_method = POST ) {
    fastcgi_pass 127.0.0.1:1234;
  }

  if ($request_method = GET ) {
     alias /path/to/files;
  }
}

独自のアプリケーションを作成する場合、GET / POSTをチェックし、X-Accel-Redirectヘッダーを送信してファイルの転送をnginxに渡すことも検討できます。


私の場合、GETブロックはproxy_passですが、それ以外は動作します。現時点では、2番目のifブロックを使用していないので、fastcgi_passディレクティブに達したときにnginx 「処理」を停止しているように見えます(つまり、POST以外のものを元に戻したいためプロキシに。
ブレントンアルカー

2
注意if:一般的にnginxのドキュメントで推奨されてnginx.com/resources/wiki/start/topics/depth/ifisevil
VOG

1
それでは、代替手段は何ですか?
WM

1
@WMは私の答えを参照してください。serverfault.com/a/823053/175421
VOG

@vog、興味深い。かなり賢い方法です。共有してくれてありがとう。
WM

23

でこれを達成することはできますがif、これは一般にNginxのドキュメントでは推奨されてifいません。他のディレクティブではうまく動作しないからです。たとえば、GETはすべてのユーザーに対して開かれ、POSTはHTTP基本認証を使用する認証されたユーザーのみに対して開かれると仮定します。これは、ifと組み合わせて使用する必要がありますがauth_basic、正しく機能しません。

なしで機能する代替手段を次に示しifます。コツは、アップストリーム名の一部として「GET」と「POST」を使用することです。したがって、これらは変数置換によって対処できます。

http {
  upstream other_GET {
    server ...;
  }
  upstream other_POST {
    server ...;
  }
  server {
    location /service {
      proxy_pass http://other_$request_method;
    }
  }
}

GET以外のすべてについてHTTP Basic Authとこれを組み合わせるには、limit_exceptブロックを追加するだけです:

  ...
    location /service {
      proxy_pass http://other_$request_method;
      limit_except GET {
        auth_basic ...;
      }
    }
  ...

このアプローチの問題は502 gateway errorno resolver defined to resolve other_HEAD(または、不足しているアップストリームが何であれ)戻ってくることです。のようなものを返す方がより意味があります405 method not allowed。これを達成する方法はありますか?
ジェームズ

1
@ジェームズ:これは、おそらくこれを参照して、新しい質問として表現されるべきです。この詳細については答えがありませんが、おそらく他の人には答えません。
vog

0

これは私が物事を私のために働かせるためにしたことです

add_header Allow "GET, POST, HEAD" always;
if ( $request_method !~ ^(GET|POST|HEAD)$ ) {
    proxy_pass http://back-end;
}

eはリクエストメソッドに基づいて2つのエンドポイント間で正確に切り替えますか?
基本的な

0

OPTIONS、PUTなどの他のメソッドのデフォルトハンドラーを含めるために、vogの回答が若干変更されました。

    upstream webdav_default {
            server example.com;
    }
    upstream webdav_upload {
            server example.com:8081;
    }
    upstream webdav_download {
            server example.com:8082;
    }
    server {
            map upstream_location $request_method {
                    GET     webdav_download;
                    HEAD    webdav_download;
                    PUT     webdav_upload;
                    LOCK    webdav_upload;
                    default webdav_default;
            }
            location / {
                    proxy_pass https://$upstream_location;
            }
    }

0

私は@timmmmmyから答えを得ることができませんでしたが、それは地図のドキュメントを指し示し、これは私のために働いた:

map $request_method $upstream_location {
   PUT     example.com:8081;
   POST    example.com:8081;
   PATCH   example.com:8081;
   default example.com:8082;
}
server {
   location / {
      proxy_pass https://$upstream_location;
   }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.