Прокси Nginx по методу запроса

17

Возможно ли / как я могу сконфигурировать блок местоположения Nginx для прокси на разные бэкэнды в зависимости от метода запроса (т.е. GET / POST)?

Причина в том, что в настоящее время я работаю с двумя методами по двум разным URL-адресам (один через http-прокси, а другой - через fcgi) и пытаюсь сделать его более "ОТДЫХАМ", поэтому в идеале хотелось бы, чтобы GET установил ресурс для возврата списка , в то время как размещение на том же ресурсе следует добавить в список.

Брентон Алкер
источник

Ответы:

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 в моем случае, но в остальном это работает. В настоящий момент я не использую второй блок if, nginx , по-видимому, останавливает «обработку» при достижении директивы fastcgi_pass (то есть не проваливается и не запускает проход прокси-сервера), потому что я хочу, чтобы что-то кроме POST вернулось на прокси.
Брентон Алкер
2
Обратите внимание , что ifобычно не рекомендуется в документации Nginx: nginx.com/resources/wiki/start/topics/depth/ifisevil
ВОГ
1
Итак, какова альтернатива?
WM
1
@WM Смотрите мой ответ: serverfault.com/a/823053/175421
ВОГ
@vog, Интересно. Довольно умный способ сделать это. Спасибо, что поделился.
WM
22

Хотя вы могли бы добиться этого с помощью if, это, как правило, не одобряется документацией Nginx , потому ifчто не подходит для других директив. Например, предположим, что 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;
    }
  }
}

Чтобы объединить это с HTTP Basic Auth для всего, кроме GET, просто добавьте limit_exceptблок:

  ...
    location /service {
      proxy_pass http://other_$request_method;
      limit_except GET {
        auth_basic ...;
      }
    }
  ...
ВОГ
источник
0

Это то, что я сделал, чтобы все работало на меня

add_header Allow "GET, POST, HEAD" always;
if ( $request_method !~ ^(GET|POST|HEAD)$ ) {
    proxy_pass http://back-end;
}
Мансур Али
источник
Как точно это переключается между двумя конечными точками на основе метода запроса?
Основное