Nobody knows how to upload a file with Ruby Net::HTTP
As a hobby project, I’m currently working on my gem http_wrapper, and right now I’m implementing file uploads. I’m not a big fan of reinventing wheels, especially when someone has already invented a perfectly round one, so the first thing I did was google possible solutions. And this is where it gets funny: I couldn’t find a single one that showed the right way to upload a file with Net::HTTP. People suggest ready-made wrappers (like Rest Client and httparty), or gems that implement multipart/form-data specifically (for example, multipart-post), or even calling curl through a system call. Horrifying, really.
None of that appealed to me, so I started digging through the guts of Net::HTTP. In the end I unearthed a big secret (judging by the fact that I couldn’t find it anywhere else on the internet), and now I’m sharing it with you: how to properly upload a file with Ruby’s standard library Net::HTTP:
require 'net/http'
# prepare the uri we'll be sending the data to
uri = URI 'http://example.com/upload_form'
# set up a new connection
connection = Net::HTTP.new uri.host, uri.port
# create the POST request object
request = Net::HTTP::Post.new uri
# build the form data
form_data = [
['user_avatar', File.read('kartinko.jpg'), {filename: 'picture.jpg'}], # file content given as a "string"
['user_photo', File.open('photo.jpg')], # file content given as a File object
# any other form fields go right here in the same format:
['submit', 'true'],
['user_name', 'valera']
]
# attach the data to the request
request.set_form form_data, 'multipart/form-data'
# send the request
response = connection.request request
#...
Profit! :)