I just want to upload the image to the server using POST. Itβs simpler how this task sounds, in Ruby there is no simple solution.
In my application, I use WWW :: Mechanize for most things, so I wanted to use it for this too, and I had a source like this:
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
The result is a server-ready file that looks scrambled:
alt text http://imagehub.org/f/1tk8/garbage.png
My next step was to downgrade WWW :: Mechanize to version 0.8.5. This worked until I tried to start it, which did not work with an error, for example, "The module was not found in hpricot_scan.so". Using the Dependency Walker tool, I could find out that hpricot_scan.so needed msvcrt-ruby18.dll. But after I put this .dll in my Ruby / bin folder, I gave me an empty field with an error, from where I could not debug much more. Therefore, the problem is that Mechanize 0.8.5 has a dependency on Hpricot instead of Nokogiri (which works flawlessly).
The next idea was to use another gem, so I tried using Net :: HTTP. After a little research, I could find out that Net :: HTTP does not have built-in support for multi-part forms, and instead you need to build a class that encodes, etc. For you. The most useful I could find is the multiparty class of Stanislav Vitvitsky . This class looked good so far, but it does not do what I need, because I do not want to publish only files, I also want to publish normal data, and this is not possible with its class.
My last attempt was to use RestClient . It looked promising since there were examples of how to upload files. However, I canβt get him to publish the form as multi-part.
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
I use http://rest-test.heroku.com , which sends a debug request if it is sent correctly, and I always get this back:
POST http://rest-test.heroku.com/ with a 101 byte payload,
content type application / x-www-form-urlencoded
{
"pict" => "# <File: 0x30d30c4>",
"username" => "s1kx",
"pict_to" => "0",
"function" => "picture2",
"pict_type" => "0",
"password" => "password"
} This clearly shows that it does not use multipart/form-data as the content type, but the standard application/x-www-form-urlencoded , although it definitely sees that pict is a file.
How to upload a file in Ruby in a multi-page form without implementing all encoding and data alignment?