def urlopen(self, method, url, body=None, headers=None, retries=3,
redirect=True, assert_same_host=True, pool_timeout=None,
- **response_kw):
+ release_conn=None, **response_kw):
"""
Get a connection from the pool and perform an HTTP request.
block for ``pool_timeout`` seconds and raise EmptyPoolError if no
connection is available within the time period.
+ release_conn
+ If False, then the urlopen call will not release the connection
+ back into the pool once a response is received. This is useful if
+ you're not preloading the response's content immediately. You will
+ need to call ``r.release_conn()`` on the response ``r`` to return
+ the connection back into the pool. If None, it takes the value of
+ ``response_kw.get('preload_content', True)``.
+
Additional parameters are passed to
``HTTPResponse.from_httplib(r, **response_kw)``
"""
if retries < 0:
raise MaxRetryError("Max retries exceeded for url: %s" % url)
+ if release_conn is None:
+ release_conn = response_kw.get('preload_content', True)
+
# Check host
if assert_same_host and not self.is_same_host(url):
host = "%s://%s" % (self.scheme, self.host)
raise HostChangedError("Connection pool with host '%s' tried to "
"open a foreign host: %s" % (host, url))
- try:
- # Request a connection from the queue
- conn = self._get_conn(timeout=pool_timeout)
+ # Request a connection from the queue
+ conn = self._get_conn(timeout=pool_timeout)
+ try:
# Make the request on the httplib connection object
httplib_response = self._make_request(conn, method, url,
body=body, headers=headers)
-
# Import httplib's response into our own wrapper object
response = HTTPResponse.from_httplib(httplib_response,
pool=self,
raise SSLError(e)
except (HTTPException, SocketError), e:
+ # Connection broken, discard. It will be replaced next _get_conn().
+ conn = None
+
+ finally:
+ if release_conn:
+ # Put the connection back to be reused
+ self._put_conn(conn)
+
+ if not conn:
log.warn("Retrying (%d attempts remain) after connection "
"broken by '%r': %s" % (retries, e, url))
return self.urlopen(method, url, body, headers, retries - 1,
}
def __init__(self, body='', headers=None, status=0, version=0, reason=None,
- strict=0, preload_content=False, decode_content=True,
+ strict=0, preload_content=True, decode_content=True,
original_response=None, pool=None, connection=None):
self.headers = headers or {}
self.status = status