I've tracked the issue down to few interactions between paste.parse_formvars
used by paste.WSGIRequest and paste.cascade. Moving the discussion to paste-users
When req.POST is called the first time, the post data is parsed and paste adds
paste.parsed_formvars to the environ which is a tuple of a MultiDict() and a
reference to the source which was parsed.
paste.cascade then copies wsgi.input into a temp file or a StringIO object.
However, it's too late to copy it at this point because the fileobject has
already been read completely and doesn't support seek.
When req.POST is called next, it finds the paste.parsed_formvars entry in the
environ but the sources are different. The original source was a
socket._fileobject but is now the copied object from paste.cascase (either a
tempfile or a StringIO object). As a result, the post data is parsed a second
time but there is no content to be read and voila, the post MultiDict is empty.
I have a couple of solutions in mind. The simplest is to use WebOb in my
middleware which handles the post body more gracefully. The second is to copy
the wsgi.input into a buffer in my middleware before handing it off to
paste.WSGIRequest. The last choice is to make paste.WSGIRequest responsible for
copying the wsgi.input into a tempfile or a StringIO object which will allow seeks.
I don't know the state of paste.WSGIRequest -- if it's still supported or not.
If not, it might be best to just use WebOb over WSGIRequest.
- Shailesh