Подтвердить что ты не робот

Как вызвать метод HTTP POST через SSL в рубине?

Итак, здесь запрос с использованием curl:

curl -XPOST -H content-type:application/json -d "{\"credentials\":{\"username\":\"username\",\"key\":\"key\"}}" https://auth.api.rackspacecloud.com/v1.1/auth

Я пытаюсь сделать этот же запрос с помощью ruby, но я не могу заставить его работать.

Я тоже попробовал несколько библиотек, но я не могу заставить его работать. Вот что я до сих пор:

uri = URI.parse("https://auth.api.rackspacecloud.com")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Post.new("/v1.1/auth")
request.set_form_data({'credentials' => {'username' => 'username', 'key' => 'key'}})
response = http.request(request)

Я получаю 415 неподдерживаемую ошибку типа носителя.

4b9b3361

Ответ 1

Вы близко, но не совсем там. Попробуйте что-то вроде этого:

uri = URI.parse("https://auth.api.rackspacecloud.com")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Post.new("/v1.1/auth")
request.add_field('Content-Type', 'application/json')
request.body = {'credentials' => {'username' => 'username', 'key' => 'key'}}.to_json
response = http.request(request)

Это установит заголовок Content-Type, а также опубликует JSON в теле, а не в данных формы, как это было в вашем коде. С примерами учетных данных, это все еще терпит неудачу, но я подозреваю, что это должно работать с реальными данными там.

Ответ 2

Там очень хорошее объяснение того, как сделать запрос JSON POST с Net:: HTTP по этой ссылке.

Я бы рекомендовал использовать библиотеку, например HTTParty. Он хорошо документирован, вы можете просто настроить свой класс следующим образом:

class RackSpaceClient
  include HTTParty

  base_uri "https://auth.api.rackspacecloud.com/"
  format :json
  headers 'Accept' => 'application/json'

  #methods to do whatever

end

Похоже, что основное различие между указанным здесь кодом Ruby и запросом на завивки заключается в том, что запрос curl представляет собой POSTing JSON (application-type application/json) для конечной точки, тогда как request.set_form_data собирается отправить форма в теле запроса POST (приложение типа контента /x -www-form-urlencoded). Вы должны убедиться, что контент, идущий в обоих направлениях, имеет тип application/json.

Ответ 3

Другой пример:

#!/usr/bin/ruby

require 'net/http'
require 'json'
require 'uri'

full_url = "http://" + options[:artifactory_url] + "/" + "api/build/promote/" + options[:build]

puts "Artifactory url: #{full_url}"

data = {
    status: "staged",
    comment: "Tested on all target platforms.",
    ciUser: "builder",
    #timestamp: "ISO8601",
    dryRun: false,
    targetRepo: "#{options[:target]}",
    copy: true,
    artifacts: true,
    dependencies: false,
    failFast: true,
}

uri = URI.parse(full_url)
headers = {'Content-Type' => "application/json", 'Accept-Encoding'=> "gzip,deflate",'Accept' => "application/json" }
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new(uri.request_uri, headers)
request.basic_auth(options[:user], options[:password])
request.body = data.to_json
response = http.request(request)

puts response.code
puts response.body

Ответ 4

Все остальные слишком длинны здесь ОДИН ЛИНИЯ:

Net::HTTP.start('auth.api.rackspacecloud.com', :use_ssl => true).post(
      '/v1.1/auth', {:credentials => {:username => "username",:key => "key"}}.to_json,
      initheader={'Content-Type' => 'application/json'}
    )

* to_json требуется require 'json'


ИЛИ если вы хотите

  • НЕ проверить хосты
  • более читабельны
  • убедитесь, что соединение закрыто, как только вы закончите.

то

ssl_opts={:use_ssl => true, :verify_mode => OpenSSL::SSL::VERIFY_NONE}
Net::HTTP.start('auth.api.rackspacecloud.com', ssl_opts) { |secure_connection|
  secure_connection.post(
      '/v1.1/auth', {:credentials => {:username => "username",:key => "key"}}.to_json,
      initheader={'Content-Type' => 'application/json'}
    )
}

Если вам сложно запомнить, какие параметры идут туда, где:

  • Параметры SSL для каждого соединения, поэтому вы указываете их при открытии соединения.
  • Вы можете повторно использовать соединение для нескольких вызовов REST на одном базовом URL-адресе. Подумайте о безопасности потоков, конечно.
  • Заголовок - это "заголовок запроса" и, следовательно, указан для каждого запроса. То есть при вызовах get/post/patch/....
  • HTTP.start(): Создает новый объект Net:: HTTP, затем дополнительно открывает соединение TCP и HTTP-сеанс.
  • HTTP.new(): Создает новый объект Net:: HTTP без открытия TCP-соединения или сеанса HTTP.