Patchwork [2,of,3] https: do not inherit httplib.HTTPSConnection that creates unused SSLContext

login
register
mail settings
Submitter Yuya Nishihara
Date June 2, 2015, 2:28 p.m.
Message ID <6c7323bd82293bbd7475.1433255334@mimosa>
Download mbox | patch
Permalink /patch/9442/
State Accepted
Headers show

Comments

Yuya Nishihara - June 2, 2015, 2:28 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1430985740 -32400
#      Thu May 07 17:02:20 2015 +0900
# Node ID 6c7323bd82293bbd74758bea5e54538c82564872
# Parent  aecf06023f2f09ea07a0b4a986a82f379d16fb42
https: do not inherit httplib.HTTPSConnection that creates unused SSLContext

HTTPSConnection of Python 2.7.9 creates SSLContext in __init__, which involves
a password prompt for decrypting the private key. This means the password was
asked twice, one for unused SSLContext, and next for our ssl function.

Because our httpsconnection replaces connect() method at all, we can simply
drop httplib.HTTPSConnection. Instead, class and instance attributes are copied
from it.

HTTPSConnection of Python 2.7.8 and 2.6.9 seem to have no such problem.

https://hg.python.org/cpython/file/v2.7.9/Lib/httplib.py#l1183

Patch

diff --git a/mercurial/url.py b/mercurial/url.py
--- a/mercurial/url.py
+++ b/mercurial/url.py
@@ -318,11 +318,18 @@  class httphandler(keepalive.HTTPHandler)
         return keepalive.HTTPHandler._start_transaction(self, h, req)
 
 if has_https:
-    class httpsconnection(httplib.HTTPSConnection):
+    class httpsconnection(httplib.HTTPConnection):
         response_class = keepalive.HTTPResponse
+        default_port = httplib.HTTPS_PORT
         # must be able to send big bundle as stream.
         send = _gen_sendfile(keepalive.safesend)
-        getresponse = keepalive.wrapgetresponse(httplib.HTTPSConnection)
+        getresponse = keepalive.wrapgetresponse(httplib.HTTPConnection)
+
+        def __init__(self, host, port=None, key_file=None, cert_file=None,
+                     *args, **kwargs):
+            httplib.HTTPConnection.__init__(self, host, port, *args, **kwargs)
+            self.key_file = key_file
+            self.cert_file = cert_file
 
         def connect(self):
             self.sock = _create_connection((self.host, self.port))