mara redeghieri
mara redeghieri

Reputation: 51

sinatra and http PUT

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

Upvotes: 5

Views: 3222

Answers (2)

Francesco Vollero
Francesco Vollero

Reputation: 41

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.

Upvotes: 2

Ben
Ben

Reputation: 9895

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

Upvotes: 4

Related Questions