Skip to content

Instantly share code, notes, and snippets.

@gabrtv
Created March 3, 2011 06:03
Show Gist options
  • Save gabrtv/852407 to your computer and use it in GitHub Desktop.
Save gabrtv/852407 to your computer and use it in GitHub Desktop.
First pass at CookieLibAgent, extending t.w.c.Agent in branch #3420 (agent-persistent-connections)
class CookieLibAgent(Agent):
def __init__(self, cookieJar, *args, **kwargs):
Agent.__init__(self, reactor, *args, **kwargs)
self.jar = cookieJar
def request(self, method, uri, headers=None, bodyProducer=None):
"""
Issue a new request.
@param method: The request method to send.
@type method: C{str}
@param uri: The request URI send.
@type uri: C{str}
@param headers: The request headers to send. If no I{Host} header is
included, one will be added based on the request URI.
@type headers: L{Headers}
@param bodyProducer: An object which will produce the request body or,
if the request body is to be empty, L{None}.
@type bodyProducer: L{IBodyProducer} provider
@return: A L{Deferred} which fires with the result of the request (a
L{Response} instance), or fails if there is a problem setting up a
connection over which to issue the request. It may also fail with
L{SchemeNotSupported} if the scheme of the given URI is not
supported.
@rtype: L{Deferred}
"""
scheme, host, port, path = _parse(uri)
if headers is None:
headers = Headers()
if not headers.hasHeader('host'):
# This is a lot of copying. It might be nice if there were a bit
# less.
headers = Headers(dict(headers.getAllRawHeaders()))
headers.addRawHeader(
'host', self._computeHostValue(scheme, host, port))
# settings cookie header explicitly will disable cookie jar functionality
if not headers.hasHeader('cookie'):
# TODO: figure out how to pass last_req to extract cookies
# in a way that respects HTTP pipelining
self.last_req = self._urllib2Request(uri)
# construct urllib2 request to allow interfacing with cookielib cookiejar
self.jar.add_cookie_header(self.last_req)
cookie_header = self.last_req.get_header('Cookie', None)
if cookie_header is not None:
headers.addRawHeader('cookie', cookie_header)
if self.persistent:
sem = self._semaphores.get((scheme, host, port))
if sem is None:
sem = defer.DeferredSemaphore(self.maxConnections)
self._semaphores[scheme, host, port] = sem
d = sem.run(self._request, method, scheme, host, port, path,
headers, bodyProducer)
d.addCallback(self._extractCookies)
return d
else:
d = self._request(
method, scheme, host, port, path, headers, bodyProducer)
d.addCallback(self._extractCookies)
return d
def _urllib2Request(self, url):
return urllib2.Request(url)
def _extractCookies(self, response):
# mock urllib2 response object
class _Response(object):
def info(self):
class _Meta(object):
def getheaders(self, name):
return response.headers.getRawHeaders(name.lower(), [])
return _Meta()
# construct and deref the urllib2 request/response objects
req = self.last_req
resp = _Response()
self.jar.extract_cookies(resp, req)
return response
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment