changeset 2569:52ce0d6bc375

HTTPS: fix python2.3, persistent connections, don't explode if SSL is not available The urllib2 differences between python 2.3 and 2.4 are hidden by using keepalive.py, which also gives us support for persistent connections. Support for HTTPS is enabled only if there's a HTTPSHandler class in urllib2. It's not possible to have separate classes as handlers for HTTP and HTTPS: to support persistent HTTPS connections, we need a class that inherits from both keepalive.HTTPHandler and urllib2.HTTPSHandler. If we try to pass (an instance of) this class and (an instance of) the httphandler class to urllib2.build_opener, this function ends up getting confused, since both classes are subclasses of the HTTPHandler default handler, and raises an exception.
author Alexis S. L. Carvalho <alexis@cecm.usp.br>
date Thu, 06 Jul 2006 03:14:55 -0300
parents 2748253b49c2
children 2264b2b077a1
files mercurial/httprepo.py
diffstat 1 files changed, 25 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/httprepo.py	Wed Jul 05 13:28:25 2006 -0500
+++ b/mercurial/httprepo.py	Thu Jul 06 03:14:55 2006 -0300
@@ -87,25 +87,31 @@
             for chunk in util.filechunkiter(data):
                 keepalive.HTTPConnection.send(self, chunk)
 
-class httphandler(keepalive.HTTPHandler):
+class basehttphandler(keepalive.HTTPHandler):
     def http_open(self, req):
         return self.do_open(httpconnection, req)
 
-class httpsconnection(httplib.HTTPSConnection):
-    # must be able to send big bundle as stream.
+has_https = hasattr(urllib2, 'HTTPSHandler')
+if has_https:
+    class httpsconnection(httplib.HTTPSConnection):
+        response_class = keepalive.HTTPResponse
+        # must be able to send big bundle as stream.
 
-    def send(self, data):
-        if isinstance(data, str):
-            httplib.HTTPSConnection.send(self, data)
-        else:
-            # if auth required, some data sent twice, so rewind here
-            data.seek(0)
-            for chunk in util.filechunkiter(data):
-                httplib.HTTPSConnection.send(self, chunk)
+        def send(self, data):
+            if isinstance(data, str):
+                httplib.HTTPSConnection.send(self, data)
+            else:
+                # if auth required, some data sent twice, so rewind here
+                data.seek(0)
+                for chunk in util.filechunkiter(data):
+                    httplib.HTTPSConnection.send(self, chunk)
 
-class httpshandler(urllib2.HTTPSHandler):
-    def https_open(self, req):
-        return self.do_open(httpsconnection, req)
+    class httphandler(basehttphandler, urllib2.HTTPSHandler):
+        def https_open(self, req):
+            return self.do_open(httpsconnection, req)
+else:
+    class httphandler(basehttphandler):
+        pass
 
 class httprepository(remoterepository):
     def __init__(self, ui, path):
@@ -176,7 +182,6 @@
 
         opener = urllib2.build_opener(
             handler,
-            httpshandler(),
             urllib2.HTTPBasicAuthHandler(passmgr),
             urllib2.HTTPDigestAuthHandler(passmgr))
 
@@ -322,4 +327,8 @@
             os.unlink(tempname)
 
 class httpsrepository(httprepository):
-    pass
+    def __init__(self, ui, path):
+        if not has_https:
+            raise util.Abort(_('Python support for SSL and HTTPS '
+                               'is not installed'))
+        httprepository.__init__(self, ui, path)