Python3 ThreadingHTTPServer发送分块编码响应异常问题求助
问题根源:分块编码的长度格式错误
嘿,我一眼就看穿问题所在了——你误用了HTTP分块编码的长度格式!
核心问题
HTTP/1.1的分块编码(Chunked Transfer Encoding)明确要求:每个块开头的长度必须是十六进制数字,而不是你代码里用的十进制。
- 当块长度≤9时,十进制和十六进制的表示完全一致(比如9的十进制和十六进制都是
9),所以客户端能正确解析; - 但当长度≥10时,十进制的
10并不是有效的十六进制长度标识(正确的十六进制应该是a或A),客户端(比如Postman)无法识别这个格式,就会一直等待符合规范的长度数据,最终导致超时或卡住。
修正后的代码
只需要把块长度的格式化方式从十进制改成十六进制就行,用格式字符串的x标识符(小写或大写都可以,HTTP规范不区分大小写):
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer class ProxyHTTPRequestHandler(BaseHTTPRequestHandler): protocol_version = 'HTTP/1.1' def do_GET(self, body=True): # HTTP 200 + minimal HTTP headers in response self.send_response(200) self.send_header('transfer-encoding', 'chunked') self.send_header('Content-Type', 'text/plain') self.end_headers() # writing 5 chunks of 10 characters - fixed chunk length format for i in range(5): text = str(i+1) * 10 # concatenate 10 chars # 关键修改:用十六进制格式化长度 chunk = '{0:x}\r\n'.format(len(text)) + text + '\r\n' self.wfile.write(chunk.encode(encoding='utf-8')) # 可选但推荐:刷新缓冲区,确保数据立即发送到客户端 self.wfile.flush() # writing close sequence close_chunk = '0\r\n\r\n' self.wfile.write(close_chunk.encode(encoding='utf-8')) self.wfile.flush() def main(): try: server_address = ('127.0.0.1', 8099) httpd = ThreadingHTTPServer(server_address, ProxyHTTPRequestHandler) print('http server is running') httpd.serve_forever() except KeyboardInterrupt: print(" ^C entered, stopping web server...") httpd.socket.close() if __name__ == '__main__': main()
额外注意事项
- 分块长度的细节:十六进制长度不能有前导零(除非长度本身就是0),比如长度8不能写成
08,直接写8就好。 - 刷新缓冲区:添加
self.wfile.flush()可以确保每个块的数据立即发送,避免因缓冲区累积导致客户端延迟接收。 - 结束块规范:必须以
0\r\n\r\n作为响应的结束标记,告诉客户端所有块已发送完毕。
修改后再测试,不管块长度是10还是更大的数值(比如16,对应的十六进制是10),客户端都能正确解析所有分块数据了。
内容的提问来源于stack exchange,提问作者manuel_b
相关产品推荐
相关产品推荐

