mercurial/keepalive.py
changeset 30487 88a448a12ae8
parent 30473 39d13b8c101d
child 30686 8352c42a0a0d
equal deleted inserted replaced
30486:d6f3877b72c7 30487:88a448a12ae8
    76 
    76 
    77   Unfortunately, these are ONLY there if status == 200, so it's not
    77   Unfortunately, these are ONLY there if status == 200, so it's not
    78   easy to distinguish between non-200 responses.  The reason is that
    78   easy to distinguish between non-200 responses.  The reason is that
    79   urllib2 tries to do clever things with error codes 301, 302, 401,
    79   urllib2 tries to do clever things with error codes 301, 302, 401,
    80   and 407, and it wraps the object upon return.
    80   and 407, and it wraps the object upon return.
    81 
       
    82   For python versions earlier than 2.4, you can avoid this fancy error
       
    83   handling by setting the module-level global HANDLE_ERRORS to zero.
       
    84   You see, prior to 2.4, it's the HTTP Handler's job to determine what
       
    85   to handle specially, and what to just pass up.  HANDLE_ERRORS == 0
       
    86   means "pass everything up".  In python 2.4, however, this job no
       
    87   longer belongs to the HTTP Handler and is now done by a NEW handler,
       
    88   HTTPErrorProcessor.  Here's the bottom line:
       
    89 
       
    90     python version < 2.4
       
    91         HANDLE_ERRORS == 1  (default) pass up 200, treat the rest as
       
    92                             errors
       
    93         HANDLE_ERRORS == 0  pass everything up, error processing is
       
    94                             left to the calling code
       
    95     python version >= 2.4
       
    96         HANDLE_ERRORS == 1  pass up 200, treat the rest as errors
       
    97         HANDLE_ERRORS == 0  (default) pass everything up, let the
       
    98                             other handlers (specifically,
       
    99                             HTTPErrorProcessor) decide what to do
       
   100 
       
   101   In practice, setting the variable either way makes little difference
       
   102   in python 2.4, so for the most consistent behavior across versions,
       
   103   you probably just want to use the defaults, which will give you
       
   104   exceptions on errors.
       
   105 
       
   106 """
    81 """
   107 
    82 
   108 # $Id: keepalive.py,v 1.14 2006/04/04 21:00:32 mstenner Exp $
    83 # $Id: keepalive.py,v 1.14 2006/04/04 21:00:32 mstenner Exp $
   109 
    84 
   110 from __future__ import absolute_import, print_function
    85 from __future__ import absolute_import, print_function
   122 httplib = util.httplib
    97 httplib = util.httplib
   123 urlerr = util.urlerr
    98 urlerr = util.urlerr
   124 urlreq = util.urlreq
    99 urlreq = util.urlreq
   125 
   100 
   126 DEBUG = None
   101 DEBUG = None
   127 
       
   128 if sys.version_info < (2, 4):
       
   129     HANDLE_ERRORS = 1
       
   130 else: HANDLE_ERRORS = 0
       
   131 
   102 
   132 class ConnectionManager(object):
   103 class ConnectionManager(object):
   133     """
   104     """
   134     The connection manager must be able to:
   105     The connection manager must be able to:
   135       * keep track of all existing
   106       * keep track of all existing
   275         r._connection = h
   246         r._connection = h
   276         r.code = r.status
   247         r.code = r.status
   277         r.headers = r.msg
   248         r.headers = r.msg
   278         r.msg = r.reason
   249         r.msg = r.reason
   279 
   250 
   280         if r.status == 200 or not HANDLE_ERRORS:
   251         return r
   281             return r
       
   282         else:
       
   283             return self.parent.error('http', req, r,
       
   284                                      r.status, r.msg, r.headers)
       
   285 
   252 
   286     def _reuse_connection(self, h, req, host):
   253     def _reuse_connection(self, h, req, host):
   287         """start the transaction with a re-used connection
   254         """start the transaction with a re-used connection
   288         return a response object (r) upon success or None on failure.
   255         return a response object (r) upon success or None on failure.
   289         This DOES not close or remove bad connections in cases where
   256         This DOES not close or remove bad connections in cases where
   593 
   560 
   594 #########################################################################
   561 #########################################################################
   595 #####   TEST FUNCTIONS
   562 #####   TEST FUNCTIONS
   596 #########################################################################
   563 #########################################################################
   597 
   564 
   598 def error_handler(url):
       
   599     global HANDLE_ERRORS
       
   600     orig = HANDLE_ERRORS
       
   601     keepalive_handler = HTTPHandler()
       
   602     opener = urlreq.buildopener(keepalive_handler)
       
   603     urlreq.installopener(opener)
       
   604     pos = {0: 'off', 1: 'on'}
       
   605     for i in (0, 1):
       
   606         print("  fancy error handling %s (HANDLE_ERRORS = %i)" % (pos[i], i))
       
   607         HANDLE_ERRORS = i
       
   608         try:
       
   609             fo = urlreq.urlopen(url)
       
   610             fo.read()
       
   611             fo.close()
       
   612             try:
       
   613                 status, reason = fo.status, fo.reason
       
   614             except AttributeError:
       
   615                 status, reason = None, None
       
   616         except IOError as e:
       
   617             print("  EXCEPTION: %s" % e)
       
   618             raise
       
   619         else:
       
   620             print("  status = %s, reason = %s" % (status, reason))
       
   621     HANDLE_ERRORS = orig
       
   622     hosts = keepalive_handler.open_connections()
       
   623     print("open connections:", hosts)
       
   624     keepalive_handler.close_all()
       
   625 
   565 
   626 def continuity(url):
   566 def continuity(url):
   627     md5 = hashlib.md5
   567     md5 = hashlib.md5
   628     format = '%25s: %s'
   568     format = '%25s: %s'
   629 
   569 
   730 
   670 
   731     DEBUG = dbbackup
   671     DEBUG = dbbackup
   732 
   672 
   733 
   673 
   734 def test(url, N=10):
   674 def test(url, N=10):
   735     print("checking error handler (do this on a non-200)")
       
   736     try: error_handler(url)
       
   737     except IOError:
       
   738         print("exiting - exception will prevent further tests")
       
   739         sys.exit()
       
   740     print('')
       
   741     print("performing continuity test (making sure stuff isn't corrupted)")
   675     print("performing continuity test (making sure stuff isn't corrupted)")
   742     continuity(url)
   676     continuity(url)
   743     print('')
   677     print('')
   744     print("performing speed comparison")
   678     print("performing speed comparison")
   745     comp(N, url)
   679     comp(N, url)