2012-06-06 9 views
32

Así que aquí está la solicitud utilizando rizo:¿Cómo invocar el método HTTP POST sobre SSL en ruby?

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

que he estado tratando de hacer esta misma solicitud utilizando rubí, pero me parece que no puede conseguir que funcione.

Probé algunas bibliotecas también, pero no puedo hacer que funcione. Esto es lo que tengo hasta ahora:

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) 

me sale un error de tipo de medio no soportado 415.

Respuesta

58

Estás cerca, pero no exactamente allí. Pruebe algo como esto en su lugar:

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) 

Esto establecerá la cabecera Content-Type, así como publicar el JSON en el cuerpo, en lugar de en los datos del formulario por ejemplo el código tenía. Con las credenciales de muestra, todavía falla, pero sospecho que debería funcionar con datos reales allí.

+0

Esto funcionó a la perfección. ¡Gracias! – NielMalhotra

+0

Puede ayudarme con esta pregunta: http://stackoverflow.com/questions/20771177/post-request-not-workingrest?noredirect=1#comment31132280_20771177 –

+4

Sugerí una edición para '.to_json' al final de la línea 'request.body' para evitar errores de codificación. ¡Gracias por la gran respuesta! –

4

Hay una muy buena explicación de cómo hacer una solicitud JSON POST con Net :: HTTP at this link.

Yo recomendaría usar una biblioteca como HTTParty. Es bien documentado, sólo puede configurar su clase, así:

class RackSpaceClient 
    include HTTParty 

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

    #methods to do whatever 

end 

Parece que la principal diferencia entre el código Ruby ha colocado allí, y la solicitud de rizo, es que la petición rizo es la publicación de JSON (tipo de contenido application/json) al punto final, mientras que request.set_form_data va a enviar un formulario en el cuerpo de la solicitud POST (tipo de contenido application/x-www-form-urlencoded). Debe asegurarse de que el contenido en ambos sentidos sea del tipo application/json.

2

Otro ejemplo:

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

2

Todos los demás son demasiado tiempo aquí es una un trazador de líneas:

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 necesidades require 'json'


O si quieres

  • NO verificar los anfitriones
  • ser más legible
  • asegurar la conexión se cierra una vez que haya terminado

a continuación:

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

En caso de que sea difícil recordar lo que ir a donde params:

  • opciones SSL son por conexión por lo que los especifica al abrir la conexión.
  • Puede reutilizar la conexión para múltiples llamadas REST a la misma URL base. Piense en seguridad hilo, por supuesto.
  • Encabezado es un "encabezado de solicitud" y, por lo tanto, se especifica por solicitud. Es decir. en llamadas a get/post/patch/....
  • HTTP.start(): Crea un nuevo objeto Net :: HTTP y luego abre la conexión TCP y la sesión HTTP.
  • HTTP.new(): Crea un nuevo objeto Net :: HTTP sin abrir una conexión TCP o una sesión HTTP.