Come invocare il metodo POST HTTP su SSL in ruby?

Quindi, ecco la richiesta utilizzando curl:

curl -XPOST -H content-type:application/json -d "{\"credentials\":{\"username\":\"username\",\"key\":\"key\"}}" https://auth.api.rackspacecloud.com/v1.1/auth 

Ho cercato di fare questa stessa richiesta usando Ruby, ma non riesco a farlo funzionare.

Ho provato anche un paio di librerie, ma non riesco a farlo funzionare. Ecco cosa ho finora:

 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) 

Ricevo un errore di tipo di supporto 415 non supportato.

Sei vicino, ma non proprio lì. Prova invece qualcosa del genere:

 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) 

Questo imposterà l’intestazione Content-Type e pubblicherà il JSON nel corpo, piuttosto che nei dati del modulo come lo aveva il codice. Con le credenziali di esempio, non riesce ancora, ma ho il sospetto che dovrebbe funzionare con dati reali.

C’è una spiegazione molto buona di come fare una richiesta POST JSON con Net :: HTTP a questo link .

Consiglierei l’uso di una libreria come HTTParty . È ben documentato, puoi semplicemente impostare la tua class in questo modo:

 class RackSpaceClient include HTTParty base_uri "https://auth.api.rackspacecloud.com/" format :json headers 'Accept' => 'application/json' #methods to do whatever end 

Sembra che la differenza principale tra il codice Ruby che hai inserito e la richiesta di arricciatura sia che la richiesta di arricciamento è POSTing JSON (content-type application / json) all’endpoint, mentre request.set_form_data sta per inviare un form in il corpo della richiesta POST (content-type application / x-www-form-urlencoded). Devi assicurarti che il contenuto che va in entrambe le direzioni sia di tipo application / json.

Tutti gli altri sono troppo lunghi qui c’è un 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 needs require 'json'


O se vuoi

  • NON verificare gli host
  • essere più leggibile
  • assicurati che la connessione sia chiusa una volta terminato

poi:

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

Nel caso sia difficile ricordare quali parametri andare dove:

  • Le opzioni SSL sono per connessione in modo da specificarle durante l’apertura della connessione.
  • È ansible riutilizzare la connessione per più chiamate REST allo stesso URL base. Pensa alla sicurezza del filo, ovviamente.
  • L’intestazione è una “intestazione di richiesta” e quindi specificata per richiesta. Cioè nelle chiamate per get / post / patch / ...
  • HTTP.start() : crea un nuovo object Net :: HTTP, quindi apre in aggiunta la connessione TCP e la sessione HTTP.
  • HTTP.new() : crea un nuovo object Net :: HTTP senza aprire una connessione TCP o una sessione HTTP.

Un altro esempio:

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