请求是否正确支持多部分响应?

时间:2018-03-17 15:52:34

标签: python python-requests

收到多部分回复时收到错误。

WARNING connectionpool  Failed to parse headers (url=************): [StartBoundaryNotFoundDefect(), MultipartInvariantViolationDefect()], unparsed data: ''
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/urllib3/connectionpool.py", line 399, in _make_request
    assert_header_parsing(httplib_response.msg)
  File "/usr/local/lib/python3.6/site-packages/urllib3/util/response.py", line 66, in assert_header_parsing
    raise HeaderParsingError(defects=defects, unparsed_data=unparsed_data)
urllib3.exceptions.HeaderParsingError: [StartBoundaryNotFoundDefect(), MultipartInvariantViolationDefect()], unparsed data: ''

这是否意味着该库不支持多部分响应?我服务器的响应适用于所有其他情况,包括浏览器,所以我有点困惑。

有什么想法吗?

这是从服务器返回的内容(当然为了简洁而截断了主体):

HTTP/1.1 200 OK
X-Powered-By: Servlet/3.1
X-CA-Affinity: 2411441258
Cache-Control: no-cache
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Content-Encoding: gzip
X-Compressed-By: BICompressionFilter
Content-Type: multipart/related; type="text/xml"; boundary="1521336443366.-7832488688540884419.-1425166373"
Content-Language: en-US
Transfer-Encoding: chunked
Date: Sun, 18 Mar 2018 01:27:23 GMT

a

154e
<i  ʲ O  x\龅L   dre     Qyi  
/su  k 

当然这是编码的。如果我在Fiddler中对它进行解码,这就是它的样子:

HTTP/1.1 200 OK
X-Powered-By: Servlet/3.1
X-CA-Affinity: 2411441258
Cache-Control: no-cache
Expires: Thu, 01 Jan 1970 00:00:00 GMT
X-Compressed-By: BICompressionFilter
Content-Type: multipart/related; type="text/xml"; boundary="1521336443366.-7832488688540884419.-1425166373"
Content-Language: en-US
Date: Sun, 18 Mar 2018 01:27:23 GMT
Content-Length: 17419


--1521336443366.-7832488688540884419.-1425166373
Content-Type: text/xml; charset=utf-8
Content-Length: 15261

<?xml version="1.0" encoding="UTF-8"?>

1 个答案:

答案 0 :(得分:2)

要回答您的问题:是的,请求可以很好地处理多部分请求。话虽如此,我也看到了同样的错误。

这似乎是urllib3中的错误,但可能与python随附的httplib包一样深。在您的情况下,我想它会返回到响应的UTF-8编码,显然您不能做很多事情(除非您还维护服务器端)。我相信完全可以忽略,但仅包含urllib3.disable_warnings()似乎对我来说并不有用。如果要使此特定警告静音,可以在代码中包括日志记录过滤器。 (使用此方法,请向home-assistant维护者致谢)

def filter_urllib3_logging():
    """Filter header errors from urllib3 due to a urllib3 bug."""
    urllib3_logger = logging.getLogger("urllib3.connectionpool")
    if not any(isinstance(x, NoHeaderErrorFilter)
               for x in urllib3_logger.filters):
        urllib3_logger.addFilter(
            NoHeaderErrorFilter()
        )


class NoHeaderErrorFilter(logging.Filter):
    """Filter out urllib3 Header Parsing Errors due to a urllib3 bug."""

    def filter(self, record):
        """Filter out Header Parsing Errors."""
        return "Failed to parse headers" not in record.getMessage()

然后,只需在设置中调用filter_urllib3_logging()。它不会停止警告,但会隐藏它们:D

!请注意!!这也会隐藏起来,因此很难诊断由解析标头引起的任何错误,有时可能是合法错误!