Falcon: No data in req.stream.read()

Created on 23 Mar 2015  路  14Comments  路  Source: falconry/falcon

I've modified the introduction example (things.py) to handle a POST request, and called it with curl.
I've started my gunicorn server with:
gunicorn things:app
And make a POST with curl:
curl localhost -d "Test data" or
curl localhost --data-urlencoded "Test data"

But req.stream.read() is always empty.
It's very strange because it was working properly and this (no data received) happened after i formatted my pc and reinstalled ubuntu 14.04.02.

Am I forgetting somenthing?

import falcon

class ThingsResource:
def on_get(self, req, resp):
"""Handles POST requests"""
req_body = req.stream.read()
print req_body
resp.status = falcon.HTTP_200 # This is the default status
resp.body = ('\nTwo things awe me most, the starry sky '
'above me and the moral law within me.\n'
'\n'
' ~ Immanuel Kant\n\n')

app = falcon.API()

things = ThingsResource()

app.add_route('/things', things)

documentation duplicate

Most helpful comment

This feature had better be switchable, off by default. I ran into this and it's fairly confusing.

All 14 comments

You can check these things:

  • In you code, you're acting on the "on_get" instead of "on_post". The "on_get" won't read anything that is not a GET request.
  • Can you try curl with -X POST 'datastring" instead of -d? -d is sending binary data

If nothing of this works tell me if there's any error message

I've used on_post, and the method is being executed because I've put other prints and them are being printed.

I've tried curl with -X POST --data-urlencoded and a lot of variations.

My big problem is that no error are fired, simply the data are empty. There's nothing on req.stream.read()

Is ther a way to debug and see what's inside req object or see the bytes curl are sending?

Have you taken a look to params(), get_param() and query_string() ?

According to the falcon documentation:

If an HTML form is POSTed to the API using the application/x-www-form-urlencoded media
type, Falcon will consume stream in order to parse the parameters and merge them into the
query string parameters. In this case, the stream will be left at EOF.

That means if the form is sent as HTML form, the stream will be empty and the query strings will be populated with the values, according to the standard.

This feature had better be switchable, off by default. I ran into this and it's fairly confusing.

Thanks ocarcp,

I was able to acces the data throught get_param().

I think was using a older version of falcon, in the last version (which I thinks was released on february, 6) this behavior changed and caused this confusion.

Yeah I know, the documentation is ahead of the current version available in pip. I had troubles too. Maybe @kgriffs can sync it up :)

@lichray tons of things are confusing on the request because falcon follows the standard completely and sometimes it doesn't make sense if you come from other fully fledged frameworks. But that's part of falcon's beauty, its fully standard :)

If by satisfying form submission standard you violated WSGI standard then you should give user a switch.

I didn't mean it was in direct violation but according to the WSGI spec:

Currently environ['wsgi.input'] points to a stream that represents the
body of the HTTP request. Once this stream has been read, it cannot
necessarily be read again.

So it's up to the implementation of the framework to choose how to process the data. In the django framework for example the HttpRequest object does the same, the only difference is that it makes it transparent for the user so you have everything available through HttpRequest.request

I don't disagree in the switch though, I never had a use case where I needed it, so I can't tell :)

Flagging this for documentation to provide clarity on how Falcon handles the incoming stream, how to parse it directly, and a few different approaches to buffering the data if that is required by the app.

Note: As of 1.0.0 form data is no longer automatically parsed by default.

http://falcon.readthedocs.io/en/stable/api/api.html#RequestOptions.auto_parse_form_urlencoded

Also note that we are working on a new interface for forms. Happy to get your feedback on these issues:

418

953

Closing this issue as

  • As of Falcon 2.0+, I don't think we are reading anything behind user's back by default
  • The documentation issue still remains to better clarify how Falcon is dealing with input streams, but let's handle that as part of https://github.com/falconry/falcon/issues/417
Was this page helpful?
0 / 5 - 0 ratings