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

Nginx https rewrite превращает POST в GET

Мой прокси-сервер работает на IP-адресе A, и именно так люди получают доступ к моей веб-службе. Конфигурация nginx будет перенаправлять на виртуальную машину на IP B.

Для прокси-сервера на IP A у меня есть это на моих сайтах.

server {
        listen 443;
        ssl on;
        ssl_certificate nginx.pem;
        ssl_certificate_key nginx.key;

        client_max_body_size 200M;
        server_name localhost 127.0.0.1;
        server_name_in_redirect off;

        location / {
                proxy_pass http://10.10.0.59:80;
                proxy_redirect http://10.10.0.59:80/ /;

                proxy_set_header Host $http_host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

}

server {
        listen 80;
        rewrite     ^(.*)   https://$http_host$1 permanent;
        server_name localhost 127.0.0.1;
        server_name_in_redirect off;
        location / {
                proxy_pass http://10.10.0.59:80;
                proxy_redirect http://10.10.0.59:80/ /;
                proxy_set_header Host $http_host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
}

В proxy_redirect был взят из как заставить nginx пересылать HTTP-запросы POST через перезапись?

Все, что попадает на общедоступный IP-адрес, будет достигать 443 из-за перезаписи. Внутренне мы перенаправляем на виртуальную машину 80.

Но когда я запускаю скрипт Python, такой как приведенный ниже, для проверки нашей конфигурации

import requests

data = {'username': '....', 'password': '.....'}
url = 'http://IP_A/api/service/signup'

res  = requests.post(url, data=data, verify=False)
print res
print res.json
print res.status_code
print res.headers

Я получаю 405 Method Not Allowed. В nginx мы обнаружили, что когда он попадал на внутренний сервер, внутренний nginx получал GET запрос, хотя в исходном заголовке мы сделали POST (это было показано в скрипте Python).

Похоже, у перезаписи есть проблема. Есть идеи, как это исправить? Когда я закомментировал переписывание, он наверняка достиг 80, и он прошел. Поскольку программа rewrite может взаимодействовать с нашим внутренним сервером, сама перезапись не вызывает проблем. Это просто перезапись упала POST к GET.

Спасибо!

(Это также будет задано на форуме Nginx, потому что это критический блокировщик ...)

Это не Nginx, это ваш браузер.

Примечание из RFC2616:

RFC 1945 и RFC 2068 указывают, что клиенту не разрешено изменять метод перенаправленного запроса. Однако большинство существующих реализаций пользовательского агента обрабатывают 302, как если бы это был ответ 303, выполняя GET для Location [..]

Это верно для всех популярных браузеров, и вы ничего не можете с этим поделать.

я нашел POST /api/brand превращался в GET /api/brand потому что веб-приложение, которое я использовал (flask-restful) делал "недействительный" запрос. Если бы я использовал POST /api/brand/ (обратите внимание на конечный /), это было успешно.