Patchwork D4877: url: Allow to configure timeout on http connection

login
register
mail settings
Submitter phabricator
Date Oct. 4, 2018, 9:34 a.m.
Message ID <differential-rev-PHID-DREV-2v35626fddgeyrsteqzv-req@phab.mercurial-scm.org>
Download mbox | patch
Permalink /patch/35441/
State New
Headers show

Comments

phabricator - Oct. 4, 2018, 9:34 a.m.
ced created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  By default, httplib.HTTPConnection opens connection with no timeout.
  If the server is hanging, Mercurial will wait indefinitely. This may be an
  issue for automated scripts.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D4877

AFFECTED FILES
  mercurial/configitems.py
  mercurial/help/config.txt
  mercurial/keepalive.py
  mercurial/url.py

CHANGE DETAILS




To: ced, #hg-reviewers
Cc: mercurial-devel

Patch

diff --git a/mercurial/url.py b/mercurial/url.py
--- a/mercurial/url.py
+++ b/mercurial/url.py
@@ -317,8 +317,8 @@ 
 
 class logginghttphandler(httphandler):
     """HTTP handler that logs socket I/O."""
-    def __init__(self, logfh, name, observeropts):
-        super(logginghttphandler, self).__init__()
+    def __init__(self, logfh, name, observeropts, timeout=None):
+        super(logginghttphandler, self).__init__(timeout=timeout)
 
         self._logfh = logfh
         self._logname = name
@@ -365,8 +365,8 @@ 
             sslutil.validatesocket(self.sock)
 
     class httpshandler(keepalive.KeepAliveHandler, urlreq.httpshandler):
-        def __init__(self, ui):
-            keepalive.KeepAliveHandler.__init__(self)
+        def __init__(self, ui, timeout=None):
+            keepalive.KeepAliveHandler.__init__(self, timeout=timeout)
             urlreq.httpshandler.__init__(self)
             self.ui = ui
             self.pwmgr = passwordmgr(self.ui,
@@ -525,18 +525,19 @@ 
     ``sendaccept`` allows controlling whether the ``Accept`` request header
     is sent. The header is sent by default.
     '''
+    timeout = ui.configwith(float, 'http', 'timeout')
     handlers = []
 
     if loggingfh:
         handlers.append(logginghttphandler(loggingfh, loggingname,
-                                           loggingopts or {}))
+                                           loggingopts or {}, timeout=timeout))
         # We don't yet support HTTPS when logging I/O. If we attempt to open
         # an HTTPS URL, we'll likely fail due to unknown protocol.
 
     else:
-        handlers.append(httphandler())
+        handlers.append(httphandler(timeout=timeout))
         if has_https:
-            handlers.append(httpshandler(ui))
+            handlers.append(httpshandler(ui, timeout=timeout))
 
     handlers.append(proxyhandler(ui))
 
diff --git a/mercurial/keepalive.py b/mercurial/keepalive.py
--- a/mercurial/keepalive.py
+++ b/mercurial/keepalive.py
@@ -172,8 +172,9 @@ 
             return dict(self._hostmap)
 
 class KeepAliveHandler(object):
-    def __init__(self):
+    def __init__(self, timeout=None):
         self._cm = ConnectionManager()
+        self._timeout = timeout
         self.requestscount = 0
         self.sentbytescount = 0
 
@@ -234,7 +235,7 @@ 
                 h = self._cm.get_ready_conn(host)
             else:
                 # no (working) free connections were found.  Create a new one.
-                h = http_class(host)
+                h = http_class(host, timeout=self._timeout)
                 if DEBUG:
                     DEBUG.info("creating new connection to %s (%d)",
                                host, id(h))
diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt
--- a/mercurial/help/config.txt
+++ b/mercurial/help/config.txt
@@ -1322,6 +1322,16 @@ 
     Optional. Always use the proxy, even for localhost and any entries
     in ``http_proxy.no``. (default: False)
 
+``http``
+----------
+
+Used to configure access to Mercurial repositories via HTTP.
+
+``timeout``
+    If set, blocking operations will timeout after that many seconds.
+    (default: None)
+
+
 ``merge``
 ---------
 
diff --git a/mercurial/configitems.py b/mercurial/configitems.py
--- a/mercurial/configitems.py
+++ b/mercurial/configitems.py
@@ -737,6 +737,11 @@ 
 coreconfigitem('http_proxy', 'user',
     default=None,
 )
+
+coreconfigitem('http', 'timeout',
+    default=None,
+)
+
 coreconfigitem('logtoprocess', 'commandexception',
     default=None,
 )