[Inteproxy-commits] r10 - trunk

scm-commit@wald.intevation.org scm-commit at wald.intevation.org
Thu Nov 16 23:14:52 CET 2006


Author: jan
Date: 2006-11-16 23:14:52 +0100 (Thu, 16 Nov 2006)
New Revision: 10

Added:
   trunk/proxyconnection.py
Modified:
   trunk/ChangeLog
Log:
Patch by Thomas Arendsen Hein:
proxyconnection.py: New. urrlib2 opener for SSL proxy (CONNECT)


Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2006-11-16 10:40:02 UTC (rev 9)
+++ trunk/ChangeLog	2006-11-16 22:14:52 UTC (rev 10)
@@ -1,3 +1,7 @@
+2006-11-16  Thomas Arendsen Hein <thomas at intevation.de>
+
+	* proxyconnection.py: New. urrlib2 opener for SSL proxy (CONNECT)
+
 2006-11-16  Jan-Oliver Wagner  <jan-oliver.wagner at intevation.de>
 
 	* InteProxy.py (inteproxy_version): New. Version string.

Added: trunk/proxyconnection.py
===================================================================
--- trunk/proxyconnection.py	2006-11-16 10:40:02 UTC (rev 9)
+++ trunk/proxyconnection.py	2006-11-16 22:14:52 UTC (rev 10)
@@ -0,0 +1,105 @@
+# Copyright (C) 2006 by Alessandro Budai
+# from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/456195
+#
+# This software may be used and distributed according to the terms
+# of the Python License 2.3 or newer, see http://www.python.org/license
+
+"""
+urrlib2 opener for SSL proxy (CONNECT method)
+
+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.
+
+tested with python 2.4
+"""
+
+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={}):
+        #request is called before connect, so can interpret url and get
+        #real host/port to be used to make CONNECT request to proxy
+        proto, rest = urllib.splittype(url)
+        if proto is None:
+            raise ValueError, "unknown URL type: %s" % url
+        #get host
+        host, rest = urllib.splithost(rest)
+        #try to get port
+        host, port = urllib.splitport(host)
+        #if port is not defined try to get from proto
+        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)
+        #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 socket.error, "Proxy connection failed: %d %s" % (code, message.strip())
+        #eat up header block from proxy....
+        while True:
+            #should not use directly fp probably
+            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)
+        #make the sock ssl-aware
+        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()



More information about the Inteproxy-commits mailing list