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

Eduard Diaz eventgrafic en gmail.com
Dom Ene 23 13:50:38 CET 2011


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
//////////////////////////////////////////////////////////////////////////
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://mail.python.org/pipermail/python-es/attachments/20110123/76b96dd7/attachment.html>


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