Loading a multi-page file in Ruby

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?

+7
ruby upload multipart mechanize
source share
2 answers

Long problem, short answer: I lacked binary mode for reading images under Windows.

f = File.new(filename, File::RDWR)

should have been

f = File.new(filename, "rb")

+9
source share

Another method is to use Bash and Curl. I used this method when I wanted to test multiple file downloads.

 bash_command = 'curl -v -F "file=@texas.png,texas_reversed.png" http://localhost:9292/fog_upload/upload' command_result = `#{bash_command}` # the backticks are important <br/> puts command_result 
+1
source share

All Articles