5

suppose i want to use curl to put a file to a webservice this way

curl -v --location --upload-file file.txt http://localhost:4567/upload/filename

in sinatra i can do:

#!/usr/bin/env ruby

require 'rubygems'
require 'sinatra'

put '/upload/:id' do
   #
   # tbd
   #
end

how can i read the streaming file?

more or less i want something like this: http://www.php.net/manual/en/features.file-upload.put-method.php#56985

  • [This question](http://stackoverflow.com/questions/4795205/streaming-web-uploads-to-socket-with-rack) implies that what you want cannot be done, but I don't yet know enough about this to be sure enough to post it as an answer. – Phrogz Feb 02 '11 at 03:12
  • @Phrogz I just found this: http://groups.google.com/group/rack-devel/msg/600825afa08474d8 - thought you might be interested. – matt Jun 29 '11 at 21:17

2 Answers2

4

The most basic example is writing it to the currect directory you are running sinatra in with no checking for existing files ... just clobbering them.

#!/usr/bin/env ruby

require 'rubygems'
require 'sinatra'

put '/upload/:id' do
  File.open(params[:id], 'w+') do |file|
    file.write(request.body.read)
  end
end

Also, you can leave off the filename portion in the curl command and it will fill it in for you with the filename. Foe example:

curl -v --location --upload-file file.txt http://localhost:4567/upload/

will result in writing the file to http://localhost:4567/upload/file.txt

Ben
  • 9,725
  • 6
  • 23
  • 28
  • Does the route block wait to run until the request is finished, or does this allow for streaming the results as they arrive? – Phrogz Feb 02 '11 at 05:23
  • I don't know about the streaming ... I missed that detail – Ben Feb 02 '11 at 05:58
2
require 'rubygems'
require 'sinatra'
require 'ftools'

put '/upload' do
  tempfile = params['file'][:tempfile]
  filename = params['file'][:filename]
  File.mv(tempfile.path,File.join(File.expand_path(File.dirname(File.dirname(__FILE__))),"public","#{filename}"))
  redirect '/'
end

In this way, you does not have to worry about the size of the file, since he's not opened (readed) in memory but just moved from the temp directory to the right location skipping a crucial blocker. In fact, the php code do the same stuff, read the file in 1k chunks and store in a new file, but since the file its the same, its pointless. To try you can follow the answer of Ben.