411 ответ приводит к исключению в Session.send

ОБНОВЛЕНИЕ: добрые люди, разрабатывающие Requests.py, находятся на рассмотрении.

Мы взаимодействуем (тестируем) со службой HTTP, которая отвечает кодом состояния 411 (длина обязательна), если при наличии тела запроса не был предоставлен заголовок запроса Content-Length; Этого следует ожидать в соответствии с RFC 2616.

Проблема, с которой мы столкнулись, связана с модулем Python Requests (curl работает как положено). При отправке некорректного запроса (без Content-Length при наличии тела запроса) служба отвечает 411, и соединение закрывается удаленной конечной точкой ( Connection: close). Это, в свою очередь, вызывает исключение из метода Requests Session.send, и мы не можем получить код состояния ответа HTTP для проверки.

Можно ли остановить эту ситуацию (исключение) и получить код состояния ответа HTTP без изменения службы HTTP?

Код

from requests import Request, Session

endpoint = "http://api.corvusoft.co.uk/resources"
request_body = '{ "data": {"core-temperature": "1,430", "core-temperature-units": "celsius", ... } }'

request = Request('POST', endpoint, data=request_body, headers={"Connection": "close"})
prepared_request = request.prepare()
del prepared_request.headers['Content-Length']

session = Session()
response = session.send(prepared_request)

print response.status_code

Трассировки стека

Scenario: HTTP PUT without Content-Length                                                                                               
    Given I have initialised the core sensors
    And I perform a HTTP "POST" request to "/readings" with headers "Content-Type: application/vnd.api+json; charset=utf-8, Accept: application/vnd.api+json":
      | """                                                   |
      | " { "data": {                                       " |
      | "     "id": "c0f22109-d258-4458-a3f5-0d16b2f55487", " |
      | "     "value": "acceptance-test"                    " |
      | "   }                                               " |
      | " }                                                 " |
      | """                                                   |
    When I perform a HTTP "PUT" request to "/queues/c0f22109-d258-4458-a3f5-0d16b2f55487" without header "Content-Length":
      | """                                                   |
      | " { "data": {                                       " |
      | "     "ttl": 30,                                    " |
      | "     "id": "c0f22109-d258-4458-a3f5-0d16b2f55487"  " |
      | "   }                                               " |
      | " }                                                 " |
      | """                                                   |
    Traceback (most recent call last):
      File "/Library/Python/2.7/site-packages/lettuce/core.py", line 144, in __call__
        ret = self.function(self.step, *args, **kw)
      File "/Users/Corvusoft/Development/test/acceptance/features/step_definitions/request.py", line 30, in i_perform_a_http_method_request_to_path_without_header_and_body
        i_perform_a_http_method_request_to_path_with_headers_and_body( step, method, path, "Accept: application/vnd.api+json, Content-Type: application/vnd.api+json; charset=utf-8", True )
      File "/Users/Corvusoft/Development/test/acceptance/features/step_definitions/request.py", line 91, in i_perform_a_http_method_request_to_path_with_headers_and_body
        response = session.send( request )
      File "/Library/Python/2.7/site-packages/requests/sessions.py", line 573, in send
        r = adapter.send(request, **kwargs)
      File "/Library/Python/2.7/site-packages/requests/adapters.py", line 415, in send
        raise ConnectionError(err, request=request)
    ConnectionError: [Errno 32] Broken pipe

Запрос

POST /resources HTTP/1.1
Host: api.corvusoft.co.uk
Connection: close
Content-Type: application/vnd.api+json; charset=utf-8
Accept: application/vnd.api+json
Accept-Charset: utf-8

{ "data": {"core-temperature": "1,430", "core-temperature-units": "celsius", ... } }

отклик

HTTP/1.1 411 Length Required
Connection: close
Content-Type: application/vnd.api+json; charset=utf-8
Content-Length: 304

{"errors":[{"status":"411","title":"Content Length Required", "description": "The server refuses to accept the request without a defined Content-Length. The client MAY repeat the request if it adds a valid Content-Length header field containing the length of the message-body in the request message."}]}

Среда

Python: 2.7.5

Запросы: 2.5.3

0 ответов

Другие вопросы по тегам