2009-06-06 16 views
7

POSTを使用して画像をサーバーにアップロードするだけです。このタスクが簡単に聞こえるように、Rubyでは単純な解決策はないようです。Rubyでのマルチファイルアップロード

私はあまりにもこのためにそれを使用したいので、ほとんどのもののために WWW::Mechanizeを使用して、このようなソースを持っています私のアプリケーションで

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

これは、サーバー上で完全にゴミ対応ファイルになりそれはすべての上に、スクランブルになります

alt text http://imagehub.org/f/1tk8/garbage.png

私の次のステップは、WWWをダウングレードすることでした::に機械化バージョン0.8.5。これは、 "モジュールがhpricot_scan.soに見つかりません"のようなエラーで失敗して実行するまで動作しました。 Dependency Walkerツールを使用すると、hpricot_scan.soにmsvcrt-ruby18.dllが必要であることがわかりました。それでも私はRuby/binフォルダに.dllファイルを置いた後、空のエラーボックスを表示して、どこからでもデバッグできなかった。ですから、ここでの問題は、Mechanize 0.8.5がNokogiriの代わりにHpricotに依存することです(完璧に動作します)。


次のアイデアは別の宝石を使用することだったので、私はNet :: HTTPを使ってみました。短い研究の後、私はNet :: HTTPにマルチパートフォームのネイティブサポートがないことを知ることができ、代わりにあなたのためにコード化するクラスを構築しなければなりません。私が見つけた最も役に立つのはMultipart-class by Stanislav Vitvitskiyでした。これまでのところ、このクラスは良く見えましたが、私が必要とすることはしません。ファイルのみをに投稿したくないので、普通のデータを投稿したいと思っています。


最後に、RestClientを使用していました。これは、ファイルをアップロードする方法の例があるので有望視されました。しかし、私はマルチパートとしてフォームを投稿することはできません。これは明らかにそれがのContentとしてmultipart/form-dataを使用していないことを示して

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" 
}

:私はそれが正しく送信された場合にデバッグするために要求を送り返すhttp://rest-test.heroku.comを使用しています、と私はいつもこれを取り戻す

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

タイプは標準application/x-www-form-urlencodedですが、確かにpictはファイルです。


どのように私は自分自身を合わせ、全データを符号化および実装せずにマルチパートフォームにRubyでファイルをアップロードすることができますか?

答えて

9

長い問題、短い答え:私はWindowsでイメージを読むためのバイナリモードが欠けていました。

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

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

1

しなければならなかったもう一つの方法は、バッシュとカールを使用することです。私は複数のファイルのアップロードをテストしたいときにこの方法を使用しました。

bash_command = 'curl -v -F "[email protected],texas_reversed.png"       
http://localhost:9292/fog_upload/upload' 
command_result = `#{bash_command}` # the backticks are important <br/> 
puts command_result