[PATCH] httpclient: update to upstream revision 2995635573d2
Augie Fackler
raf at durin42.com
Tue May 10 02:10:08 UTC 2016
# HG changeset patch
# User Augie Fackler <augie at google.com>
# Date 1462842830 14400
# Mon May 09 21:13:50 2016 -0400
# Node ID 8a66eda46c989944f242a96960ef4d36f8785713
# Parent ed2a3818c1fc1599966e8b0de4677c2ec5f2eb37
httpclient: update to upstream revision 2995635573d2
This is mostly Python 3 compat work thanks to timeless.
diff --git a/mercurial/httpclient/__init__.py b/mercurial/httpclient/__init__.py
--- a/mercurial/httpclient/__init__.py
+++ b/mercurial/httpclient/__init__.py
@@ -41,18 +41,29 @@ from __future__ import absolute_import
# 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 @@ class HTTPResponse(object):
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 @@ def _foldheaders(headers):
"""
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 @@ class HTTPConnection(object):
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 @@ class HTTPConnection(object):
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)
diff --git a/mercurial/httpclient/_readers.py b/mercurial/httpclient/_readers.py
--- a/mercurial/httpclient/_readers.py
+++ b/mercurial/httpclient/_readers.py
@@ -33,7 +33,12 @@ have any clients outside of httpplus.
"""
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__)
diff --git a/mercurial/httpclient/socketutil.py b/mercurial/httpclient/socketutil.py
--- a/mercurial/httpclient/socketutil.py
+++ b/mercurial/httpclient/socketutil.py
@@ -122,7 +122,8 @@ else:
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(
More information about the Mercurial-devel
mailing list