Django 尝试SSE报错 AssertionError: Hop-by-hop headers not allowed 的分析

情况描述

近期计划测试一下django对日志打印的支持,一般都是用websocket的方式,想测试一下SSE 的服务端推送,发现过程中存在报错:

Traceback (most recent call last):
  File "D:\Software\Anaconda3\lib\wsgiref\handlers.py", line 137, in run
    self.result = application(self.environ, self.start_response)
  File "D:\IDE Projects\Music\venv\lib\site-packages\django\contrib\staticfiles\handlers.py", line 76, in __call__
    return self.application(environ, start_response)
  File "D:\IDE Projects\Music\venv\lib\site-packages\django\core\handlers\wsgi.py", line 142, in __call__
    start_response(status, response_headers)
  File "D:\Software\Anaconda3\lib\wsgiref\handlers.py", line 249, in start_response
    assert not is_hop_by_hop(name),"Hop-by-hop headers not allowed"
AssertionError: Hop-by-hop headers not allowed

部分代码

    response = HttpResponse(content_type='text/event-stream')
    response['Cache-Control'] = 'no-cache'
    # AssertionError: Hop-by-hop headers not allowed
    response['Connection'] = 'keep-alive'
    response['Transfer-Encoding'] = 'chunked'

初步分析

1)报错大致是说Hop-by-hop headers not allowed ,说是HTTP1.0 不支持这个头部

HTTP 首部字段将定义成缓存代理和非缓存代理的行为,分成 2 种类型。

端到端首部(End-to-end Header)
分在此类别中的首部会转发给请求 / 响应对应的最终接收目标,且必须保存在由缓存生成的响应中,另外规 定它必须被转发。

逐跳首部(Hop-by-hop Header)
分在此类别中的首部只对单次转发有效,会因通过缓存或代理而不再转发。HTTP/1.1 和之后版本中,如果要使用 hop-by-hop 首部,需提供 Connection 首部字段。

2)依据堆栈信息,找到对应的判断函数 is_hop_by_hop(name) ,只要头部存在如下的集合元素,就会被判定为 hop_by_hop

# wsgiref\handlers.py
        if __debug__:
            for name, val in headers:
                name = self._convert_string_type(name, "Header name")
                val = self._convert_string_type(val, "Header value")
                assert not is_hop_by_hop(name),"Hop-by-hop headers not allowed"

# handlers\wsgi.py
_hoppish = {
    'connection':1, 'keep-alive':1, 'proxy-authenticate':1,
    'proxy-authorization':1, 'te':1, 'trailers':1, 'transfer-encoding':1,
    'upgrade':1
}.__contains__

def is_hop_by_hop(header_name):
    """Return true if 'header_name' is an HTTP/1.1 "Hop-by-Hop" header"""
    return _hoppish(header_name.lower())

3)于是乎,我把Connection 和 Transfer-Encoding 注释掉,就正常了

总结

未完待续!!!

参考链接:
HTTP 首部字段详细介绍
Python __debug__内置变量的用法

你可能感兴趣的:(实用类,异常与报错,django,python)