urllib: problème de gestion des erreurs d'une authentification basic

Document Actions
Réponses: 2   Visites: 0
Up one level
Vous devez être un membre enregistré pour contribuer sur ce forum. Inscrivez-vous maintenant

urllib: problème de gestion des erreurs d'une authentification basic

Posté par LeYantibus le 26/06/2010 21:42
Bonjour,

Je suis novice, et j'ai un souci avec la gestion des erreurs lorsque j'essai d'accèder à une page protégée par mot de passe avec la fonction 'urlopen'.

Je m'explique, prenons un exemple simple.

Admettons, par exemple, que nous possédions un routeur sur notre réseau local dont l'accès est protégé par un identifiant et un mot de passe (type htaccess) avec pour IP LAN '192.168.1.1', identifiant 'admin' et mot de passe 'admin'. Et que l'on veuille accéder à ses pages de configurations; on prossédera, normalement, ainsi :

code:
# identifiant, mdp et url pour accèder au routeur (non-erronés)
uri = 'http://192.168.1.1/'
user = 'admin'
passwd = 'admin'

from urllib import request  # anciennement 'urllib2'

# création du password manager
pm = request.HTTPPasswordMgrWithDefaultRealm()
pm.add_password(None, uri, user, passwd)

# création du handler d'authentification et installation de l'opener
request.install_opener(
request.build_opener(
request.HTTPBasicAuthHandler(pm)))

# récupération de la page principal du routeur
page_data = request.urlopen(uri).read()

# et on peut l'afficher
print(page_data.decode('encodage_de_la_page'))


Si les informations (indentifiant, mot de passe et ip) sont corrects, tout ce passera bien.

Le problème vient quand le mdp ou l'identifiant est erroné...
On aurait pu croire qu'une exception HTTPError soit déclenchée avec l'attribut 'code' valant 401... (cela aurai été trop simple) Mais non!
A la place on se tape une liste énorme d'erreur fini par l'exception RuntimeError !!

Alors j'ai bien tenté de lire les script request.py et client.py pour comprendre... Mais malheureusement, je ne suis pas encore parvenu à les digérer.

Si quelqu'un peut m'aider à comprendre pourquoi l'exception déclanchée n'a rien avoir avec une erreur HTTP 401 ça me serai très utile !

Merci d'avance.

Re: urllib: problème de gestion des erreurs d'une authentification basic

Posté par merwok le 25/08/2010 05:14
Sans version ni traceback, c’est difficile :)

Re: urllib: problème de gestion des erreurs d'une authentification basic

Posté par LeYantibus le 01/10/2010 12:17
Re,

Désolé pour mon retour tardif.

Ma question n'a toujours pas de réponse... J'ai bien ma petite idée sur le problème que j'ai évoqué; je pense qu'il faut installer l'opener après avoir vérifié les identifiants. Mais je trouve dommage qu'en installant un opener on ne puisse plus gérer les erreurs http... Imaginons que le mot de passe du site ou du routeur change pendant que l'on navigue dedans; on va se prendre une RuntimeError sans savoir de quoi il s'agit. :(

Sinon, voici le traceback (Python 3.1.2, Win32)

Ca commence par ça :
code:
Traceback (most recent call last):
  File "C:/Etudes/test.py", line 18, in <module>
    page_data = request.urlopen(uri).read()
  File "C:\Python31\lib\urllib\request.py", line 121, in urlopen
    return _opener.open(url, data, timeout)


Ensuite, ça boucle une bonne vingtaine de fois (j'ai pas compter non plus :p ) sur ça :
code:
  File "C:\Python31\lib\urllib\request.py", line 355, in open
    response = meth(req, response)
  File "C:\Python31\lib\urllib\request.py", line 467, in http_response
    'http', request, response, code, msg, hdrs)
  File "C:\Python31\lib\urllib\request.py", line 387, in error
    result = self._call_chain(*args)
  File "C:\Python31\lib\urllib\request.py", line 327, in _call_chain
    result = func(*args)
  File "C:\Python31\lib\urllib\request.py", line 811, in http_error_401
    url, req, headers)
  File "C:\Python31\lib\urllib\request.py", line 789, in http_error_auth_reqed
    return self.retry_http_basic_auth(host, req, realm)
  File "C:\Python31\lib\urllib\request.py", line 799, in retry_http_basic_auth
    return self.parent.open(req, timeout=req.timeout)


Pour enfin finir avec ça :
code:
  File "C:\Python31\lib\urllib\request.py", line 349, in open
    response = self._open(req, data)
  File "C:\Python31\lib\urllib\request.py", line 367, in _open
    '_open', req)
  File "C:\Python31\lib\urllib\request.py", line 327, in _call_chain
    result = func(*args)
  File "C:\Python31\lib\urllib\request.py", line 1090, in http_open
    return self.do_open(http.client.HTTPConnection, req)
  File "C:\Python31\lib\urllib\request.py", line 1072, in do_open
    h.request(req.get_method(), req.selector, req.data, headers)
  File "C:\Python31\lib\http\client.py", line 932, in request
    self._send_request(method, url, body, headers)
  File "C:\Python31\lib\http\client.py", line 970, in _send_request
    self.endheaders(body)
  File "C:\Python31\lib\http\client.py", line 928, in endheaders
    self._send_output(message_body)
  File "C:\Python31\lib\http\client.py", line 782, in _send_output
    self.send(msg)
  File "C:\Python31\lib\http\client.py", line 723, in send
    self.connect()
  File "C:\Python31\lib\http\client.py", line 705, in connect
    self.timeout)
  File "C:\Python31\lib\socket.py", line 292, in create_connection
    for res in getaddrinfo(host, port, 0, SOCK_STREAM):
RuntimeError: maximum recursion depth exceeded while calling a Python object


En attente d'une explication un peu plus technique que ma simple constatation, je précise aussi que je ne connais pas très bien le protocol HTTP.
Merci d'avance.

Python.org : Le site officiel du langage Python.
Zope.org : Le site web officiel de Zope.
Daily Python-URL : Actus de l'univers Python.
Tribute to Zyons : Zyons notre ami et membre fondateur de l'Afpy, nous quittait en 2005.