2009-06-06 6 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, я дал мне пустое поле с ошибкой, откуда я не мог отлаживать гораздо больше. Поэтому проблема заключается в том, что Mechanize 0.8.5 имеет зависимость от Hpricot вместо Nokogiri (который работает безупречно).


Следующая идея заключалась в использовании другого драгоценного камня, поэтому я попытался использовать 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 является файлом.


Как загрузить файл в Руби многочастной формы без реализации всего кодирования и данных, совместив себя?

ответ

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 
Смежные вопросы