Ticket #4922: cookieagent_composed2.patch

File cookieagent_composed2.patch, 4.1 KB (added by gabrtv, 4 years ago)

composed, minus dependency on persistent connections

  • twisted/web/client.py

     
    11# -*- test-case-name: twisted.web.test.test_webclient -*- 
    22# Copyright (c) 2001-2010 Twisted Matrix Laboratories. 
    33# See LICENSE for details. 
     4import urllib2 
    45 
    56""" 
    67HTTP client. 
     
    848849                p.transport.loseConnection() 
    849850        self._protocolCache = {} 
    850851 
     852class CookieAgent(object): 
     853    """ 
     854    L{CookieAgent} extends the basic L{Agent} to add RFC-compliant 
     855    handling of HTTP cookies.  Cookies are written to and extracted 
     856    from a C{cookielib.CookieJar} instance. 
     857    """ 
     858    def __init__(self, agent, cookieJar, *args, **kwargs): 
     859        self._agent = agent 
     860        self.jar = cookieJar 
    851861 
     862    def request(self, method, uri, headers=None, bodyProducer=None): 
     863        """ 
     864        Issue a new request. 
     865 
     866        @param method: The request method to send. 
     867        @type method: C{str} 
     868 
     869        @param uri: The request URI send. 
     870        @type uri: C{str} 
     871 
     872        @param headers: The request headers to send.  If no I{Host} header is 
     873            included, one will be added based on the request URI. 
     874        @type headers: L{Headers} 
     875 
     876        @param bodyProducer: An object which will produce the request body or, 
     877            if the request body is to be empty, L{None}. 
     878        @type bodyProducer: L{IBodyProducer} provider 
     879 
     880        @return: A L{Deferred} which fires with the result of the request (a 
     881            L{Response} instance), or fails if there is a problem setting up a 
     882            connection over which to issue the request.  It may also fail with 
     883            L{SchemeNotSupported} if the scheme of the given URI is not 
     884            supported. 
     885        @rtype: L{Deferred} 
     886        """ 
     887        # setting cookie header explicitly will disable automatic request cookies 
     888        if not headers.hasHeader('cookie'): 
     889            last_req = self._urllib2Request(uri) 
     890            self.jar.add_cookie_header(last_req) 
     891            cookie_header = last_req.get_header('Cookie', None) 
     892            if cookie_header is not None: 
     893                headers.addRawHeader('cookie', cookie_header)         
     894        d = self._agent.request(method, uri, headers, bodyProducer) 
     895        d.addCallback(self._extractCookies, last_req) 
     896        return d 
     897     
     898    def _urllib2Request(self, uri): 
     899        """ 
     900        Given a URI, return a urllib2.Request instance for use with cookielib 
     901         
     902        @param uri: The request URI send. 
     903        @type uri: C{str} 
     904 
     905        @return: A C{urllib2.Request} instance for use with cookielib 
     906        @rtype: C{urllib2.Request} 
     907        """ 
     908        return urllib2.Request(uri) 
     909 
     910    def _extractCookies(self, response, request): 
     911        """ 
     912        Extract response cookies and store them in the cookie jar 
     913 
     914        @param response: A urllib2-style response object 
     915        @type uri: C{urllib.Response} 
     916 
     917        @param response: A urllib2-style response object 
     918        @type uri: C{urllib.Response} 
     919 
     920        @return: A L{Deferred} which fires with the result of the request (a 
     921            L{Response} instance), or fails if there is a problem setting up a 
     922            connection over which to issue the request.  It may also fail with 
     923            L{SchemeNotSupported} if the scheme of the given URI is not 
     924            supported. 
     925        @rtype: L{Deferred} 
     926        """ 
     927        # construct a urllib2-style response object 
     928        class _Response(object): 
     929            def info(self): 
     930                class _Meta(object): 
     931                    def getheaders(self, name): 
     932                        return response.headers.getRawHeaders(name.lower(), []) 
     933                return _Meta() 
     934        resp = _Response() 
     935        self.jar.extract_cookies(resp, request) 
     936        return response 
     937 
    852938__all__ = [ 
    853939    'PartialDownloadError', 
    854940    'HTTPPageGetter', 'HTTPPageDownloader', 'HTTPClientFactory', 'HTTPDownloader', 
    855941    'getPage', 'downloadPage', 
    856942 
    857     'ResponseDone', 'Response', 'Agent'] 
     943    'ResponseDone', 'Response', 'Agent', 'CookieAgent']