2009-06-06 59 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。然而,在我將這個.dll放入我的Ruby/bin文件夾後,它給了我一個空的錯誤框,從那裏我無法進一步調試。所以這裏的問題是,機械化0.8.5依賴於Hpricot而不是Nokogiri(它完美地工作)。


接下來的想法是使用不同的gem,所以我嘗試使用Net :: HTTP。經過簡短的研究,我可以發現在Net :: HTTP中不存在對多部分表單的本地支持,相反,您必須構建一個爲您編碼等的類。我能找到的最有幫助的是Multipart-class by Stanislav Vitvitskiy。這個班目前看起來不錯,但它並沒有做我所需要的,因爲我不想發帖只有檔案,我也想發佈正常的數據,這對他的班級來說是不可能的。


我的最後一次嘗試是使用RestClient。這看起來很有希望,因爲已經有如何上傳文件的例子。然而,我無法將它作爲多部分發布。

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

我使用http://rest-test.heroku.com發回的請求,如果它被正確發送到調試,我總是把它恢復:

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

這清楚地表明,它不使用multipart/form-data作爲內容 - 類型,但標準application/x-www-form-urlencoded,雖然它絕對看到pict是一個文件。


如何上傳在Ruby中一個文件到一個多形式,但沒有實施全編碼和數據對準自己?

回答

9

長問題,簡短回答:我錯過了在Windows下閱讀圖像的二進制模式。

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

必須是

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

1

的另一種方法是使用Bash和捲曲。當我想測試多個文件上傳時,我使用了這種方法。

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 
相關問題