HTTP 400 (bad request) for logical error, not malf

2019-01-10 08:23发布

问题:

The HTTP/1.1 specification (RFC 2616) has the following to say on the meaning of status code 400, Bad Request (§10.4.1):

The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications.

There seems to be a general practice among a few HTTP-based APIs these days to use 400 to mean a logical rather than a syntax error with a request. My guess is that APIs are doing this to distinguish between 400 (client-induced) and 500 (server-induced). Is it acceptable or incorrect to use 400 to indicate non-syntactic errors? If it is acceptable, is there an annotated reference on RFC 2616 that provides more insight into the intended use of 400?

Examples:

  • Google Data Protocol, Protocol Reference, HTTP Status Codes

回答1:

Status 422 (RFC 4918, Section 11.2) comes to mind:

The 422 (Unprocessable Entity) status code means the server understands the content type of the request entity (hence a 415(Unsupported Media Type) status code is inappropriate), and the syntax of the request entity is correct (thus a 400 (Bad Request) status code is inappropriate) but was unable to process the contained instructions. For example, this error condition may occur if an XML request body contains well-formed (i.e., syntactically correct), but semantically erroneous, XML instructions.



回答2:

As of this time, the latest draft of the HTTPbis specification, which is intended to replace and make RFC 2616 obsolete, states:

The 400 (Bad Request) status code indicates that the server cannot or will not process the request because the received syntax is invalid, nonsensical, or exceeds some limitation on what the server is willing to process.

This definition, while of course still subject to change, ratifies the widely used practice of responding to logical errors with a 400.



回答3:

HTTPbis will address the phrasing of 400 Bad Request so that it covers logical errors as well. So 400 will incorporate 422.

From https://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-18#section-7.4.1
"The server cannot or will not process the request, due to a client error (e.g., malformed syntax)"



回答4:

Even though, I have been using 400 to represent logical errors also, I have to say that returning 400 is wrong in this case because of the way the spec reads. Here is why i think so, the logical error could be that a relationship with another entity was failing or not satisfied and making changes to the other entity could cause the same exact to pass later. Like trying to (completely hypothetical) add an employee as a member of a department when that employee does not exist (logical error). Adding employee as member request could fail because employee does not exist. But the same exact request could pass after the employee has been added to the system.

Just my 2 cents ... We need lawyers & judges to interpret the language in the RFC these days :)

Thank You, Vish



回答5:

It could be argued that having incorrect data in your request is a syntax error, even if your actual request at the HTTP level (request line, headers etc) is syntactically valid.

For example, if a Restful web service is documented as accepting POSTs with a custom XML Content Type of application/vnd.example.com.widget+xml, and you instead send some gibberish plain text or a binary file, it seems resasonable to treat that as a syntax error - your request body is not in the expected form.

I don't know of any official references to back this up though, as usual it seems to be down to interpreting RFC 2616.

Update: Note the revised wording in RFC 7231 §6.5.1:

The 400 (Bad Request) status code indicates that the server cannot or will not process the request due to something that is perceived to be a client error e.g., malformed request syntax, invalid request message framing, or deceptive request routing).

seems to support this argument more than the now obsoleted RFC 2616 §10.4.1 which said just:

The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications.



回答6:

On Java EE servers a 400 is returned if your URL refers to a non-existent "web -application". Is that a "syntax error"? Depends on what you mean by syntax error. I would say yes.

In English syntax rules prescribe certain relationships between parts of speech. For instance "Bob marries Mary" is syntactically correct, because it follows the pattern {Noun + Verb + Noun}. Whereas "Bob marriage Mary" would be syntactically incorrect, {Noun + Noun + Noun}.

The syntax of a simple URLis { protocol + : + // + server + : + port }. According to this "http://www.google.com:80" is syntactically correct.

But what about "abc://www.google.com:80"? It seems to follow the exact same pattern. But really it is a syntax error. Why? Because 'abc' is not a DEFINED protocol.

The point is that determining whether or not we have a 400 situation requires more than parsing the characters and spaces and delimiters. It must also recognize what are the valid "parts of speech".