Closed sgrif closed 7 years ago
That seems like the right thing to do. Slating for 0.2.
As a side note, the docs also state that a 400 gets emitted if it fails to parse the form. https://rocket.rs/guide/requests/#forms
This would need to be updated if #103 is merged
Actually, 400 (Bad Request) is the correct code to emit if the request cannot be parsed. 422 (Unprocessable Entity) on the other hand means, "The request data you gave is syntactically valid, but it doesn't fit the constraints for this route."
To clarify further because why not. 400
should be returned if the request body isn't JSON, XML, etc. Any other considerations (eg. an int vs a string or a parametric validation) should be 422
.
Alright! This is one of two remaining issues for 0.2!
So, looking at the RFC, section 8.2.1, we should return a 400
when any of the following occurs:
=
at all or has no =
after an &
.The first one is pretty easy to detect but requires a change to the FormItems
iterator. The second one means we have to check every string for spaces, which we can do efficiently if we change the FormItems
decorator again. The last one...seems expensive, and I don't really know what the point of it is besides being able to send it in the URL.
Would be good to know what other frameworks do here. My intuition is that we should just check for 1 and ignore 2 and 3. This can be done by simply adding a method to the FormItems
structure to see if there is any remaining, unparsed text. But even then: should Rocket just let this fly?
It's not clear to me what the correct approach is here.
[Copied this from #103]
I'm partial to just doing [1]. That's a simple parse failure.
I can't find the source, but I remember reading a quote (similar) to the following in a RFC (probably the HTML one).
Accept as much variation as feasible but return exactly 1 result.
I'd argue that while doing [2] and [3] are very cheap performance-wise (just a simple character rejection with a blacklist of only 7 characters) it feels like being overly strict. What happens if there exists a browser that decides it wants to send spaces? It's not ambiguous to accept spaces so I don't see a problem. I could see a warning log though.
What happens if there exists a browser that decides it wants to send spaces? It's not ambiguous to accept spaces so I don't see a problem. I could see a warning log though.
The short answer is that if the browser sends spaces, it is not in compliance with the RFC.
Consistent behavior globally is really valuable. Feature matrix hell is not fun.
Personally I caution against doing things that are technically possible without a substantial and valuable use case. The smaller the set of rules that describe the system, the easier it is for my limited human brain to reason about. Unnecessary complexity saps productivity like one would not believe.
If deserializing the response data into a struct using
FromForm
fails, Rocket by default will return400 BAD REQUEST
, regardless of the reason that deserialization failed. This is the incorrect response code, unless deserialization failed due to malformed JSON. It is clearly defined in RFC 2616 as "The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications.". For failures due to missing fields, unrecognized fields, fields of the wrong type, or pretty much any failure that isn't the result of the body being syntactically incorrect for the declared content-type,422 UNPROCESSABLE ENTITY
should be used instead.