Ticket #4519: twisted-web-request-args.patch

File twisted-web-request-args.patch, 6.6 KB (added by jamesh, 4 years ago)

twisted-web-request-args.patch

  • twisted/web/http.py

    # Bazaar merge directive format 2 (Bazaar 0.90)
    # revision_id: james@jamesh.id.au-20100625152527-euuvx1hdyfhtq940
    # target_branch: bzr+ssh://bazaar.launchpad.net/~twisted-\
    #   dev/twisted/trunk/
    # testament_sha1: 1d0f101861fcf22a3614667211f3f704f0e34b59
    # timestamp: 2010-06-25 23:27:37 +0800
    # base_revision_id: svn-v4:bbbe8e31-12d6-0310-92fd-\
    #   ac37d47ddeeb:trunk:29351
    # 
    # Begin patch
    === modified file 'twisted/web/http.py'
     
    597597    sentLength = 0 # content-length of response, or total bytes sent via chunking 
    598598    etag = None 
    599599    lastModified = None 
    600     args = None 
     600    _args = None 
    601601    path = None 
    602602    content = None 
    603603    _forceSSL = 0 
     
    759759        @param version: The HTTP version of this request. 
    760760        """ 
    761761        self.content.seek(0,0) 
    762         self.args = {} 
    763762        self.stack = [] 
    764763 
    765764        self.method, self.uri = command, path 
     
    770769            self.path = self.uri 
    771770        else: 
    772771            self.path, argstring = x 
    773             self.args = parse_qs(argstring, 1) 
    774772 
    775773        # cache the client and server information, we'll need this later to be 
    776774        # serialized and sent with the request so CGIs will work remotely 
    777775        self.client = self.channel.transport.getPeer() 
    778776        self.host = self.channel.transport.getHost() 
    779777 
    780         # Argument processing 
    781         args = self.args 
     778        self.process() 
     779 
     780    def args(self): 
     781        if self._args is not None: 
     782            return self._args 
     783 
     784        # Parse query string arguments 
     785        x = self.uri.split('?', 1) 
     786        if len(x) != 1: 
     787            self._args = parse_qs(x[1], 1) 
     788        else: 
     789            self._args = {} 
     790 
     791        # Parse post body arguments 
     792        args = self._args 
    782793        ctype = self.requestHeaders.getRawHeaders('content-type') 
    783794        if ctype is not None: 
    784795            ctype = ctype[0] 
     
    803814                        return 
    804815                    raise 
    805816            self.content.seek(0, 0) 
    806  
    807         self.process() 
    808  
     817        return args 
     818    args = property(args) 
    809819 
    810820    def __repr__(self): 
    811821        return '<%s %s %s>'% (self.method, self.uri, self.clientproto) 
  • twisted/web/test/test_http.py

    === modified file 'twisted/web/test/test_http.py'
     
    826826 
    827827        self.runRequest(httpRequest, MyRequest) 
    828828 
     829    def test_formNotParsedUntilArgsAccessed(self): 
     830        """The post body is not parsed until request.args is accessed.""" 
     831        query = 'key=value' 
     832        httpRequest = '''\ 
     833POST / HTTP/1.0 
     834Content-Length: %d 
     835Content-Type: application/x-www-form-urlencoded 
     836 
     837%s''' % (len(query), query) 
     838 
     839        testcase = self 
     840        self.parse_qs_calls = [] 
     841        orig_parse_qs = http.parse_qs 
     842        def parse_qs(query_string, *args): 
     843            testcase.parse_qs_calls.append(query_string) 
     844            return orig_parse_qs(query_string, *args) 
     845        self.patch(http, 'parse_qs', parse_qs) 
     846        class MyRequest(http.Request): 
     847            def process(self): 
     848                testcase.assertEquals(self.method, "POST") 
     849                # Arguments have not been parsed: 
     850                testcase.assertEquals(testcase.parse_qs_calls, []) 
     851                # But have been after first access to self.args: 
     852                testcase.assertEquals(self.args["key"], ["value"]) 
     853                testcase.assertEquals(testcase.parse_qs_calls, [query]) 
     854 
     855                # Reading from the content file-like must produce the entire 
     856                # request body. 
     857                testcase.assertEquals(self.content.read(), query) 
     858                testcase.didRequest = 1 
     859                self.finish() 
     860 
     861        self.runRequest(httpRequest, MyRequest) 
     862 
    829863    def testMissingContentDisposition(self): 
    830864        req = '''\ 
    831865POST / HTTP/1.0