Parcourir la source

* added wrapper to httplib to enable https proxy support for Python < 2.6.1. Needs more work for it to function!

git-svn-id: http://proj.badc.rl.ac.uk/svn/ndg-security/trunk/ndg_httpsclient@7985 051b1e3e-aa0c-0410-b6c2-bfbade6052be
pjkersha il y a 13 ans
Parent
commit
87b8985fd4
1 fichiers modifiés avec 67 ajouts et 0 suppressions
  1. 67 0
      ndg/httpsclient/httplib_proxy.py

+ 67 - 0
ndg/httpsclient/httplib_proxy.py

@@ -0,0 +1,67 @@
+'''
+Created on Jan 11, 2012
+
+@author: philipkershaw
+'''
+import socket
+from httplib import HTTPConnection as _HTTPConnection
+from httplib import HTTPException
+
+# maximal line length when calling readline().
+_MAXLINE = 65536
+
+class LineTooLong(HTTPException):
+    def __init__(self, line_type):
+        HTTPException.__init__(self, "got more than %d bytes when reading %s"
+                                     % (_MAXLINE, line_type))
+        
+
+class HTTPConnection(_HTTPConnection):
+    NDG_HTTPSCLIENT = True
+    
+    def __init__(self, *arg, **kwarg):
+        self._tunnel_host = None
+        self._tunnel_port = None
+        self._tunnel_headers = {}
+
+        _HTTPConnection.__init__(self, *arg, **kwarg)
+        
+    def set_tunnel(self, host, port=None, headers=None):
+        """ Sets up the host and the port for the HTTP CONNECT Tunnelling.
+
+        The headers argument should be a mapping of extra HTTP headers
+        to send with the CONNECT request.
+        """
+        self._tunnel_host = host
+        self._tunnel_port = port
+        if headers:
+            self._tunnel_headers = headers
+        else:
+            self._tunnel_headers.clear()
+
+    def _tunnel(self):
+        self._set_hostport(self._tunnel_host, self._tunnel_port)
+        self.send("CONNECT %s:%d HTTP/1.0\r\n" % (self.host, self.port))
+        for header, value in self._tunnel_headers.iteritems():
+            self.send("%s: %s\r\n" % (header, value))
+        self.send("\r\n")
+        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("Tunnel connection failed: %d %s" % (code,
+                                                            message.strip()))
+        while True:
+            line = response.fp.readline(_MAXLINE + 1)
+            if len(line) > _MAXLINE:
+                raise LineTooLong("header line")
+            if line == '\r\n': break
+            
+    def connect(self):
+        """Connect to the host and port specified in __init__."""
+        _HTTPConnection.connect(self)
+
+        if self._tunnel_host:
+            self._tunnel()