Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

req.params is empty when incoming HTTP POST data has a field longer than 256 bytes. #2136

Closed
justinvirtualitics opened this issue Jan 1, 2023 · 5 comments

Comments

@justinvirtualitics
Copy link

justinvirtualitics commented Jan 1, 2023

Setup a simple API, as follows with Falcon 3.1.1:

class MyApi(object):
    def on_post(self, req, resp):
        form = req.params
        # do stuff with the form data...

app = falcon.App()
app.req_options.auto_parse_form_urlencoded = True
app.add_route('/myapi', MyApi())

Call the API from a C# app using BestHTTP/2.

HTTPRequest request = new HTTPRequest(new Uri(MyApiUri), HTTPMethods.Post, MyApiResponseCallback);
string a1= "somevalue";
string a2 = "someothervalue";
string a3 = "somethirdvalue";
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddField("a1", a1);
request.AddField("a2", a2);
request.AddField("a3", a3);
request.ConnectTimeout = new TimeSpan(0, 0, 10);
request.Timeout = new TimeSpan(0, 0, 10);
request.Send();

The above works perfectly as long as the strings aren't too large.
A simple test case:

  • a2 and a3 values remain constant between tests, while a1 changes between a shorter string and a longer string.
  • When a1 is long enough (>256 bytes), the API no longer extracts form data from req.params.

I have not found any information about a limit the 100s of bytes for a given field in a POST request like this, and I have reason to believe that this issue is on the Falcon side. I have been able to extract the values (not keys) from req.media and confirmed that the data in question has arrived at the server, but fails to be read through the request params method wrapper.

Any help would be greatly appreciated.

@justinvirtualitics justinvirtualitics changed the title req.params is empty when incoming HTTP POST data has a long enough field. req.params is empty when incoming HTTP POST data has a field longer than 256 bytes. Jan 1, 2023
@justinvirtualitics
Copy link
Author

A possible fix on the C#/BestHTTP side:

request.FormUsage = BestHTTP.Forms.HTTPFormUsage.UrlEncoded;

It seems that the 256 byte threshold was triggering the default "Automatic" Form Usage setting, which apparently switched it to Multipart instead of UrlEncoded as the server was expecting.

@CaselIT
Copy link
Member

CaselIT commented Jan 1, 2023

Hi,

I don't think there is any kind of limit on the falcon side regarding the size of the form body.
Can you confirm in the on_post that the content type is x-www-form-urlencoded in all cases, even when params is empty?

Maybe you can switch to multipart in all cases and use the falcon api to handle that: https://falcon.readthedocs.io/en/stable/api/multipart.html

@justinvirtualitics
Copy link
Author

Thanks for the response @CaselIT .

Upon closer investigation, the content type on the falcon side was appearing as changed (to multipart) in that case, I just hadn't noticed it before. So overall it does appear that the issue was on the C#/BestHTTP side specific to my usage, and not a problem with Falcon.

Switching the api to multipart in all cases on the Falcon side is something I may try later, but for now, I have this working as intended.

Thanks again, closing this issue now.

@CaselIT
Copy link
Member

CaselIT commented Jan 2, 2023

Great, thanks for reporting back

@vytas7
Copy link
Member

vytas7 commented Jan 6, 2023

Just adding to @CaselIT's answer, as of Falcon 3+, it is recommended to use req.media to handle even URL-encoded forms, i.e. form = req.params becomes form = req.get_media() (auto_parse_form_urlencoded is now deprecated).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants