[~/sinatra/sinatra-upload]$ tree . |-- app.rb |-- uploads | `--- README `--- views `--- upload.haml 2 directories, 3 files
The important part is not to forget to set the enctype
in your form element, otherwise you will just get the filename instead of an object:
[~/sinatra/sinatra-upload(master)]$ cat views/upload.haml %html %body %h1 File uploader! %form(method="post" enctype='multipart/form-data') %input(type='file' name='myfile') %br %input(type='submit' value='Upload!')
[~/sinatra/sinatra-upload(master)]$ cat app.rb require 'rubygems' require 'sinatra' require 'haml' require 'pp' # Handle GET-request (Show the upload form) get "/upload?" do haml :upload end # Handle POST-request (Receive and save the uploaded file) post "/upload" do pp params File.open('uploads/' + params['myfile'][:filename], "w") do |f| f.write(params['myfile'][:tempfile].read) end return "The file was successfully uploaded!" end [~/sinatra/sinatra-upload(master)]$
As you can see, you don’t have to write much code to get this to
work. The params
-hash contains our uploaded element with data such
as filename, type and the actual datafile, which can be accessed
as a Tempfile-object.
We read the contents from this file and store it into a directory called uploads, which you will have to create before running this script.
Here’s an example of what the params
-hash may look like when uploading
a picture of a cat:
{ "myfile" => { :type => "image/png", :head => "Content-Disposition: form-data; name=\"myfile\"; filename=\"cat.png\"\r\n Content-Type: image/png\r\n", :name => "myfile", :tempfile => #<File:/var/folders/3n/3asd/-Tmp-/RackMultipart201-1476-nfw2-0>, :filename=>"cat.png" } }
File upload with sinatra. YouTube
This script offers little to no security at all. Clients will be able to overwrite old images, fill up your harddrive and so on. So just use some common sense and do some Ruby magic to patch up the security holes yourself.