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)