更新: 开发 Requests.py 的好心人正在处理此案。
我们正在与 HTTP 服务进行交互(测试),该服务在存在请求正文的情况下未提供Content-Length请求标头时响应 411(需要长度)状态代码;根据RFC 2616 ,这是可以预料的。
我们遇到的问题围绕请求 Python 模块(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."}]}
环境
蟒蛇:2.7.5
要求:2.5.3