问题
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
回答1:
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
来源:https://stackoverflow.com/questions/3027564/can-i-have-sinatra-rack-not-read-the-entire-request-body-into-memory