Patchwork [2,of,4,force-tls] httpclient: import 4bb625347d4a to provide SSL wrapper injection

mail settings
Submitter Augie Fackler
Date Sept. 20, 2013, 2:29 p.m.
Message ID <>
Download mbox | patch
Permalink /patch/2561/
State Accepted
Commit c48df403caae2a5aad26cf8ad3ddee09dedfedd5
Headers show


Augie Fackler - Sept. 20, 2013, 2:29 p.m.
# HG changeset patch
# User Augie Fackler <>
# Date 1379682909 14400
#      Fri Sep 20 09:15:09 2013 -0400
# Node ID 2431d0d80cdc3a8f9cac58751185a513df0fdf4d
# Parent  069ad53af06879c9809ea71ab00138d02839a3d5
httpclient: import 4bb625347d4a to provide SSL wrapper injection

This lets us inject our own ssl.wrap_socket equivalent into
httpclient, which means that any changes we make to our ssl handling
can be *entirely* on our side without having to muck with httpclient,
which sounds appealing. For example, an extension could wrap
sslutil.ssl_wrap_socket with an api-compatible wrapper and then tweak
SSL settings more precisely or use GnuTLS instead of OpenSSL.


diff --git a/mercurial/httpclient/ b/mercurial/httpclient/
--- a/mercurial/httpclient/
+++ b/mercurial/httpclient/
@@ -292,7 +292,7 @@ 
     def __init__(self, host, port=None, use_ssl=None, ssl_validator=None,
-                 proxy_hostport=None, **ssl_opts):
+                 proxy_hostport=None, ssl_wrap_socket=None, **ssl_opts):
         """Create a new HTTPConnection.
@@ -307,12 +307,23 @@ 
                    "100 Continue" response. Default is TIMEOUT_ASSUME_CONTINUE.
           proxy_hostport: Optional. Tuple of (host, port) to use as an http
                        proxy for the connection. Default is to not use a proxy.
+          ssl_wrap_socket: Optional function to use for wrapping
+            sockets. If unspecified, the one from the ssl module will
+            be used if available, or something that's compatible with
+            it if on a Python older than 2.6.
+        Any extra keyword arguments to this function will be provided
+        to the ssl_wrap_socket method. If no ssl
         if port is None and host.count(':') == 1 or ']:' in host:
             host, port = host.rsplit(':', 1)
             port = int(port)
             if '[' in host:
                 host = host[1:-1]
+        if ssl_wrap_socket is not None:
+            self._ssl_wrap_socket = ssl_wrap_socket
+        else:
+            self._ssl_wrap_socket = socketutil.wrap_socket
         if use_ssl is None and port is None:
             use_ssl = False
             port = 80
@@ -387,7 +398,7 @@ 
             logger.debug('wrapping socket for ssl with options %r',
-            sock = socketutil.wrap_socket(sock, **self.ssl_opts)
+            sock = self._ssl_wrap_socket(sock, **self.ssl_opts)
             if self._ssl_validator: