2012-06-06 42 views
32

因此,這裏的請求,使用curl:如何在ruby中通過SSL調用HTTP POST方法?

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不支持的媒體類型的錯誤。

回答

58

你很接近,但並不完全在那裏。嘗試這樣的事情,而不是:

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在身上,而不是形式的數據作爲你的代碼有它。憑藉示例憑據,它仍然失敗,但我懷疑它應該與那裏的真實數據一起工作。

+0

這工作完美。謝謝! – NielMalhotra

+0

CAn你幫我解決這個問題:http://stackoverflow.com/questions/20771177/post-request-not-working-rest?noredirect=1#comment31132280_20771177 –

+4

我建議編輯'.to_json'在結尾'request.body'行來避免編碼錯誤。儘管謝謝你的偉大答案! –

4

對於如何使用Net :: HTTP at this link進行JSON POST請求有一個非常好的解釋。

我會推薦使用類似HTTParty的圖書館。這充分證明,你可以設置你的類像這樣:

class RackSpaceClient 
    include HTTParty 

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

    #methods to do whatever 

end 

看起來你放在那裏的Ruby代碼,以及捲曲的要求之間的主要區別是,捲曲的請求正在發佈JSON( content-type application/json)發送到端點,而request.set_form_data將在POST請求(content-type application/x-www-form-urlencoded)主體中發送一個表單。你必須確保兩種方式的內容都是application/json類型。

2

又如:

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

2

所有其他太長這裏是一個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'


或者如果你想

  • 驗證主機
  • 更具可讀性
  • 確保連接被關閉一旦你完成

則:

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'} 
    ) 
} 

在情況下,它很難記住PARAMS去的地方:

  • SSL選項是每個連接,所以你指定它們打開連接。
  • 您可以將多個REST調用的連接重用到相同的基本URL。當然想到線程安全。
  • 標題是一個「請求標題」,因此每個請求指定。即致電get/post/patch/...
  • HTTP.start():創建一個新的Net :: HTTP對象,然後另外打開TCP連接和HTTP會話。
  • HTTP.new():在不打開TCP連接或HTTP會話的情況下創建新的Net :: HTTP對象。
相關問題