处理tornado出现报错httputil.HTTPInputError("Response with both Transfer-Encoding and Content-Length")
问题原因
tornado
框架出现httputil.HTTPInputError("Response with both Transfer-Encoding and Content-Length")
的原因是HTTP协议规范中不允许同时使用Transfer-Encoding
和Content-Length
这两个响应头。在HTTP协议中,Transfer-Encoding
用于标识传输数据的编码方式,而Content-Length
用于标识响应正文的长度。当一个响应同时包含这两个头部信息时,就会导致不符合HTTP协议标准,从而触发tornado
抛出httputil.HTTPInputError
异常。
解决方案
tornado
库中出现httputil.HTTPInputError("Response with both Transfer-Encoding and Content-Length")
这个错误的原因是因为 HTTP 响应中同时存在 Transfer-Encoding
和 Content-Length
两种不兼容的头部信息。这种情况在 HTTP 协议中是不允许的,因为 Transfer-Encoding
指示了数据传输时的编码方式,而 Content-Length
则表示消息主体的长度,这两者不能同时出现在同一个响应中。
要解决这个问题,我们可以通过以下两种方法之一:
1. 在Tornado
应用程序中进行配置,禁用自动的 Transfer-Encoding
头部设置,从而避免同时设置 Transfer-Encoding
和 Content-Length
。可以通过设置HTTPRequest
对象的allow_nonstandard_methods
属性为True
来实现。示例代码如下:
http_client = httpclient.HTTPClient()
request = httpclient.HTTPRequest(url, allow_nonstandard_methods=True)
response = http_client.fetch(request)
- 如果无法修改
Tornado
应用程序的配置,可以考虑通过中间件或代理服务器,在请求到达应用程序之前修改响应头部,确保响应中只包含一种方式来指示消息体的传输方式(Transfer-Encoding
或Content-Length
),而不是同时包含两种。这样可以确保请求符合HTTP协议标准,避免出现这个错误。 无论采用哪种方法,都需要确保在处理HTTP请求和响应时,遵循HTTP协议的规范,避免出现不兼容的头部信息,以确保应用程序的稳定性和正确性。具体例子
当Tornado出现httputil.HTTPInputError("Response with both Transfer-Encoding and Content-Length")
错误时,这通常是因为收到的HTTP响应头中同时包含了Transfer-Encoding
和Content-Length
字段,这是不符合HTTP协议规范的。 要正确处理这个问题,可以通过禁用Tornado的自动Content-Length
特性来解决。在处理HTTP请求的时候,需要在HTTPClient
对象的构造函数中设置defaults
参数,将use_gzip
设置为False
,以避免Tornado在处理HTTP响应时自动添加Content-Length
头。 以下是一个示例代码,展示了如何正确使用Tornado处理HTTP请求并避免出现该错误:
import tornado.ioloop
import tornado.httpclient
def handle_response(response):
if response.error:
print("Error:", response.error)
else:
print(response.body)
def fetch_data():
http_client = tornado.httpclient.HTTPClient()
try:
response = http_client.fetch("http://example.com/api", use_gzip=False)
handle_response(response)
except Exception as e:
print("Error fetching data:", e)
http_client.close()
if __name__ == "__main__":
fetch_data()
tornado.ioloop.IOLoop.current().start()
在上面的例子中,我们创建了一个HTTPClient
对象,并在发起HTTP请求时将use_gzip
设置为False
,这样就可以避免Tornado自动添加Content-Length
头,并解决了Response with both Transfer-Encoding and Content-Length
错误。