UPDATE: The kind folks developing Requests.py are on the case.
We're interacting (testing) with a HTTP service that responds with a 411 (Length Required) status code when no Content-Length request header has been supplied in the presence of a request body; This is to be expected as per RFC 2616.
The problem we've encountered centres around the Requests Python Module (curl works as expected). When sending an illformed request (lacking Content-Length in the presence of a request body) the service responds 411 and the connection is closed by the remote endpoint (Connection: close). This in turn throws an exception from the Requests Session.send method and we're unable to retrieve the HTTP response status code for validation.
Is it possible to stop this situation (exception) and retrieve the HTTP response status code without altering the HTTP service?
Code
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
Stack Trace
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
Request
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", ... } }
Response
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."}]}
Environment
Python: 2.7.5
Requests: 2.5.3