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 |