我可以让 Sinatra / Rack 不将整个请求正文读入内存吗?

发布于 2024-09-05 08:15:25 字数 334 浏览 5 评论 0原文

假设我有一条 Sinatra 路线 ala:

put '/data' do
  request.body.read
  # ...
end

看起来整个 request.body 都被读入内存。有没有办法在主体进入系统时消耗它,而不是预先将其全部缓冲在 Rack/Sinatra 中?

我发现我可以这样做来读取部分正文,但整个正文似乎仍然被预先读入内存。

put '/data' do
  while request.body.read(1024) != nil 
    # ...
  end
  # ...
end

Say I have a Sinatra route ala:

put '/data' do
  request.body.read
  # ...
end

It appears that the entire request.body is read into memory. Is there a way to consume the body as it comes into the system, rather than having it all buffered in Rack/Sinatra beforehand?

I see I can do this to read the body in parts, but the entire body still seems to be read into memory beforehand.

put '/data' do
  while request.body.read(1024) != nil 
    # ...
  end
  # ...
end

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

情话难免假 2024-09-12 08:15:25

如果不修补 Sinatra 和/或 Rack,通常无法避免这种情况。当request.POST由 Sinatra 调用来创建 参数

但是你可以在 Sinatra 前面放置一个中间件来删除主体:

require 'sinatra'
require 'stringio'

use Rack::Config do |env|
  if env['PATH_INFO'] == '/data' and env['REQUEST_METHOD'] == 'PUT'
    env['rack.input'], env['data.input'] = StringIO.new, env['rack.input']
  end
end

put '/data' do
  while request.env['data.input'].body.read(1024) != nil 
    # ...
  end
  # ...
end

You cannot avoid this in general without patching Sinatra and/or Rack. It is done by Rack::Request when request.POST is called by Sinatra to create params.

But you could place a middleware in front of Sinatra to remove the body:

require 'sinatra'
require 'stringio'

use Rack::Config do |env|
  if env['PATH_INFO'] == '/data' and env['REQUEST_METHOD'] == 'PUT'
    env['rack.input'], env['data.input'] = StringIO.new, env['rack.input']
  end
end

put '/data' do
  while request.env['data.input'].body.read(1024) != nil 
    # ...
  end
  # ...
end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文