python-запросы, делающие запрос GET вместо запроса POST

У меня есть ежедневный cron, который обрабатывает некоторые повторяющиеся события в моем приложении, и время от времени я замечаю одну странную ошибку, которая появляется в журналах. Cron, среди прочего, выполняет проверку некоторых кодов и использует веб-приложение, работающее на том же сервере, поэтому запрос проверки выполняется через POST запрос с некоторыми данными.

url = 'https://example.com/validate/'
payload = {'pin': pin, 'sku': sku, 'phone': phone, 'AR': True}
validation_post = requests.post(url, data=payload)

Итак, это делает фактический запрос, и я регистрирую ответ. Время от времени, а в последнее время до 50% запроса, в ответе содержится следующее сообщение от nginx:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>405 Method Not Allowed</title>
<h1>Method Not Allowed</h1>
<p>The method GET is not allowed for the requested URL.</p>

Таким образом, фактический запрос был сделан с использованием метода GET, а не POST, как указано в коде. В nginx access.log я вижу эту запись:

123.123.123.123 - - [18/Feb/2015:12:26:50 -0500] "GET /validate/ HTTP/1.1" 405 182 "-" "python-requests/2.2.1 CPython/2.7.6 Linux/3.13.0-37-generic"

И журнал uwsgi для приложения показывает то же самое:

[pid: 6888|app: 0|req: 1589/58763] 123.123.123.123 () {40 vars in 613 bytes} [Mon Apr  6 11:42:41 2015] GET /validate/ => generated 182 bytes in 1 msecs (HTTP/1.1 405) 4 headers in 234 bytes (1 switches on core 0)

Итак, все указывает на то, что фактический запрос был сделан не с использованием POST. Маршрут приложения, который обрабатывает этот код, прост, и это выдержка: @app.route('/validate/', method=['POST']) @login_required

def validate():
    if isinstance(current_user.user, Sales):
        try:
            #do the stuff here
        except Exception, e:
            app.logger.exception(str(e))
            return 0
    abort(403)

Маршрут приложения может дать сбой, и в блоке try есть несколько returns, но даже если они не работают или есть исключение, нет ничего, что могло бы вызвать код ошибки 405 в этом блоке, только 403, что редко случается, так как я создаю и войдите в систему вручную из cron.

Я нашел похожую вещь здесь, но суть заключалась в том, что было перенаправление с версии HTTP на HTTPS, и у меня также есть это перенаправление на сервере, но URL-адрес, по которому выполняется запрос, содержит HTTPS, поэтому я сомневаюсь, что это является причиной.

Стек, на котором я это запускаю, — uwsgi+nginx+flask. Кто-нибудь может увидеть, что может быть причиной этого? Повторюсь, это происходит не всегда, поэтому иногда работает так, как ожидалось, иногда нет. Недавно я перешел с apache и mod_wsgi на этот новый стек, и с этого момента я начал сталкиваться с этой ошибкой; не могу припомнить, чтобы когда-либо видел его в среде apache.

Спасибо!


person wont_compile    schedule 06.04.2015    source источник


Ответы (1)


Единственный раз, когда мы меняем запрос POST на GET, это когда мы обрабатываем перенаправление. В зависимости от кода редиректа мы изменим метод запроса. Если вы хотите быть уверены, что мы не используем редиректы, вам нужно передать allow_redirects=False. Тем не менее, вам нужно выяснить, почему ваше приложение генерирует перенаправления (в том числе, перенаправляет ли оно на HTTP или в другой домен или использует определенный код состояния).

person Ian Stapleton Cordasco    schedule 07.04.2015
comment
Спасибо за ответ. Я изменил вызовы в своем приложении с помощью этого флага и добавил некоторую отладочную информацию, чтобы попытаться выяснить, что вызывает это. - person wont_compile; 07.04.2015
comment
Я знаю, это может показаться раздражающим, но я хочу заверить вас, что то, что мы делаем, — это наилучшая на данный момент практика обработки перенаправлений. То, что происходит в запросах, предназначено для вашей безопасности. - person Ian Stapleton Cordasco; 07.04.2015