Ruby: How to post a file via HTTP as multipart/form-data?

I like RestClient. It encapsulates net/http with cool features like multipart form data:

require 'rest_client'
RestClient.post('http://localhost:3000/foo', 
  :name_of_file_param => File.new('/path/to/file'))

It also supports streaming.

gem install rest-client will get you started.


Another one using only standard libraries:

uri = URI('https://some.end.point/some/path')
request = Net::HTTP::Post.new(uri)
request['Authorization'] = 'If you need some headers'
form_data = [['photos', photo.tempfile]] # or File.open() in case of local file

request.set_form form_data, 'multipart/form-data'
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http| # pay attention to use_ssl if you need it
  http.request(request)
end

Tried a lot of approaches but only this was worked for me.


I can't say enough good things about Nick Sieger's multipart-post library.

It adds support for multipart posting directly to Net::HTTP, removing your need to manually worry about boundaries or big libraries that may have different goals than your own.

Here is a little example on how to use it from the README:

require 'net/http/post/multipart'

url = URI.parse('http://www.example.com/upload')
File.open("./image.jpg") do |jpg|
  req = Net::HTTP::Post::Multipart.new url.path,
    "file" => UploadIO.new(jpg, "image/jpeg", "image.jpg")
  res = Net::HTTP.start(url.host, url.port) do |http|
    http.request(req)
  end
end

You can check out the library here: http://github.com/nicksieger/multipart-post

or install it with:

$ sudo gem install multipart-post

If you're connecting via SSL you need to start the connection like this:

n = Net::HTTP.new(url.host, url.port) 
n.use_ssl = true
# for debugging dev server
#n.verify_mode = OpenSSL::SSL::VERIFY_NONE
res = n.start do |http|

Tags:

Http

Ruby

Post