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.
--- a/mercurial/httpclient/__init__.py Thu Sep 19 16:29:00 2013 -0400
+++ b/mercurial/httpclient/__init__.py Fri Sep 20 09:15:09 2013 -0400
@@ -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)