Я сейчас, в качестве хобби, работаю над своим гемом http_wrapper. И на текущий момент реализую фичу загрузки файлов. Я не очень люблю изобретать колеса, особенно если кто-то уже изобрел отличное круглое колесо, поэтому первым делом начал гуглить возможные варианты решения моей задачи. И вот где начинается забавное: я не нашел ни одного варианта, в котором бы предлагалась правильная загрузка файла с помощью Net::HTTP
. Предлагают использовать готовые обертки (типа Rest Client и httparty) или гемы, реализующие именно функционал multipart/form-data
(например, multipart-post), да даже использовать curl
через системный вызов предлагают. Жуть, в общем.
Все это мне не понравилось и я начал копаться в недрах Net::HTTP
. И в итоге откопал большую тайну (судя по тому, что больше я этого нигде на просторах интернета не нашел), которой сейчас с вами поделюсь: как правильно закачать файл с помощью стандартной библиотеки Ruby Net::HTTP
:
require 'net/http'
# готовим uri, куда будем отправлять данные
uri = URI 'http://example.com/upload_form'
# подготавливаем новое соединение
connection = Net::HTTP.new uri.host, uri.port
# создаем объект POST-запроса
request = Net::HTTP::Post.new uri
# формируем данные
form_data = [
['user_avatar', File.read('kartinko.jpg'), {filename: 'picture.jpg'}], # контент файла представлен "строкой"
['user_photo', File.open('photo.jpg')], # контент файла представлен объектом класса File
# другие нужные данные формы идут сюда же в этом же формате:
['submit', 'true'],
['user_name', 'valera']
]
# добавляем данные к запросу
request.set_form form_data, 'multipart/form-data'
# отправляем запрос
response = connection.request request
Профит! :)
Ну наконец-то) Я уж думал не нагуглю никогда). А тут ещё и соотечественник) Спасибо)
Рад, что помог :)
Спасибо вам большое. Уже второй раз сюда попадаю и ваша статья меня выручает.
Спасибо за статью, затупил с форсингом контент-тайпа, но в итоге справился=)
Давайте рассмотрим как правильно установить скаченный установочный файл, который помещен на карте памяти. Есть два основных способа, каждый из которых хорош по своему.
Как получить ответ от сервера, на который был залит файл? Сервер ведь должен сообщить об успешной отправке.
Сейчас это работает чуть иначе:
uri = URI(‘http://example.com’)
request = Net::HTTP::Post.new(uri)
req_params = {
:user_avatar => [File.read(‘avatar.jpg’), {filename: ‘avatar.jpg’}],
:user_name => ‘valera’
}
request.set_form_data(req_params)
result = Net::HTTP.start(uri.hostname, uri.port) do |http|
http.request(request)
end