分块读取上传内容并不需要分块 HTTP
当上传经由正向代理表现不同时,把有界的应用读取与 HTTP/1.1 报文分帧区分开来。
不需要。客户端可以用小块缓冲区读取大文件,并以已知的 Content-Length 发送。有界读取控制内存占用;HTTP 分帧则告诉接收方请求体在哪里结束。
字节长度已知的稳定文件,与产出未知数据量的生成器并不相同。无论哪种来源,都应使用库所支持的请求体接口。你不需要仅仅为了给出长度而把整个文件拼成一个字符串。
对 HTTP/1.1 而言,要检查实际发出的分帧方式:按协议规则使用 Content-Length 或 chunked 传输编码。chunked 编码会在文件内容之外附加长度标记。不要混用相互矛盾的分帧字段,也不要为了让代理接受上传而猜测长度。
如果经代理的上传失败,记录 HTTP 版本、请求体来源和第一次拒绝。411 响应所指向的排查方向,与连接在请求体传到一半时关闭并不相同。如果失败的是身份验证重试,则检查上传内容能否重放。改动应用的读取缓冲区大小,可能使请求分帧保持原样不变。
路径会影响这一观察。明文转发会把上传的 HTTP 分帧暴露给代理;普通的端到端 HTTPS 则把它放进隧道里。HTTP/2 使用自己的分帧。因此 Squid 历史上的限制只能解释某些旧的失败,而不是一条“如今每个代理都会拒绝流式上传”的规则。