调用requests.post触发urllib3.HeaderParsingError响应头被截断问题
异常原因分析
- 响应头不符合HTTP行折叠规范
你提供的curl输出中Access-Control-Allow-Headers被拆为两行,第二行trol,Content-Type开头没有空格/制表符前缀,不符合HTTP/1.1的头字段行折叠要求。curl本身对不规范响应的容错性极高,会自动拼接连续的非标准头行,而urllib3 1.26.7默认开启严格头校验,会将无冒号的第二行识别为无效内容,触发解析错误,也可能是后端应用生成该头字段时意外插入了换行符,导致头被强制拆分。 - Python标准库
http.client的长度限制触发截断
Python 3.8版本的http.client存在单行响应头最大长度限制(默认为65536字节,部分发行版会调低该值),如果你的Access-Control-Allow-Headers长度刚好接近阈值,就会被截断,剩余内容会被判定为未解析数据。 - Nginx代理buffer配置过小导致头分段
你观察到Python请求返回的是Transfer-Encoding: chunked、curl请求返回的是Content-Length,说明两次请求的响应传输方式不一致。如果Nginx的proxy_buffer_size、proxy_buffers配置过小,当转发的响应头超过buffer大小时,会将头内容拆分到多个TCP分段返回,urllib3的部分版本在解析跨TCP分段的连续头时存在已知bug,会误判头结束边界。 - 依赖库版本已知bug
requests==2.26.0搭配urllib3==1.26.7存在已知的头解析兼容问题:当反向代理返回的响应头尾部刚好落在TCP报文边界时,urllib3的解析逻辑会误将后续头内容识别为body前的无效数据,触发MissingHeaderBodySeparatorDefect报错,该问题在urllib3 1.26.9+版本已修复。
临时验证方案
- 升级urllib3到1.26.9或更高版本,确认是否复现问题
- 检查Nginx配置,将
proxy_buffer_size调整到至少4k,关闭不必要的头自动折叠逻辑 - 缩短
Access-Control-Allow-Headers的字段长度,避免单行头过长
内容的提问来源于stack exchange,提问作者user124114
相关产品推荐
相关产品推荐

