【问题标题】:Executing curl through Ruby script通过 Ruby 脚本执行 curl
【发布时间】:2021-02-17 11:43:17
【问题描述】:

我正在尝试使用两种不同的方法通过 Ruby 脚本执行 curl,但两者都有一些错误。

第一种方法是使用shell命令

#!/usr/bin/ruby

`curl --cacert RepoCert --location --request POST 'https://test-service/rest/services/request/' --header 'Authorization: Basic amkkdksmmkk3XCf45DffSa23Ert' --header 'Content-Type: application/json' --data-binary "{ \"serviceID\": \"3\", \"TypeId\": \"52\", \"requestFieldValues\": { \"summary\": \"summary\", \"description\": \"something\", \"prority\": { \"id\": \"1\"}, \"customfield\": \"5\" }} "`

我有一个错误

"Unexpected character (\u0027s\u0027 (code 115)): was expecting double-quote to start field name\n at [Source: com.itlab.jira.plugins.extender.helper.RequestWrapper$5db70c75; line:1, column:5]"

还尝试使用 Ruby Net::HTTP(从https://jhawthorn.github.io/curl-to-ruby/ 生成的代码)

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

uri = URI.parse("https://test-service/rest/services/request/")
request = Net::HTTP::Post.new(uri)
request.content_type = "application/json"
request["Authorization"] = "Basic amkkdksmmkk3XCf45DffSa23Ert"
request.body = JSON.dump({
  "serviceID" => "3",
  "TypeId" => "52",
  "requestFieldValues" => {
    "summary" => "summary",
    "description" => "something",
    "prority" => {
      "id" => "1"
    },
    "customfield" => "5"
  }
})

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end

我明白了

/usr/share/ruby/net/http.rb:921:in `connect': SSL_connect returned=1 errno=0 state=error: certificate verify failed (OpenSSL::SSL::SSLError)

问题是在这种情况下我必须使用证书授权,所以我不能忽略它。

Curl 执行表单命令行工作正常。知道如何修复其中一种方法(或两种方法)吗?

【问题讨论】:

  • 首先我会从反引号切换到Open3Kernel#system 的多参数形式。那些将绕过外壳并打开一层引用/转义。然后你可以像system('curl', '--cacert', 'RepoCert', ..., '--data-binary', ruby_hash.to_json) 这样简单的事情,不用担心谁在解释哪些引号和反斜杠。
  • system('curl', ...) 是一种非常残酷的做法,您会失去很多控制权。使用 Net::HTTP 是一个进步,如果有点棘手的话。我推荐Faraday,它既强大又易于使用。

标签: ruby curl ssl-certificate net-http


【解决方案1】:

感谢大家的帮助,但我使用 Net::HTTP 解决了这个问题。如果有人寻找过类似案例,我会在此处发表评论。

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

uri = URI.parse("https://test-service/rest/services/request/")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
http.ca_file = "/directory/to/cert/file"

request = Net::HTTP::Post.new(uri.request_uri)

request.content_type = "application/json"
request["Authorization"] = "Basic amkkdksmmkk3XCf45DffSa23Ert"
request.body = JSON.dump({
  "serviceID" => "3",
  "TypeId" => "52",
  "requestFieldValues" => {
    "summary" => "summary",
    "description" => "something",
    "prority" => {
      "id" => "1"
    },
    "customfield" => "5"
  }
})


response = http.request(request)

【讨论】:

    猜你喜欢
    • 2018-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-21
    • 1970-01-01
    • 1970-01-01
    • 2017-07-04
    • 2014-01-20
    相关资源
    最近更新 更多