Mercurial > hg-stable
changeset 29131:8a66eda46c98
httpclient: update to upstream revision 2995635573d2
This is mostly Python 3 compat work thanks to timeless.
author | Augie Fackler <augie@google.com> |
---|---|
date | Mon, 09 May 2016 21:13:50 -0400 |
parents | ed2a3818c1fc |
children | 12769703d4ba |
files | mercurial/httpclient/__init__.py mercurial/httpclient/_readers.py mercurial/httpclient/socketutil.py |
diffstat | 3 files changed, 89 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/httpclient/__init__.py Fri May 06 19:52:21 2016 +0800 +++ b/mercurial/httpclient/__init__.py Mon May 09 21:13:50 2016 -0400 @@ -41,18 +41,29 @@ # Many functions in this file have too many arguments. # pylint: disable=R0913 -import cStringIO import errno -import httplib +import inspect import logging import rfc822 import select import socket +try: + import cStringIO as io + io.StringIO +except ImportError: + import io + +try: + import httplib + httplib.HTTPException +except ImportError: + import http.client as httplib + from . import ( _readers, socketutil, - ) +) logger = logging.getLogger(__name__) @@ -242,7 +253,7 @@ self.status = int(self.status) if self._eol != EOL: hdrs = hdrs.replace(self._eol, '\r\n') - headers = rfc822.Message(cStringIO.StringIO(hdrs)) + headers = rfc822.Message(io.StringIO(hdrs)) content_len = None if HDR_CONTENT_LENGTH in headers: content_len = int(headers[HDR_CONTENT_LENGTH]) @@ -296,6 +307,46 @@ """ return dict((k.lower(), (k, v)) for k, v in headers.iteritems()) +try: + inspect.signature + def _handlesarg(func, arg): + """ Try to determine if func accepts arg + + If it takes arg, return True + If it happens to take **args, then it could do anything: + * It could throw a different TypeError, just for fun + * It could throw an ArgumentError or anything else + * It could choose not to throw an Exception at all + ... return 'unknown' + + Otherwise, return False + """ + params = inspect.signature(func).parameters + if arg in params: + return True + for p in params: + if params[p].kind == inspect._ParameterKind.VAR_KEYWORD: + return 'unknown' + return False +except AttributeError: + def _handlesarg(func, arg): + """ Try to determine if func accepts arg + + If it takes arg, return True + If it happens to take **args, then it could do anything: + * It could throw a different TypeError, just for fun + * It could throw an ArgumentError or anything else + * It could choose not to throw an Exception at all + ... return 'unknown' + + Otherwise, return False + """ + spec = inspect.getargspec(func) + if arg in spec.args: + return True + if spec.keywords: + return 'unknown' + return False class HTTPConnection(object): """Connection to a single http server. @@ -346,9 +397,31 @@ if '[' in host: host = host[1:-1] if ssl_wrap_socket is not None: - self._ssl_wrap_socket = ssl_wrap_socket + _wrap_socket = ssl_wrap_socket else: - self._ssl_wrap_socket = socketutil.wrap_socket + _wrap_socket = socketutil.wrap_socket + call_wrap_socket = None + handlesubar = _handlesarg(_wrap_socket, 'server_hostname') + if handlesubar is True: + # supports server_hostname + call_wrap_socket = _wrap_socket + handlesnobar = _handlesarg(_wrap_socket, 'serverhostname') + if handlesnobar is True and handlesubar is not True: + # supports serverhostname + def call_wrap_socket(sock, server_hostname=None, **ssl_opts): + return _wrap_socket(sock, serverhostname=server_hostname, + **ssl_opts) + if handlesubar is False and handlesnobar is False: + # does not support either + def call_wrap_socket(sock, server_hostname=None, **ssl_opts): + return _wrap_socket(sock, **ssl_opts) + if call_wrap_socket is None: + # we assume it takes **args + def call_wrap_socket(sock, **ssl_opts): + if 'server_hostname' in ssl_opts: + ssl_opts['serverhostname'] = ssl_opts['server_hostname'] + return _wrap_socket(sock, **ssl_opts) + self._ssl_wrap_socket = call_wrap_socket if use_ssl is None and port is None: use_ssl = False port = 80 @@ -429,7 +502,8 @@ sock.setblocking(1) logger.debug('wrapping socket for ssl with options %r', self.ssl_opts) - sock = self._ssl_wrap_socket(sock, **self.ssl_opts) + sock = self._ssl_wrap_socket(sock, server_hostname=self.host, + **self.ssl_opts) if self._ssl_validator: self._ssl_validator(sock) sock.setblocking(0)
--- a/mercurial/httpclient/_readers.py Fri May 06 19:52:21 2016 +0800 +++ b/mercurial/httpclient/_readers.py Mon May 09 21:13:50 2016 -0400 @@ -33,7 +33,12 @@ """ from __future__ import absolute_import -import httplib +try: + import httplib + httplib.HTTPException +except ImportError: + import http.client as httplib + import logging logger = logging.getLogger(__name__)
--- a/mercurial/httpclient/socketutil.py Fri May 06 19:52:21 2016 +0800 +++ b/mercurial/httpclient/socketutil.py Mon May 09 21:13:50 2016 -0400 @@ -122,7 +122,8 @@ server_side=False, cert_reqs=CERT_NONE, ssl_version=_PROTOCOL_SSLv23, ca_certs=None, do_handshake_on_connect=True, - suppress_ragged_eofs=True): + suppress_ragged_eofs=True, + server_hostname=None): """Backport of ssl.wrap_socket from Python 2.6.""" if cert_reqs != CERT_NONE and ca_certs: raise CertificateValidationUnsupported(