fastapi-httpbin icon indicating copy to clipboard operation
fastapi-httpbin copied to clipboard

Inconsistent Behavior Between fastapi-httpbin and httpbin in Handling urlencode Payload in POST Request

Open lmanc opened this issue 2 years ago • 1 comments
trafficstars

It appears that, unlike httpbin, fastapi-httpbin consistently interprets a urlencode payload in a POST request as JSON.

When a POST request is sent to httpbin, with the following command:

$ curl -v -d "birthyear=1905&press=%20OK%20" http://www.httpbin.org/post

curl automatically sets the Content-Type header to application/x-www-form-urlencoded, as its default behavior. httpbin responds with the following:

"form": {
    "birthyear": "1905",
    "press": " OK "
},
"json": null

However, if the Content-Type is specified as application/json:

$ curl -v -H "content-type: application/json" -d '{"birthyear": 1905, "press": " OK "}' http://www.httpbin.org/post

The response now includes a populated "json" field:

"json": {
    "birthyear": 1905,
    "press": " OK "
},

In contrast, it appears that fastapi-httpbin always expects JSON content, even when the Content-Type is set to application/x-www-form-urlencoded:

$ curl -v -d "birthyear=1905&press=%20OK%20" https://httpbin.dmuth.org/post

This request produces an error message in the "data" field:

"data": {
    "message": "No JSON/bad JSON supplied.  If you used Swagger, you'll need to use curl on the CLI with the -d option instead for non-GET methods, or GET-method data for GET."
}

If the Content-Type is set to application/json however, it works as expected:

$ curl -v -H "content-type: application/json" -d '{"birthyear": 1905, "press": " OK "}' https://httpbin.dmuth.org/post

The response from fastapi-httpbin then successfully populates the "data" field with the submitted form data:

"data": {
    "birthyear": 1905,
    "press": " OK "
}

I'm uncertain whether the observed behavior with content-type: application/x-www-form-urlencoded, which differs from httpbin, is an intended feature.

lmanc avatar Jul 04 '23 18:07 lmanc

Sorry for the delay, I was traveling! Now that I'm back home I was able to dig into this.

The issue is known behavior, but not desired behavior. The issue I ran into is that the original httpbin's /post endpoint just... reads all post data, regardless of variable. FastAPI, however, requires variables to be named in its function definitions, so when I first built this I was out of luck.

Or so I thought. :-)

With the benefit of several months having elapsed, I took another look at this, since it was brought up, and discovered that FastAPI has a request.body() function that behaves similar to request.json(), which I was already using. So I added in some support for that, wrote some tests, and "regular" form submissions should be parseable now. I will deploy shortly, and when https://httpbin.dmuth.org/version reports 0.0.47, you'll be good to try again.

Thanks,

-- Doug

dmuth avatar Jul 22 '23 21:07 dmuth