36

所以这是使用 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 不支持的媒体类型错误。

4

4 回答 4

63

你很近,但不完全在那里。尝试这样的事情:

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 发布到正文中,而不是像您的代码那样在表单数据中发布。使用示例凭据,它仍然失败,但我怀疑它应该与那里的真实数据一起工作。

于 2012-06-06T19:03:27.870 回答
4

在此链接上有一个很好的解释如何使用 Net::HTTP 发出 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 代码和 curl 请求之间的主要区别在于 curl 请求将 JSON(内容类型应用程序/json)发布到端点,而request.set_form_data将在主体中发送一个表单POST 请求(内容类型应用程序/x-www-form-urlencoded)。您必须确保双向传输的内容是 application/json 类型。

于 2012-06-06T17:54:42.810 回答
3

所有其他人都太长了,这里是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'}
    )
}

如果很难记住参数在哪里:

  • SSL 选项是每个连接的,因此您在打开连接时指定它们。
  • 您可以将连接重复用于对同一基本 url 的多个 REST 调用。当然要考虑线程安全。
  • 标头是“请求标头”,因此按请求指定。即在调用get/ post/ patch/ ...
  • HTTP.start(): 创建一个新的 Net::HTTP 对象,然后另外打开 TCP 连接和 HTTP 会话。
  • HTTP.new(): 创建一个新的 Net::HTTP 对象而不打开 TCP 连接或 HTTP 会话。
于 2016-02-02T18:03:10.837 回答
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
于 2015-08-25T18:35:32.783 回答