Requests / Bravado 302 ответ на POST превращается в GET (Python)
Когда я писал обработчик для веб-сервиса на языке бравадо (через request.session()), я столкнулся с этой особенностью:
Запрос POST превращается в запрос GET, поскольку он перенаправляется. Причинение моего POST быть искалеченным, и я не могу заставить вещь работать.
РЕДАКТИРОВАТЬ: фактический вызов запросов сделан из бравадо, как объяснено в: Как настроить пользовательский http-клиент в Бравадо? Что мне понадобилось для установки дополнительных сертификатов на стороне клиента.
Таким образом, сама просьба вызова / сеанса скрывается бравадой.
Эта проблема (переход post / get по запросам) обсуждалась в других темах, где она рассматривается в соответствии со спецификацией, но, тем не менее, странность.
В конце я просто взломал запросы в следующих сегментах в session.py:
def rebuild_method(self, prepared_request, response):
"""When being redirected we may want to change the method of the request
based on certain specs or browser behavior.
"""
method = prepared_request.method
# http://tools.ietf.org/html/rfc7231#section-6.4.4
if response.status_code == codes.see_other and method != 'HEAD':
method = 'GET'
# Do what the browsers do, despite standards...
# First, turn 302s into GETs.
if response.status_code == codes.found and method != 'HEAD':
if method == 'POST':
#print ( '\n\nDeliberately not changing to GET\n\n' )
else:
method = 'GET'
# Second, if a POST is responded to with a 301, turn it into a GET.
# This bizarre behaviour is explained in Issue 1704.
if response.status_code == codes.moved and method == 'POST':
method = 'GET'
prepared_request.method = method
Куда я просто не перехожу, чтобы добраться.
А также здесь:
def resolve_redirects(self, resp, req, stream=False, timeout=None,
verify=True, cert=None, proxies=None, yield_requests=False, **adapter_kwargs):
Где я закомментировал:
## # https://github.com/requests/requests/issues/1084
## if resp.status_code not in (codes.temporary_redirect, codes.permanent_redirect):
## # https://github.com/requests/requests/issues/3490
## print(prepared_request.headers)
## purged_headers = ('Content-Length', 'Content-Type', 'Transfer-Encoding')
## for header in purged_headers:
## prepared_request.headers.pop(header, None)
## prepared_request.body = None
Конечно, это безобразный хак, но что я должен был сделать? Надеюсь, у кого-нибудь есть указатель на это.
1 ответ
Если вы не хотите изменять библиотеку запросов, вы можете вместо этого проверить перенаправления в своем коде, вот пример:
url = 'https://httpbin.org/redirect-to?url=http%3A%2F%2Fhttpbin.org%2Fpost'
data = {'name': 'Hello'}
while True:
rep = requests.post(url, data=data, allow_redirects=False)
if rep.status_code in [301, 302]:
url = rep.headers.get('location')
print 'redirect to', url
continue
break
print rep.text
Конечно, вы должны обрабатывать возможность бесконечного цикла и другие коды состояния http