web-dev-qa-db-ja.com

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

リクエストメソッド(つまり、GET/POST)に応じて異なるバックエンドにプロキシするようにNginxロケーションブロックを構成することは可能ですか?

その理由は、私は現在2つの異なるURL(1つはhttpプロキシ経由で、もう1つはfcgi経由)で2つのメソッドを処理しており、より「REST」にしようとしているため、リソースを取得してリストを返すことが理想的です。 、同じリソースにPOSTすると、リストに追加されます。

19
Brenton Alker

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

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

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

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

28
Jason

これはifで実現できますが、ifは他のディレクティブとうまく連携しないため、これは一般的に Nginxのドキュメントで非推奨 です。たとえば、GETがすべてのユーザーに対して開かれている必要があると想定しますが、POSTはHTTP Basic Authを使用する認証済みユーザーのみを対象としています。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基本認証と組み合わせるには、 _limit_except_ ブロックを追加するだけです。

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

私は@timmmmmyからの答えを得ることができませんでしたが、それは map documentation を示し、これは私にとってはうまくいきました:

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;
   }
}
0
rik harris

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

これは私が物事をうまく機能させるためにやったことです

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