IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Réseau/Web Python Discussion :

Erreur HTTP 400 avec mechanize, proxy et https


Sujet :

Réseau/Web Python

  1. #1
    Candidat au Club
    Inscrit en
    Mai 2008
    Messages
    2
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 2
    Points : 2
    Points
    2
    Par défaut Erreur HTTP 400 avec mechanize, proxy et https
    Bonjour tous,

    Je suis en train de développer un robot en python pour extraire des données sur un site sécurisé.

    le site sécurisé est sur internet et je suis derriere un proxy sur un réseau local.

    Petite particularité, ce site n'est accessible qu'au travers de certificats.


    Mon code est le suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    from mechanize import Browser
     
    host = 'www.myserver.com:443'
    site_id="https://www.myserver.com/"
     
    br=Browser()
    br.set_proxies({"https": "http://my-proxy.company.com:8088","http": "http://my-proxy.company.com:8088"})
    br.add_client_certificate(host,"certs/certificate_key.pem","certs/certificate.pem")
    br.set_debug_http(True)
     
    print "in test.py"
     
    br.open(site_id)
    En l'executant, j'obtient ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    in test.py
    connect: (my-proxy.company.com, 8088)
    send: 'GET <a href="https://www.myserver.com/" target="_blank">https://www.myserver.com/</a> HTTP/1.1\r\nAccept-Encoding: identity\r\nHost: <a href="http://www.myserver.com\r\nConnection:" target="_blank">www.myserver.com\r\nConnection:</a> close\r\nUser-Agent: Python-urllib/2.5\r\n\r\n'
    reply: 'HTTP/1.1 400 Bad Request\r\n'
    header: Cache-Control: no-cache
    header: Pragma: no-cache
    header: Content-Type: text/html; charset=utf-8
    header: Proxy-Connection: close
    header: Connection: close
    header: Content-Length: 691
    Traceback (most recent call last):
      File "./test.py", line 67, in <module>
        br.open(site_id)
      File "build/bdist.linux-i686/egg/mechanize/_mechanize.py", line 203, in open
      File "build/bdist.linux-i686/egg/mechanize/_mechanize.py", line 254, in _mech_open
    mechanize._response.httperror_seek_wrapper: HTTP Error 400: Bad Request
    J'ai testé ce même code sur un serveur qui n'avait pas besoin de proxy et il fonctionne.

    Par ailleurs, la librairie mechanize que j'utilise (0.1.7b) semble être une traduction de ce que fait la lib www::mechanize de perl.
    L'erreur 400 étant commune dans ce contexte perl, la solution passait par une variable à unseté. "https"

    Je n'ai pas trouvé d'équivalent pour mechanize python, mais le comportement semble bien similaire.

    Es-ce que quelqu'un a déjà rencontré ce genre de problème? et résolu ...

    Merci pour vos réponses et aides.
    Poupoune

  2. #2
    Candidat au Club
    Inscrit en
    Mai 2008
    Messages
    2
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 2
    Points : 2
    Points
    2
    Par défaut ca y est. C'est good. Ca marche :-)
    Re-bonjour tous,

    Après de multiples recherches pour résoudre mon problème d'erreur 400, voici la solution:
    J'ai repris un code qui ne fonctionnait qu'avec urllib2, peu évolutif et surtout qui ne marchait pas avec mechanize.
    Donc, voila ce que j'ai écrit, afin d'utiliser un proxy et un serveur distant sécurisé et python-mechanize:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    #!/usr/bin/python
     
    import mechanize
    from mechanize import Browser, ProxyHandler, HTTPHandler, _parse_proxy
    from httplib import HTTPConnection, FakeSocket
    import urllib
    from urllib import unquote
    import socket
     
     
    class ProxyHTTPSConnection(HTTPConnection):
        def __init__(self, host, port=None, key_file=None, cert_file=None,
                     strict=None, real_host=None, real_port = None, debug = 0):
            HTTPConnection.__init__(self, host, port, strict)
            self.key_file = key_file
            self.cert_file = cert_file
            self._real_host = real_host
            if real_port:
                self._real_port = real_port
            else:
                self._real_port = 443
     
        def connect(self):
            """Connect to a host on a given (SSL) port through proxy."""
     
            HTTPConnection.connect(self)
            #send proxy CONNECT request
            self.send("CONNECT %s:%d HTTP/1.0\r\n\r\n" % (self._real_host, self._real_port))
            #expect a HTTP/1.0 200 Connection established
            response = self.response_class(self.sock, strict=self.strict, method=self._method)
            (version, code, message) = response._read_status()
            #probably here we can handle auth requests...
            if code != 200:
                #proxy returned and error, abort connection, and raise exception
                self.close()
                raise self.sock.error, "Proxy connection failed: %d %s" % (code, message.strip())
            #eat up header block from proxy....
            while True:
                #should not use directly fp probablu
                line = response.fp.readline()
                if line == '\r\n': break
            ssl = socket.ssl(self.sock, self.key_file, self.cert_file)
            self.sock = FakeSocket(self.sock, ssl)
     
     
    class ProxyHTTPSConnectionFactory:
        def __init__(self, key_file, cert_file, host, port):
            self._key_file = key_file
            self._cert_file = cert_file
            self.host = host
            self.port = port
     
        def __call__(self, hostport):
            return ProxyHTTPSConnection(
                hostport,
                key_file=self._key_file, cert_file=self._cert_file,
                real_host=self.host, real_port=self.port)
     
     
    class ProxyHTTPSHandler(HTTPHandler):
        """Provide HTTPS access through HTTP proxy using "CONNECT" 
        """
        def __init__(self,client_cert_manager = None):
            HTTPHandler.__init__(self)
            self.client_cert_manager = client_cert_manager
     
        def http_open(self, req):
            # The proxy is set and a secure channel have to be set.
            if self.client_cert_manager is not None:
                key_file, cert_file = self.client_cert_manager.find_key_cert(
                    req.get_full_url())
                proto, rest = urllib.splittype(req.get_full_url())
                host, rest = urllib.splithost(rest)
                host, port = urllib.splitport(host)
                self._debuglevel = self.parent._ua_handlers.get("https")._debuglevel
                conn_factory = ProxyHTTPSConnectionFactory(key_file, cert_file,host,port)
            else:
                conn_factory = ProxyHTTPSConnection
            return self.do_open(conn_factory, req)
     
     
     
    class ExtProxyHandler(ProxyHandler):
        def __init__(self, proxies=None):
            ProxyHandler.__init__(self,proxies)
     
        def proxy_open(self, req, proxy, type):
            orig_type = req.get_type()
            proxy_type, user, password, hostport = _parse_proxy(proxy)
            if proxy_type is None:
                proxy_type = orig_type
            if user and password:
                user_pass = '%s:%s' % (unquote(user), unquote(password))
                creds = base64.encodestring(user_pass).strip()
                req.add_header('Proxy-authorization', 'Basic ' + creds)
            hostport = unquote(hostport)
            req.set_proxy(hostport, proxy_type)
            if orig_type == proxy_type:
                # let other handlers take care of it
                return None
            else:
                # need to start over, because the other handlers don't
                # grok the proxy's URL type
                # e.g. if we have a constructor arg proxies like so:
                # {'http': 'ftp://proxy.example.com'}, we may end up turning
                # a request for http://acme.example.com/a into one for
                # ftp://proxy.example.com/a
                if orig_type == "https":
                    handler=ProxyHTTPSHandler(self.parent._client_cert_manager)
                    handler.add_parent(self.parent)
                    return handler.http_open(req)
                else:
                    return self.parent.open(req)
     
     
    class ExtBrowser(Browser):
        def __init__(self):
            Browser.handler_classes['_proxy']=ExtProxyHandler
            Browser.__init__(self)
     
     
     
     
    if __name__ == '__main__':
     
        site_id="https://www.mysecureserver.com/"
     
        br=ExtBrowser()
     
        br.set_handle_robots(False)
        br.set_proxies({"https":"http://proxy.mycompany.com:8080"})
     
        host = 'www.mysecureserver.com:443'
        br.add_client_certificate(host,"~/.subversion/certificate_key.pem","~/.subversion/certificate.pem")
     
        br.set_debug_http(True)
     
        br.open(site_id)
     
        print br.title()
        print br.geturl()
    Je ne connais python que depuis la semaine dernière... alors, si mon code contient des erreurs de conventions ou autres, dites-le moi, merci.

    Par ailleurs, je serai bien tenter de suggérer mon adaptation à mechanize, de sorte à intégrer cela dans les distribs...

    a+

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Erreur HTTP 400
    Par noumedem dans le forum Spring
    Réponses: 23
    Dernier message: 11/10/2013, 13h33
  2. Réponses: 1
    Dernier message: 23/08/2013, 18h07
  3. [Erreur HTTP 400] Bad request.
    Par ZeKiD dans le forum Subversion
    Réponses: 0
    Dernier message: 16/08/2011, 15h36
  4. Http client avec proxy
    Par mermoz dans le forum Pentaho
    Réponses: 4
    Dernier message: 27/05/2010, 20h30
  5. Réponses: 4
    Dernier message: 11/06/2008, 17h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo