I'm porting a CP2 app to CP3 (3.1.0beta3) and have an issue with CP3
Request.process_body() attempting to parse params from the request
body of a PUT request with no "Content-Type" header defined, which
wasn't how CP2 behaved in the same situation.
Given this super simple CP3 test app:
{{{
import cherrypy
class Root(object):
@cherrypy.expose
def upload(self):
return "Upload OK"
cherrypy.quickstart(Root())
}}}
If I create a PUT request to /upload, with no "Content-Type" header
defined, then CP3 attempts to parse the request body (which, in my
case, contains binary data, but that doesn't matter) into params, and
the request fails because the params cannot be mapped to method
arguments (which you can examine by defining upload(self, *args,
**kwargs)) which is not what would be expected. Compare this with the
same app running under CP2 and the request body is not parsed.
If I create a PUT request with any "Content-Type" (besides
"application/x-www-form-urlencoded" and similar) then the request
works properly (CP3 doesn't attempt to parse the request body).
If I create a PUT request with "Content-Type: application/x-www-form-
urlencoded" then CP3 does attempt to parse the request body (as I
would expect).
Here's some examples of the above behaviour using curl (error
responses truncated):
{{{
$ curl --upload-file ~/tmp/foo.tmp
http://localhost:8080/upload
TypeError: upload() got an unexpected keyword argument 'test file.
# (works with CP2)
$ curl --header "Content-Type: foo/bar" --upload-file ~/tmp/foo.tmp
http://localhost:8080/upload
Upload OK
$ curl --header "Content-Type: application/x-www-form-urlencoded" --
upload-file ~/tmp/foo.tmp
http://localhost:8080/upload
TypeError: upload() got an unexpected keyword argument 'test file.
}}}
I'd like to see the behaviour changed back to only attempting to parse
the request body if a valid form-like "Content-Type" (like
"application/x-www-form-urlencoded") is supplied, for a few reasons:
1. Request.body_params__doc (and Request.body__doc) indicate that this
is how it should behave, i.e. body_params: "If the request Content-
Type is 'application/x-www-form-urlencoded' or multipart, this will be
a dict of the params pulled from the entity body"; and body: "If the
request Content-Type is 'application/x-www-form-urlencoded' or
multipart, this will be None. Otherwise, this will contain the request
entity body as a string"
2. The request body should be left alone unless the Content-Type
indicates that it contains encoded parameters or multipart data.
3. This is how it worked in CP2.
In the case of my application, I don't want to force my users to
supply a Content-Type with their PUT request, when they didn't need to
before (doing so is optional).
If this is reasonable, I'm happy to create a ticket (and possibly a
patch) for CP3.
Cheers,
Chris Miles