Я просто хочу загрузить изображение на сервер с помощью POST. Как бы просто ни звучала эта задача, в 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
Это приводит к тому, что файл на сервере полностью готов к мусору и выглядит зашифрованным повсюду:
альтернативный текст http://imagehub.org/f/1tk8/garbage.png
Моим следующим шагом было понижение WWW :: Mechanize до версии 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-класс Станислава Витвицкого . Пока этот класс выглядел хорошо, но он не делает то, что мне нужно, потому что я не хочу публиковать только файлов, я также хочу публиковать нормальные данные, а это невозможно с его классом.
Моя последняя попытка была использовать 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 в многокомпонентную форму, не используя всю кодировку и выравнивание данных?