Rails v6如何在客户端未发送Content-Length时填充请求内容长度?
Rails 6 自动计算请求内容长度的实现逻辑
Rails 6 针对未携带Content-Length头的分块传输请求,核心是在ActionDispatch::Request的参数解析流程中新增了兜底计算逻辑:
- 首先检测请求头是否缺少
Content-Length、且存在Transfer-Encoding: chunked标识 - 满足条件时会在解析参数前,将完整的请求输入流写入临时磁盘缓存
- 缓存写入完成后,自动将缓存文件的实际字节大小赋值给
content_length属性,后续所有框架和业务逻辑都可以正常读取该值
Rails 5 移植方案(猴子补丁)
在Rails 5项目的config/initializers/目录下新建backport_chunked_content_length.rb文件,添加如下代码即可复用Rails 6的该能力:
module ActionDispatch class Request def content_length # 已有Content-Length时直接返回原值 return super if get_header('CONTENT_LENGTH') # 仅对分块传输的请求做兜底处理 return unless get_header('HTTP_TRANSFER_ENCODING')&.include?('chunked') # 读取完整请求体到缓存,raw_post方法会自动缓存结果避免重复读取 raw_body = raw_post # 将计算出的长度写入请求头,避免后续重复计算 set_header('CONTENT_LENGTH', raw_body.bytesize.to_s) raw_body.bytesize end end end
提示:如果业务中存在超大文件上传场景,建议提前配置Rack最大请求体限制和临时文件存储路径,避免磁盘资源占用异常。
内容的提问来源于stack exchange,提问作者kukrt
相关产品推荐
相关产品推荐

