您的位置:

处理tornado出现报错httputil.HTTPInputError("Response with both Transfer-Encoding and Content-Length")

  发布时间:2025-01-02 16:44:45
问题原因是tornado框架出现httputil.HTTPInputError异常的原因是HTTP协议规范中不允许同时使用Transfer-Encoding和Content-Length这两个响应头。解决方案包括在Tornado应用程序中配置,禁用自动的Transfer-Encoding头部设置,或通过中间件或代理服务器处理响应头部。具体例子展示了如何正确处理该错误。

问题原因

tornado框架出现httputil.HTTPInputError("Response with both Transfer-Encoding and Content-Length")的原因是HTTP协议规范中不允许同时使用Transfer-EncodingContent-Length这两个响应头。在HTTP协议中,Transfer-Encoding用于标识传输数据的编码方式,而Content-Length用于标识响应正文的长度。当一个响应同时包含这两个头部信息时,就会导致不符合HTTP协议标准,从而触发tornado抛出httputil.HTTPInputError异常。

解决方案

tornado库中出现httputil.HTTPInputError("Response with both Transfer-Encoding and Content-Length")这个错误的原因是因为 HTTP 响应中同时存在 Transfer-EncodingContent-Length 两种不兼容的头部信息。这种情况在 HTTP 协议中是不允许的,因为 Transfer-Encoding 指示了数据传输时的编码方式,而 Content-Length 则表示消息主体的长度,这两者不能同时出现在同一个响应中。 要解决这个问题,我们可以通过以下两种方法之一: 1. 在Tornado应用程序中进行配置,禁用自动的 Transfer-Encoding 头部设置,从而避免同时设置 Transfer-EncodingContent-Length。可以通过设置HTTPRequest对象的allow_nonstandard_methods属性为True来实现。示例代码如下:


http_client = httpclient.HTTPClient()
request = httpclient.HTTPRequest(url, allow_nonstandard_methods=True)
response = http_client.fetch(request)
  1. 如果无法修改Tornado应用程序的配置,可以考虑通过中间件或代理服务器,在请求到达应用程序之前修改响应头部,确保响应中只包含一种方式来指示消息体的传输方式(Transfer-EncodingContent-Length),而不是同时包含两种。这样可以确保请求符合HTTP协议标准,避免出现这个错误。 无论采用哪种方法,都需要确保在处理HTTP请求和响应时,遵循HTTP协议的规范,避免出现不兼容的头部信息,以确保应用程序的稳定性和正确性。

    具体例子

    当Tornado出现httputil.HTTPInputError("Response with both Transfer-Encoding and Content-Length")错误时,这通常是因为收到的HTTP响应头中同时包含了Transfer-EncodingContent-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错误。