Enviar un XML con Net::HTTP::Post


#1

Estoy tratando de enviar un XML con este código:

xml = … (el xml a enviar)
destino = … (URL destino)

url = URI.parse(destino)
req = Net::HTTP::Post.new(url.path)
req.content_type = ‘text/xml’
req.form_data = xml
res = Net::HTTP.new(url.host, url.port).start {|http| http.request(req)
}

Este es el XML:

<?xml version="1.0" encoding="UTF-8"?> part001 DA4B 5598

Pero esto es lo que reciben en destino:
50%3c%3fxml%20version%3d%221.0%22%20encoding%3d%22UTF-8%22%3f%3e%0a=&%3ctoken%3e%0a=&%20%20%3crequest%20type%3d%22validation%22%3e%0a=&%20%20%20%20%3cuser%3epart001%3c%2fuser%3e%0a=&%20%20%20%20%3cpass%3eDA4B%3c%2fpass%3e%0a=&%20%20%20%20%3cuserId%3e5598%3c%2fuserId%3e%0a=&%20%20%3c%2frequest%3e%0a=&%3c%2ftoken%3e%0a=

Parece que está llegando codificado y no en texto plano, se están
escapando los carácteres; no tiene pinta de ser un problema de encoding
(yo uso UTF-8, y se supone que el destino tb), porque no son Ñ's ni
vocales acentuadas los causantes del problema, sino carácteres normales.

No sé si el método de envio que uso, con Net::HTTP::Post, tiene que por
defecto se codifiquen… ¿Sabéis si Net::HTTP::Post tiene alguna
propiedad para que esto no ocurra?

Otra posibilidad es que sea alguna jugarreta del IIS del destino, pero
aquí ya no sé ni cómo comprobarlo…

Any help welcome!!


#2

2009/5/6 Fernando C. removed_email_address@domain.invalid:

}
¿Utilizas form_data por alguna razón en concreto?

form_data se utiliza para enviar formularios (por eso te está llegando
en formato urlencoded), creo que el XML debería ir en el body de la
petición: req.body = xml.


#3

David A. wrote:

2009/5/6 Fernando C. removed_email_address@domain.invalid:

}
�Utilizas form_data por alguna raz�n en concreto?

form_data se utiliza para enviar formularios (por eso te est� llegando
en formato urlencoded), creo que el XML deber�a ir en el body de la
petici�n: req.body = xml.

Pues eso era!! Muchísimas gracias!!

Y es que hay que ver lo mal documentado que está esto:
http://www.ruby-doc.org/stdlib/libdoc/net/http/rdoc/classes/Net/HTTP/Post.html

Mucho mejor documentado están los GET y los POST de FORM:
http://www.ruby-doc.org/stdlib/libdoc/net/http/rdoc/classes/Net/HTTP.html

pero el Net::HTTP::Post, parece que sea el patito feo de la
documentación… incluídos blogs y foros.

s2


#4

Así me ha funcionado:

require ‘rest_client’
require ‘net/http’
require ‘uri’

def enviar_xml(xml)
url = URI.parse(“http://www.destino.com”)
req = Net::HTTP::Post.new(url.path)
req.content_type = ‘text/xml’
req.basic_auth @username, @password
req.body = xml
http_resp = Net::HTTP.new(url.host, url.port).start {|http|
http.request(req) }

# Procesar respuesta Net:OK
case http_resp
when Net::HTTPSuccess, Net::HTTPRedirection
  respuesta = Hash.from_xml(http_resp.body)['token']['response']
  return respuesta

# Procesar respuesta Net:ERROR
else
  fallo_conexion(@res) # Una rutina mía
  return false
end

end

No veo ninguna diferencia con lo tuyo, no sé qué problema puedes
tener… salvo que estés en un caso de bloqueo de procesos, como me pasó
a mí:
http://www.ruby-forum.com/topic/185456#811733

Por si acaso es eso, lanza un mongrel_rails start -p 4000, y prueba a
ejecutar desde el 4000 el envío al 3000 o viceversa, a ver…

s2


#5

tuve que cambiar un poco las cosas para poder enviar un hash, pego aquí
mi
solución final por si a alguien la necesita, seguro que hay una forma
más
fácil, pero por ahora quedará asi jeje

module HashToHttpParams
def to_http_params
map do |k, v|
if v.is_a?(Hash)
v.map do |kk, vv|
“#{k}[#{kk}]=#{vv}”
end.join(’&’)
else
“#{k}=#{v}”
end
end.join(’&’)
end
end

Hash.send(:include, HashToHttpParams)

parameters = { :page => {“page_text”=>“

test

”,
“page_title”=>“test”,
“browser_title”=>“test”} }

url = URI.parse(‘http://localhost:3000/admin/pages/create’)

req = Net::HTTP::Post.new(url.path)
req.basic_auth @username, @password

res = Net::HTTP.new(url.host, url.port).start {|http| http.request(req,
parameters.to_http_params) }

la solución la adapte de este post:
http://porras.lacoctelera.net/post/2007/10/08/enviando-formularios-con-parametros-compuestos-con-ruby-y-net#c4300080

Saludos.

On Fri, Jun 26, 2009 at 2:02 PM, Fernando C. <


#6

2009/5/6 Fernando C. removed_email_address@domain.invalid

s2
Podrías postear la solución final? tengo el mismo requerimiento y no
logro
hacerlo andar, este es mi código:

  parameters = {"page_text"=>"<p>test</p>", "page_title"=>"test",

“browser_title”=>“test”}

  url = URI.parse('http://localhost:3000/admin/pages/create')

  req = Net::HTTP::Post.new(url.path)
  req.basic_auth @username, @password
  req.body = parameters

  res = Net::HTTP.new(url.host, url.port).start {|http|

http.request(req) }

  case res
  when Net::HTTPSuccess, Net::HTTPRedirection
    # OK
  else
    res.error!
  end

en realidad creo me alcanzaría con poder enviar un hash ya que del lado
del
servidor siempre veo el parámetro como un string.

Saludos y gracias.