[Python-es] problema con urllib2, sólo la primera conexión con el "server" funciona

Jose Caballero jcaballero.hep en gmail.com
Dom Ene 23 17:17:22 CET 2011


Hola Eduard,

He probado el código que recomiendas, pero no funciona.
Un print "hola mundo" (para hacer debug a mano) me dice que nunca se está
llamando al método https_open(), y por tanto nunca estoy mandando la
información del certificado PEM para autenticarme (creo).
Parece que me está faltando algo.

Por cierto, el error que devuelve el server es un error implementado
específico para la aplicación, no es un mensaje de error estándard que tenga
significado para el común de los mortales.
En concreto es SC=60.
Pero, como digo, significa que en los parámetros de la conexión no hay info
de autenticación.

Muchas gracias de todas formas por tu respuesta.
Sigo googleando...
Saludos cordiales,
Jose




El 23 de enero de 2011 07:50, Eduard Diaz <eventgrafic en gmail.com> escribió:

> Hola jose,
>
> Seria interesante que enviaras el mensaje de error para tener mas
> informacion
>
> A veces es muy util activar el modo debuglevel en el opener:
>
>
> opener = urllib2.build_opener(
>     HTTPSClientAuthHandler('/tmp/pem_certificate', '/tmp/pem_certificate'),
>     urllib2.HTTPHandler(debuglevel=1)
>     )
>
> según la documentación, urllib2.urlopen envia conexiones HTTP/1.1 con
> Connection:close en el header
> http://docs.python.org/library/urllib2.html#urllib2.urlopen
>
> Por lo que creo que el problema está en que cada llamada a connect se abre
> una nueva sesion y por eso en la segunda conexión no estas autenticado.
>
> En estos casos normalmente no utilizo urlopen sino que como ya tienes el
> opener, utilizo request= urllib2.Request para crear el request, esto permite
> personalizar los headers mediante request.add_header y añadir los datos
> mediante request.add_data.
>
> Una vez que el request tiene toda la información necesaria, haces la
> llamada mediante  opener.open(request).read().
>
> Esto se ha de repetir para cada consulta
>
> Ejemplo:
>
>
> opener = urllib2.build_opener(
>     HTTPSClientAuthHandler('/tmp/pem_certificate', '/tmp/pem_certificate'),
>     urllib2.HTTPHandler(debuglevel=1)
>     )
>
> # primera conexion
> req = urllib2.Request(url)
> # ... añadir el data ...
> req.add_data(data1)
> print opener.open(req).read()
>
> # segunda conexion
> req = urllib2.Request(url)
> # ... añadir el data ...
> req.add_data(data2)
> print opener.open(req).read()
>
> Todo esto seria interesante implementarlo en una clase Client que conserve
> la sesión y que permita hacer las llamadas necesarias según se requiera
>
> Por cierto, si te ha sido útil y encuentras la solución, te agradecería que
> lo publicaras en el hilo, para mi es interesante las comunicaciones entre
> servicios web y intercambiar las experiencias nos permite a todos
> profundizar en el tema
>
> Un saludo
>
> El 21 de enero de 2011 21:18, Jose Caballero <jcaballero.hep en gmail.com>escribió:
>
>> Hola,
>>
>> necesito enviar ciertos datos a un servidor mediante el método POST, y
>> analizar la respuesta que el servidor me devuelve.
>> Este proceso se realiza varias veces, pasando distinta información en cada
>> comunicación.
>>
>> La comunicación se debe autenticar mediante un certificado PEM.
>>
>> Lo estoy intentando con urllib/urllib2, con un código más o menos como el
>> siguiente (parte copiado de un blog que encontré en google):
>>
>>
>> ------------------------------------------------------------------------------------------------------------------------------
>>
>> import urllib
>> import urllib2
>> import httplib
>>
>>
>> def connect(url, data):
>>
>>         class HTTPSClientAuthHandler(urllib2.HTTPSHandler):
>>             def __init__(self, key, cert):
>>                 urllib2.HTTPSHandler.__init__(self)
>>                 self.key = key
>>                 self.cert = cert
>>
>>             def https_open(self, req):
>>                 # Rather than pass in a reference to a connection class,
>> we pass in
>>                 # a reference to a function which, for all intents and
>> purposes,
>>                 # will behave as a constructor
>>                 return self.do_open(self.getConnection, req)
>>
>>             def getConnection(self, host, timeout=300):
>>                 return httplib.HTTPSConnection(host, key_file=self.key,
>> cert_file=self.cert)
>>
>>         opener =
>> urllib2.build_opener(HTTPSClientAuthHandler('/tmp/pem_certificate',
>> '/tmp/pem_certificate') )
>>         urllib2.install_opener(opener)
>>         urlhandler =  urllib2.urlopen(url, urllib.urlencode(data))
>>         ret = urlhandler.read()
>>
>>         return ret
>>
>>
>> ret1 = connect(url, data1)
>> print ret1
>>
>> ret2 = connect(url, data2)
>> print ret2
>>
>> ret3 = connect(url, data3)
>> print ret3
>>
>>
>> ------------------------------------------------------------------------------------------------------------------------------
>>
>> Mi problema es que sólo la primera conexión funciona.
>> Para la segunda y la tercera el servidor me devuelve un mensaje de error.
>> Este mensaje, algo críptico, viene a decir que estoy estableciendo una
>> comunicación sin autenticar.
>> Sin embargo, el fichero PEM sigue ahí, uso el mismo para las tres
>> conexiones.
>> ¿Por qué funciona la primera vez y no las demás?
>> Nota: no tengo acceso a los logs del servidor. Sólo sé lo que me devuelve
>> como mensaje de error.
>>
>> Lo único que se me ocurre es algún problema de conexiones abiertas que
>> deberían haber sido cerradas o algo similar.
>>
>> Si alguien me puede dar alguna pista estaré eternamente agradecido.
>>
>>
>> Muchas gracias por adelantando.
>> Jose
>>
>>
>>
>>
>>
>>
>>
>> _______________________________________________
>> Python-es mailing list
>> Python-es en python.org
>> http://mail.python.org/mailman/listinfo/python-es
>> FAQ: http://python-es-faq.wikidot.com/
>>
>>
>
>
> --
> //////////////////////////////////////////////////////////////////////////
> Eduard Díaz
> www.scopia.es
> SCOPIA VISUAL INTERFACES SYSTEMS S.L.
> Barcelona
> Tel. 625 055 126, 933 171 771
> //////////////////////////////////////////////////////////////////////////
>
> _______________________________________________
> Python-es mailing list
> Python-es en python.org
> http://mail.python.org/mailman/listinfo/python-es
> FAQ: http://python-es-faq.wikidot.com/
>
>
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://mail.python.org/pipermail/python-es/attachments/20110123/5b6325c2/attachment.html>


Más información sobre la lista de distribución Python-es