Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sinatra and http PUT

Tags:

ruby

sinatra

rack

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

like image 976
mara redeghieri Avatar asked Feb 01 '11 19:02

mara redeghieri


2 Answers

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

like image 102
Ben Avatar answered Nov 18 '22 02:11

Ben


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.

like image 2
Francesco Vollero Avatar answered Nov 18 '22 00:11

Francesco Vollero