web-dev-qa-db-ja.com

rubyでSSL経由でHTTP POSTメソッドを呼び出す方法は?

したがって、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サポートされていないメディアタイプエラーが表示されます。

35
NielMalhotra

あなたは近くにいますが、そこには全くありません。代わりに次のようなものを試してください。

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'}}
response = http.request(request)

これにより、Content-Typeヘッダーが設定されるだけでなく、コードに含まれているフォームデータではなく、本文にJSONがポストされます。サンプル認証情報では、まだ失敗しますが、実際のデータで動作するはずです。

61
Eugene

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リクエストの主な違いは、curlリクエストがJSON(content-type application/json)をエンドポイントにPOSTしているのに対し、request.set_form_dataは、POSTリクエスト(content-type application/x-www-form-urlencoded)の本文でフォームを送信します。両方の方法でコンテンツを確認する必要がありますタイプapplication/jsonの。

4
Jason Lewis

他のすべては長すぎますONE LINER

_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'_が必要


またはあなたがしたい場合

  • [〜#〜] not [〜#〜]ホストを検証する
  • より読みやすく
  • 完了したら、接続が閉じられていることを確認してください

その後:

_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オプションは接続ごとにあるため、接続を開くときに指定します。
  • 同じベースURLへの複数のREST呼び出しに対して接続を再利用できます。もちろんスレッドセーフについて考えてください。
  • ヘッダーは「リクエストヘッダー」であるため、リクエストごとに指定されます。つまりget/post/patch/_..._への呼び出しで。
  • HTTP.start():新しいNet :: HTTPオブジェクトを作成し、さらにTCP接続およびHTTPセッションを開きます。
  • HTTP.new():TCP接続またはHTTPセッションを開かずに新しいNet :: HTTPオブジェクトを作成します。
3
Kashyap

もう一つの例:

#!/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
3
Noamsh