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

login
register
mail settings
Submitter Augie Fackler
Date Sept. 20, 2013, 2:29 p.m.
Message ID <2431d0d80cdc3a8f9cac.1379687399@arthedain.pit.corp.google.com>
Download mbox | patch
Permalink /patch/2561/
State Accepted
Commit c48df403caae2a5aad26cf8ad3ddee09dedfedd5
Headers show

Comments

Augie Fackler - Sept. 20, 2013, 2:29 p.m.
# HG changeset patch
# User Augie Fackler <raf@durin42.com>
# 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.

Patch

diff --git a/mercurial/httpclient/__init__.py b/mercurial/httpclient/__init__.py
--- a/mercurial/httpclient/__init__.py
+++ b/mercurial/httpclient/__init__.py
@@ -292,7 +292,7 @@ 
     def __init__(self, host, port=None, use_ssl=None, ssl_validator=None,
                  timeout=TIMEOUT_DEFAULT,
                  continue_timeout=TIMEOUT_ASSUME_CONTINUE,
-                 proxy_hostport=None, **ssl_opts):
+                 proxy_hostport=None, ssl_wrap_socket=None, **ssl_opts):
         """Create a new HTTPConnection.
 
         Args:
@@ -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 @@ 
             sock.setblocking(1)
             logger.debug('wrapping socket for ssl with options %r',
                          self.ssl_opts)
-            sock = socketutil.wrap_socket(sock, **self.ssl_opts)
+            sock = self._ssl_wrap_socket(sock, **self.ssl_opts)
             if self._ssl_validator:
                 self._ssl_validator(sock)
         sock.setblocking(0)