Note that there are some explanatory texts on larger screens.

plurals
  1. POMultipart File Upload in Ruby
    text
    copied!<p>I simply want to upload an image to a server with POST. As simple as this task sounds, there seems to be no simple solution in Ruby.</p> <p>In my application I am using <a href="http://mechanize.rubyforge.org/" rel="noreferrer">WWW::Mechanize</a> for most things so I wanted to use it for this too, and had a source like this:</p> <pre><code>f = File.new(filename, File::RDWR) reply = agent.post( 'http://rest-test.heroku.com', { :pict => f, :function => 'picture2', :username => @username, :password => @password, :pict_to => 0, :pict_type => 0 } ) f.close</code></pre> <p>This results in a totally garbage-ready file on the server that looks scrambled all over:</p> <blockquote> <p><a href="http://imagehub.org/f/1tk8/garbage.png" rel="noreferrer">alt text http://imagehub.org/f/1tk8/garbage.png</a></p> </blockquote> <p>My next step was to downgrade WWW::Mechanize to version 0.8.5. This worked until I tried to run it, which failed with an error like "Module not found in hpricot_scan.so". Using the Dependency Walker tool I could find out that hpricot_scan.so needed msvcrt-ruby18.dll. Yet after I put that .dll into my Ruby/bin-folder it gave me an empty error box from where on I couldn't debug very much further. So the problem here is that Mechanize 0.8.5 has a dependency on Hpricot instead of Nokogiri (which works flawlessly).</p> <hr> <p>The next idea was to use a different gem, so I tried using Net::HTTP. After short research I could find out that there is no native support for multipart forms in Net::HTTP and instead you have to build a class that encodes etc. for you. The most helpful I could find was the <a href="http://stanislavvitvitskiy.blogspot.com/2008/12/multipart-post-in-ruby.html" rel="noreferrer">Multipart-class by Stanislav Vitvitskiy</a>. This class looked good so far, but it does not do what I need, because I don't want to post <em>only</em> files, I also want to post normal data, and that is not possible with his class.</p> <hr> <p>My last attempt was to use <a href="http://rest-client.heroku.com/rdoc/" rel="noreferrer">RestClient</a>. This looked promising, as there have been examples on how to upload files. Yet I can't get it to post the form as multipart.</p> <pre><code>f = File.new(filename, File::RDWR) reply = RestClient.post( 'http://rest-test.heroku.com', :pict => f, :function => 'picture2', :username => @username, :password => @password, :pict_to => 0, :pict_type => 0 ) f.close</code></pre> <p>I am using <a href="http://rest-test.heroku.com" rel="noreferrer">http://rest-test.heroku.com</a> which sends back the request to debug if it is sent correctly, and I always get this back:</p> <pre>POST http://rest-test.heroku.com/ with a 101 byte payload, content type application/x-www-form-urlencoded { "pict" => "#&lt;File:0x30d30c4&gt;", "username" => "s1kx", "pict_to" => "0", "function" => "picture2", "pict_type" => "0", "password" => "password" }</pre> <p>This clearly shows that it does not use <code>multipart/form-data</code> as content-type but the standard <code>application/x-www-form-urlencoded</code>, although it definitely sees that <code>pict</code> is a file.</p> <hr> <p><strong>How can I upload a file in Ruby to a multipart form without implementing the whole encoding and data aligning myself?</strong></p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload