2009-06-06 11 views
7

Ich möchte einfach ein Bild auf einen Server mit POST hochladen. So einfach diese Aufgabe klingt, es scheint keine einfache Lösung in Ruby zu geben.Multipart Datei-Upload in Ruby

In meiner Anwendung verwende ich WWW::Mechanize für die meisten Dinge so wollte ich es für diese auch verwenden, und hatte eine Quelle wie folgt aus:

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

Dies führt zu einer völlig Müll fertige Datei auf dem Server das sieht verschlüsselt alle über:

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

Mein nächster Schritt war WWW herabzustufen :: Mechanize zu Version 0.8.5. Dies funktionierte, bis ich versuchte, es auszuführen, was mit einem Fehler wie "Modul nicht gefunden in hpricot_scan.so" fehlschlug. Mit dem Dependency Walker Tool konnte ich herausfinden, dass hpricot_scan.so msvcrt-ruby18.dll benötigt. Aber nachdem ich diese .dll in meinen Ruby/bin-Ordner gelegt hatte, gab es mir eine leere Fehlerbox, von wo aus ich nicht viel weiter debuggen konnte. Das Problem ist also, dass Mechanize 0.8.5 eine Abhängigkeit von Hpricot anstelle von Nokogiri hat (was einwandfrei funktioniert).

Die nächste Idee war, ein anderes Juwel zu verwenden, also versuchte ich, Net :: HTTP zu verwenden. Nach kurzer Recherche konnte ich feststellen, dass es in Net :: HTTP keine native Unterstützung für mehrteilige Formulare gibt und stattdessen eine Klasse erstellen muss, die für Sie codiert. Am hilfreichsten war die Multipart-class by Stanislav Vitvitskiy. Diese Klasse sah bisher gut aus, aber sie tut nicht, was ich brauche, denn ich möchte keine nur Dateien posten, ich möchte auch normale Daten posten, und das ist mit seiner Klasse nicht möglich.


Mein letzter Versuch war RestClient zu verwenden. Dies sah vielversprechend aus, da es Beispiele zum Hochladen von Dateien gab. Trotzdem kann ich das Formular nicht als mehrteilig veröffentlichen.

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

ich http://rest-test.heroku.com bin mit der die Anfrage sendet zurück zu debuggen, wenn es richtig gesendet wird, und ich bekomme immer diese zurück:

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

Dies zeigt deutlich, dass es nicht multipart/form-data als Content- nicht verwendet Geben Sie aber den Standard application/x-www-form-urlencoded, obwohl es auf jeden Fall sieht, dass pict eine Datei ist.


Wie kann ich eine Datei in Ruby zu einer mehrteiligen Form laden, ohne die gesamte Codierung und Daten Umsetzung selbst ausrichten?

Antwort

9

Langes Problem, kurze Antwort: Ich habe den Binärmodus für das Lesen des Bildes unter Windows vermisst.

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

hatte

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

1

Eine andere Methode zu verwenden, Bash und Locken sein. Ich habe diese Methode verwendet, als ich mehrere Datei-Uploads testen wollte.

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 
Verwandte Themen