|
|
 |
|
Title: urrlib2 opener for SSL proxy (CONNECT method)
Submitter: Alessandro Budai
(other recipes)
Last Updated: 2005/11/16
Version no: 1.1
Category:
Network
|
|
3 vote(s)
|
|
|
|
Description:
This small module builds an urllib2 opener that can be used to make a connection through a proxy using the http CONNECT method (that can be used to proxy SSLconnections).
The current urrlib2 seems to not support this method.
Source: Text Source
import urllib2
import urllib
import httplib
import socket
class ProxyHTTPConnection(httplib.HTTPConnection):
_ports = {'http' : 80, 'https' : 443}
def request(self, method, url, body=None, headers={}):
proto, rest = urllib.splittype(url)
if proto is None:
raise ValueError, "unknown URL type: %s" % url
host, rest = urllib.splithost(rest)
host, port = urllib.splitport(host)
if port is None:
try:
port = self._ports[proto]
except KeyError:
raise ValueError, "unknown protocol for: %s" % url
self._real_host = host
self._real_port = port
httplib.HTTPConnection.request(self, method, url, body, headers)
def connect(self):
httplib.HTTPConnection.connect(self)
self.send("CONNECT %s:%d HTTP/1.0\r\n\r\n" % (self._real_host, self._real_port))
response = self.response_class(self.sock, strict=self.strict, method=self._method)
(version, code, message) = response._read_status()
if code != 200:
self.close()
raise socket.error, "Proxy connection failed: %d %s" % (code, message.strip())
while True:
line = response.fp.readline()
if line == '\r\n': break
class ProxyHTTPSConnection(ProxyHTTPConnection):
default_port = 443
def __init__(self, host, port = None, key_file = None, cert_file = None, strict = None):
ProxyHTTPConnection.__init__(self, host, port)
self.key_file = key_file
self.cert_file = cert_file
def connect(self):
ProxyHTTPConnection.connect(self)
ssl = socket.ssl(self.sock, self.key_file, self.cert_file)
self.sock = httplib.FakeSocket(self.sock, ssl)
class ConnectHTTPHandler(urllib2.HTTPHandler):
def do_open(self, http_class, req):
return urllib2.HTTPHandler.do_open(self, ProxyHTTPConnection, req)
class ConnectHTTPSHandler(urllib2.HTTPSHandler):
def do_open(self, http_class, req):
return urllib2.HTTPSHandler.do_open(self, ProxyHTTPSConnection, req)
if __name__ == '__main__':
import sys
opener = urllib2.build_opener(ConnectHTTPHandler, ConnectHTTPSHandler)
urllib2.install_opener(opener)
req = urllib2.Request(url='https://192.168.1.1')
req.set_proxy('192.168.1.254:3128', 'https')
f = urllib2.urlopen(req)
print f.read()
Discussion:
This module provides an openers that can be used with urrlib2 to make a connection through a proxy that supports the CONNECT method.
The ProxyHTTPConnection class takes care of connecting to the proxy, sending the CONNECT string and interpreting results. In case of success (http code 200 reply) we are connected to remote host and everything can go as usual.
When connecting to an SSL enabled host ProxyHTTPSConnection, after a successfull connect, makes the socket ssl-aware.
Currently no authentication scheme is supported, but can be easily added (maybe even resorting to urrlib2 support).
|
|
Add comment
|
|
Number of comments: 3
Modification to use with https redirection (required for libgmail), Norm Petterson, 2006/05/04
Thanks for the nice tool. However, https redirection is not handled,
since urllib2 doesn't let you do set_proxy on the redirection
requests. I modified the above opener accordingly:
class ConnectHTTPHandler(urllib2.HTTPHandler):
def __init__(self, proxy=None, debuglevel=0):
self.proxy = proxy
urllib2.HTTPHandler.__init__(self, debuglevel)
def do_open(self, http_class, req):
if self.proxy is not None:
req.set_proxy(self.proxy, 'http')
return urllib2.HTTPHandler.do_open(self, ProxyHTTPConnection, req)
class ConnectHTTPSHandler(urllib2.HTTPSHandler):
def __init__(self, proxy=None, debuglevel=0):
self.proxy = proxy
urllib2.HTTPSHandler.__init__(self, debuglevel)
def do_open(self, http_class, req):
if self.proxy is not None:
req.set_proxy(self.proxy, 'https')
return urllib2.HTTPSHandler.do_open(self, ProxyHTTPSConnection, req)
Note that you specify your proxy with urllib2.build_opener, e.g.,
p = '127.0.0.1:5865'
opener = urllib2.build_opener(
ConnectHTTPHandler(proxy=p), ConnectHTTPSHandler(proxy=p))
Also, of course, you no longer need to do req.set_proxy in your own
code.
Add comment
HTTP proxy with CONNECT support to tunnel HTTPS request, yin sun, 2006/06/16
To work with "HTTP proxy with CONNECT support to tunnel HTTPS request", a ProxyHTTPSConnertion is needed inside ConnectHTTPHandler
This is the code change
class ConnectHTTPHandler(urllib2.HTTPHandler):
def do_open(self, http_class, req):
return urllib2.HTTPHandler.do_open(self, ProxyHTTPSConnection, req)
Add comment
urllib2.HTTPSHandler error, Joey Joey, 2007/11/15
i'm getting this error:
Traceback (most recent call last):
File "test.py", line 77, in ?
class ConnectHTTPSHandler(urllib2.HTTPSHandler):
AttributeError: 'module' object has no attribute 'HTTPSHandler'
I'm using Python 2.4
Add comment
|
|
|
|
|
 |
|