Reading body stream in Sinatra

半世苍凉 提交于 2019-12-12 04:05:17

问题


I'm trying to upload a file with XHR request using PUT method with Sinatra. My first idea was to upload the file and writing the stream directly into a MongoDB GridFS

@fs.open("test.iso", "w") do |f|
  f.write request.body.read
end 

It works, but, it loads the entire file into the RAM and it write it into the MongoDB GridFS. I'd like to avoid this behavior by writing it continuously to the GridFS (stream the file, not loading it and put it in the GridFS) without loading the entire file into the RAM : because for huge files (like 1GB or more) it's clearly a bad practice (due to RAM consumption).

How can I do that ?

EDIT : Can I have Sinatra / Rack not read the entire request body into memory? method is creating a TempFile, the thing is I want to only work with streams to optimize memory consumption on server-side. Like a php://input would do in PHP.

EDIT 2 :

Here is how I'm currently handling it :

  • HTML/JS part
  • Ruby/Sinatra part

回答1:


It looks like the streaming support in Sinatra is only in the opposite direction for long running GET requests out to the client.

If you do a POST multipart upload, Sinatra will write the data to a tempfile and provide you with the details in the params Hash.

require 'sinatra'
require 'fileutils'

post '/upload' do
  tempfile = params['file'][:tempfile]
  filename = params['file'][:filename]
  FileUtils.mv(tempfile.path, "test.iso")
  "posted"
end

While in the same sinatra directory:

$ echo "testtest" > /tmp/file_to_upload
$ curl --form "file=@/tmp/file_to_upload" http://localhost:4567/upload
posted
$ cat test.iso
testtest


来源:https://stackoverflow.com/questions/24699700/reading-body-stream-in-sinatra

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!