Ruby: How to Post a File Via Http as Multipart/Form-Data

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.

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

You already have access to a File instance (well, a TempFile instance) with params[:image].tempfile

Trash all the File.open stuff and simply construct an UploadIO with that:

UploadIO.new(params[:image].tempfile, ...)

Ruby: How to post a file?

The headers and params are in the wrong order. Consult the source here

The fixed call should be

File.open("./test.png") do |png|
req = Net::HTTP::Post::Multipart.new(uri.request_uri,
{"file" => UploadIO.new(png, "image/png", "image.png")}.merge(data))
res = Net::HTTP.start(url.host, url.port) do |http|
http.request(req)
end
end

Ruby post a file stream via HTTP as multipart/form-data?

You should be able to use any IO object, including a stream, as the parameter:

RestClient.post('http://localhost:3000/foo', :name_of_file_param => my_stream)

Uploading data via HTTP PUT without multi-part gutter

With net/http, set the request body to the file content as stream:

request.body_stream = File.open("#{file}")
request.content_length = File.size("#{file}")
request.content_type = "text/plain" # ?!

Determining the proper MIME type from the file alone is an adventure in itself.

How to send a multipart streaming request using httpclient in ruby

Regarding your first issue, it appears that the documentation is not correct. I've performed some tests, and the content type appears to be application/x-www-form-urlencoded. You need to set the content type explicitly:

body: body, header: {'Content-Type': 'multipart/form-data; boundary=ABC'}

That's not sufficient though. You also need to set the content disposition manually. For instance:

      body = [{ 'Content-Type' => 'application/atom+xml; charset=UTF-8',
'Content-Disposition' => 'form-data; name="name1"',
:content => '<entry>...</entry>' },
{ 'Content-Type' => 'video/mp4',
'Content-Disposition' => 'form-data; name="file"; filename="myfile.pdf"',
'Content-Transfer-Encoding' => 'binary',
:content => file }]

With this, httpbin reports one file and one form parameter.

Your second issue is related to the same. Both your files and values need to have the content disposition set. For instance (quick and dirty, style can probably be better):

files.each do |k, v|
request_body << { 'Content-Type' => v.content_type, :content => v.content, 'Content-Disposition' => 'form-data; name="' + k + '"; filename="' + v.filename + '"' }
end
values.each { |k, v| request_body << { :content => v, 'Content-Disposition' => 'form-data; name="' + k + '"' }}

Note that you should escape any " in a name or filename.



Related Topics



Leave a reply



Submit