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

File twisted-web-request-args.patch, 6.6 KB (added by jamesh, 6 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