Выполнение curl через Ruby script

#ruby #curl #ssl-certificate #net-http

#ruby #curl #ssl-сертификат #net-http

Вопрос:

Я пытаюсь выполнить curl через Ruby script, используя два разных метода, и в обоих есть некоторые ошибки.

Первый метод — использование команды оболочки

 #!/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 (u0027su0027 (code 115)): was expecting double-quote to start field namen 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, работает нормально. Есть идеи, как исправить один из этих методов (или оба)?

Комментарии:

1. Сначала я бы переключился с обратных ссылок на Open3 или на форму с несколькими аргументами Kernel#system . Они будут обходить оболочку и разворачивать один уровень кавычек / экранирования. Тогда вы можете делать простые вещи, такие как system('curl', '--cacert', 'RepoCert', ..., '--data-binary', ruby_hash.to_json) и перестать беспокоиться о том, кто интерпретирует кавычки и обратную косую черту.

2. system('curl', ...) это действительно жестокий способ сделать это, вы теряете много контроля. Использование Net::HTTP — это шаг вперед, хотя и немного сложнее. Я бы порекомендовал Faraday , который является одновременно мощным и довольно простым в использовании.

Ответ №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)