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() |
Partager