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)

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

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

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

Спасибо!

2 ответа

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

Не уверен, что это задумано, но удаление косой черты в конце URL-адреса исправило это для меня:

      url = 'https://example.com/validate/'  # remove the slash
payload = {'pin': pin, 'sku': sku, 'phone': phone, 'AR': True}
validation_post = requests.post(url, data=payload)
Другие вопросы по тегам