web-dev-qa-db-fra.com

Comment invoquer HTTP POST sur SSL en rubis?

Voici donc la demande en utilisant curl:

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

J'ai essayé de faire cette même demande en utilisant Ruby, mais je n'arrive pas à le faire fonctionner.

J'ai également essayé quelques bibliothèques, mais je n'arrive pas à le faire fonctionner. Voici ce que j'ai jusqu'à présent:

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)

J'obtiens une erreur de type de support 415 non pris en charge.

35
NielMalhotra

Vous êtes proche, mais pas tout à fait là. Essayez plutôt quelque chose comme ceci:

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)

Cela définira l'en-tête Content-Type ainsi que publier le JSON dans le corps, plutôt que dans les données du formulaire comme votre code l'avait. Avec l'exemple d'informations d'identification, il échoue toujours, mais je pense qu'il devrait fonctionner avec de vraies données.

61
Eugene

Il y a une très bonne explication sur la façon de faire une requête JSON POST avec Net :: HTTP sur ce lien .

Je recommanderais d'utiliser une bibliothèque comme HTTParty . C'est bien documenté, vous pouvez simplement configurer votre classe comme suit:

class RackSpaceClient
  include HTTParty

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

  #methods to do whatever

end

Il semble que la principale différence entre le code Ruby que vous y avez placé et la demande curl) est que la demande curl POSTE JSON (application de type de contenu/json) sur le point de terminaison, tandis que request.set_form_data va envoyer un formulaire dans le corps de la requête POST (application de type de contenu/x-www-form-urlencoded). Vous devez vous assurer que le contenu dans les deux sens est de type application/json.

4
Jason Lewis

Tous les autres sont trop longs voici 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 A besoin de require 'json'


OU si vous voulez

  • PAS vérifiez les hôtes
  • être plus lisible
  • assurez-vous que la connexion est fermée une fois que vous avez terminé

ensuite:

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

Dans le cas où il est difficile de se rappeler quels paramètres vont où:

  • Les options SSL sont par connexion, vous devez donc les spécifier lors de l'ouverture de la connexion.
  • Vous pouvez réutiliser la connexion pour plusieurs REST appels vers la même URL de base. Pensez à la sécurité des threads bien sûr.
  • L'en-tête est un "en-tête de demande" et est donc spécifié par demande. C'est à dire. dans les appels à get/post/patch/....
  • HTTP.start(): crée un nouvel objet Net :: HTTP, puis ouvre en outre la connexion TCP et la session HTTP).
  • HTTP.new(): crée un nouvel objet Net :: HTTP sans ouvrir une connexion TCP ou session HTTP).
3
Kashyap

Un autre exemple:

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