Назад | Перейти на главную страницу

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

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

Причина в том, что в настоящее время я обрабатываю 2 метода с двумя разными URL-адресами (один через http-прокси, а другой через fcgi), и я пытаюсь сделать его более "REST", поэтому в идеале хотелось бы, чтобы GETting ресурса возвращал список , в то время как POSTing на тот же ресурс должен добавить в список.

Я не использую эту конфигурацию, но на основе примеры здесь:

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.

Хотя вы могли бы добиться этого с помощью 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 ...;
      }
    }
  ...

Я не смог получить ответ от @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;
   }
}

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

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

Небольшое изменение ответа vog, чтобы включить обработчик по умолчанию для других методов, таких как OPTIONS, PUT и т. Д.

    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;
            }
    }