Twitter GitHub

Никто не знает как правильно закачать файл с помощью Ruby Net::HTTP

Я сейчас, в качестве хобби, работаю над своим гемом 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

Профит! :)

Комментарии (7)

  • Ну наконец-то) Я уж думал не нагуглю никогда). А тут ещё и соотечественник) Спасибо)

  • R says

    Спасибо вам большое. Уже второй раз сюда попадаю и ваша статья меня выручает.

  • Дима says

    Спасибо за статью, затупил с форсингом контент-тайпа, но в итоге справился=)

  • Давайте рассмотрим как правильно установить скаченный установочный файл, который помещен на карте памяти. Есть два основных способа, каждый из которых хорош по своему.

  • Амир says

    Как получить ответ от сервера, на который был залит файл? Сервер ведь должен сообщить об успешной отправке.

  • Gendalph says

    Сейчас это работает чуть иначе:
    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