10
from socket import error as SocketError, timeout as SocketTimeout
10
from socket import timeout as SocketTimeout
13
13
from http.client import HTTPConnection, HTTPException
14
14
from http.client import HTTP_PORT, HTTPS_PORT
15
15
except ImportError:
16
16
from httplib import HTTPConnection, HTTPException
17
17
from httplib import HTTP_PORT, HTTPS_PORT
20
20
from queue import LifoQueue, Empty, Full
21
21
except ImportError:
22
22
from Queue import LifoQueue, Empty, Full
25
try: # Compiled with SSL?
25
try: # Compiled with SSL?
26
26
HTTPSConnection = object
27
27
BaseSSLError = None
31
31
from http.client import HTTPSConnection
32
32
except ImportError:
33
33
from httplib import HTTPSConnection
207
208
conn = self.pool.get(block=self.block, timeout=timeout)
209
# If this is a persistent connection, check if it got disconnected
210
if conn and is_connection_dropped(conn):
211
log.info("Resetting dropped connection: %s" % self.host)
210
except AttributeError: # self.pool is None
211
raise ClosedPoolError(self, "Pool is closed.")
218
217
"connections are allowed.")
219
218
pass # Oh well, we'll create a new connection then
220
# If this is a persistent connection, check if it got disconnected
221
if conn and is_connection_dropped(conn):
222
log.info("Resetting dropped connection: %s" % self.host)
221
225
return conn or self._new_conn()
223
227
def _put_conn(self, conn):
228
232
Connection object for the current host and port as returned by
229
233
:meth:`._new_conn` or :meth:`._get_conn`.
231
If the pool is already full, the connection is discarded because we
232
exceeded maxsize. If connections are discarded frequently, then maxsize
235
If the pool is already full, the connection is closed and discarded
236
because we exceeded maxsize. If connections are discarded frequently,
237
then maxsize should be increased.
239
If the pool is closed, then the connection will be closed and discarded.
236
242
self.pool.put(conn, block=False)
243
return # Everything is dandy, done.
244
except AttributeError:
238
248
# This should never happen if self.block == True
239
249
log.warning("HttpConnectionPool is full, discarding connection: %s"
252
# Connection never got put back into the pool, close it.
242
255
def _make_request(self, conn, method, url, timeout=_Default,
243
256
**httplib_request_kw):
259
272
sock.settimeout(timeout)
261
httplib_response = conn.getresponse()
263
log.debug("\"%s %s %s\" %s %s" %
265
conn._http_vsn_str, # pylint: disable-msg=W0212
266
httplib_response.status, httplib_response.length))
274
try: # Python 2.7+, use buffering of HTTP responses
275
httplib_response = conn.getresponse(buffering=True)
276
except TypeError: # Python 2.6 and older
277
httplib_response = conn.getresponse()
279
# AppEngine doesn't have a version attr.
280
http_version = getattr(conn, '_http_vsn_str', 'HTTP/?')
281
log.debug("\"%s %s %s\" %s %s" % (method, url, http_version,
282
httplib_response.status,
283
httplib_response.length))
268
284
return httplib_response
288
Close all pooled connections and disable the pool.
290
# Disable access to the pool
291
old_pool, self.pool = self.pool, None
295
conn = old_pool.get(block=False)
271
302
def is_same_host(self, url):
273
304
Check if the given ``url`` is a member of the same host as this
307
if url.startswith('/'):
276
310
# TODO: Add optional support for socket.gethostbyname checking.
277
311
scheme, host, port = get_host(url)
280
314
# Use explicit default port for comparison when none is given.
281
315
port = port_by_scheme.get(scheme)
283
return (url.startswith('/') or
284
(scheme, host, port) == (self.scheme, self.host, self.port))
317
return (scheme, host, port) == (self.scheme, self.host, self.port)
286
319
def urlopen(self, method, url, body=None, headers=None, retries=3,
287
320
redirect=True, assert_same_host=True, timeout=_Default,
320
353
Number of retries to allow before raising a MaxRetryError exception.
323
Automatically handle redirects (status codes 301, 302, 303, 307),
324
each redirect counts as a retry.
356
If True, automatically handle redirects (status codes 301, 302,
357
303, 307). Each redirect counts as a retry.
326
359
:param assert_same_host:
327
360
If ``True``, will make sure that the host of the pool requests is
418
450
raise SSLError(e)
420
except (HTTPException, SocketError) as e:
452
except HTTPException as e:
421
453
# Connection broken, discard. It will be replaced next _get_conn().
423
455
# This is necessary so we can access e below
427
if conn and release_conn:
428
# Put the connection back to be reused
460
# Put the connection back to be reused. If the connection is
461
# expired then it will be None, which will get replaced with a
462
# fresh connection during _get_conn.
429
463
self._put_conn(conn)
432
467
log.warn("Retrying (%d attempts remain) after connection "
433
468
"broken by '%r': %s" % (retries, err, url))
434
469
return self.urlopen(method, url, body, headers, retries - 1,
435
redirect, assert_same_host) # Try again
470
redirect, assert_same_host,
471
timeout=timeout, pool_timeout=pool_timeout,
472
release_conn=release_conn, **response_kw)
437
474
# Handle redirect?
438
475
redirect_location = redirect and response.get_redirect_location()
439
476
if redirect_location:
477
if response.status == 303:
440
479
log.info("Redirecting %s -> %s" % (url, redirect_location))
441
480
return self.urlopen(method, redirect_location, body, headers,
442
retries - 1, redirect, assert_same_host)
481
retries - 1, redirect, assert_same_host,
482
timeout=timeout, pool_timeout=pool_timeout,
483
release_conn=release_conn, **response_kw)