Issue #790 resolved

[PATCH] Request body of PUT with no Content-Type is parsed incorrectly

Anonymous created an issue

When CP3 receives a request (such as a PUT) containing an entity body, but without a Content-Type header, it still tries to parse the entity body to pull out params. This results in the controller method being called with a nonsensical set of keyword args.

CP2 didn't do this, because _cpwsgiserver.HTTPRequest.parse_request would always create a Content-Type header with an empty value if the client left that header out.

CP3 should behave the same as CP2, which is to not attempt to parse the request body unless the Content-Type is "application/x-www-form-urlencoded" or multipart.

The attached patch changes CP3 to behave this way (includes updated unit tests).

Also see the thread at http://groups.google.com/group/cherrypy-devel/browse_thread/thread/9db04c18725dcf3c

Reported by miles.chris@gmail.com

Comments (10)

  1. Robert Brewer

    +1 on the ticket needing fixed, but -1 on the patch. No code should modify request.headers; it's important that applications have access to the actual header values sent (or not sent) in the HTTP request. Better to fake out just the body parser than the entire stack.

  2. Anonymous

    Fair call. Attached is a new patch (cp3_no_content_type2.patch) that passes a modified (if necessary) copy of the headers to !FieldStorage, ensuring that a "Content-Type" header is included. This ensures that !FieldStorage doesn't attempt to parse the request body if the client didn't supply a "Content-Type" header, but leaves the actual request header values untouched outside of this section.

    No unit tests needed to be updated to support this patch.

  3. Anonymous

    It doesn't work because self.headers.copy() returns a dict rather than another !HeaderMap object. That's why I had to make the copy using h = http.HeaderMap(self.headers.items()).

    An alternative fix would be to overload the copy method of !HeaderMap to return a copy of itself properly.

  4. Robert Brewer

    Ah. Now I remember, cgi.Fieldstorage expects all lowercase header keys. HeaderMap works around that by overriding __contains__ etc to title-case the search key.

    Sheesh.

  5. Log in to comment