[Twisted-web] request.args empty when rendering PUT?

L. Daniel Burr ldanielburr at mac.com
Wed Mar 28 07:51:43 CST 2007

On Wed, 28 Mar 2007 07:24:00 -0500, Jarek Zgoda  
<jarek.zgoda at sensisoft.com> wrote:

> The code that produces failure:
> path = '/indexer'
> headers = {
>     'Content-Type': 'application/x-www-form-urlencoded',
>     'accept': 'text/plain',
> }
> docs = [{'field1': 'value1', 'field2': 'value2'}]
> params = urllib.urlencode({'items': pickle.dumps(docs)})
> http = httplib.HTTPConnection('localhost', 8080)
> try:
>     http.request('PUT', path, params, headers)
>     response = http.getresponse()
>     print response.reason
> finally:
>     http.close()
> The dictionary I get as request.args is empty.

My apologies, I was thinking about POST, not PUT.  request.args
will always be empty in the case of a PUT.  This is because
twisted.web.http.Request does the following:

- parse the querystring (note that your PUT has no querystring)
- if the request method is POST
   - parse the request body

Long story short, a PUT gets ignored when it comes to parsing
and populating request.args.  I've never run into this problem
because I don't PUT 'application/x-www-urelencoded' data, only
JSON or text/xml, which don't get handled as request.args anyway.

The solution is, in your render_PUT method, to do something like

 from twisted.web import http, resource

class MyResource(resource.Resource):
     allowedMethods = ('PUT',)
     isLeaf = True

     def render_PUT(self, request):
         parameters = http.parse_qs(request.content.read(), 1)
         # proceed using parameters instead of request.args

Obviously, this is a fairly trivial piece of code, but if you
feel strongly about this issue, please consider filing a ticket
on twistedmatrix.com, requesting that a PUT, with a Content-Type
of 'application/x-www/urlencoded' or 'multipart/form-data' be
parsed into request.args just as a POST would be.

Hope this helps,

L. Daniel Burr

More information about the Twisted-web mailing list