Is it valid HTTP to send a 406 with the client request has no Accept header - http

https://www.rfc-editor.org/rfc/rfc7231#section-5.3.2 states that
A request without any Accept header field implies that the user agent
will accept any media type in response.
Also https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html states that
If no Accept header field is present, then it is assumed that the
client accepts all media types. If an Accept header field is present,
and if the server cannot send a response which is acceptable according
to the combined Accept field value, then the server SHOULD send a 406
(not acceptable) response.
Still, would it be wrong to send back a 406 Not Acceptable in such case ?
In particular we want to enforce the customer to write client code that is version aware (our Content-Types have a version modified).

would it be wrong to send back a 406 Not Acceptable in such case?
The short answer is yes and the answer is in your own question. Once RFC 2616 is no longer relevant, consider the quote from the RFC 7231:
A request without any Accept header field implies that the user agent will accept any media type in response.
The same paragraph of RFC 7231 states in which situation the 406 status code can be used:
If the header field is present in a request and none of the available representations for the response have a media type that is listed as acceptable, the origin server can either honor the header field by sending a 406 (Not Acceptable) response or disregard the header field by treating the response as if it is not subject to content negotiation.
See how the 406 status code is defined:
6.5.6. 406 Not Acceptable
The 406 (Not Acceptable) status code indicates that the target resource does not have a current representation that would be acceptable to the user agent, according to the proactive negotiation header fields received in the request (Section 5.3), and the server is unwilling to supply a default representation.

Yes, it would be wrong for compliant servers. A missing accept header should be treated the same as accepting all content-types. That doesn’t mean you can’t still reject a missing accept header, since many security tools already do:
Abyss Guard
ModSecurity
Bad Behavior
If you want to stay compliant, you could send a 400 error which is generic, but 406 error would make more sense.

Related

accept header in HTTP request

I am trying to learn web services in general and have a small doubt.
When HTTP request is sent, if I mention a particular format (for example JSON) in Accept header and suppose server does not support that format, then will it be a network call error or server will still respond with whatever format it supports?
I know while sending a POST request, client sends another header by name "Content Type" and if that format is not supported by server, then it responds back with 415 error. (unsupported media type).
It's up to the server. It does not need to pay attention to the Accept header field.
A request without any Accept header field implies that the user agent
will accept any media type in response. If the header field is present
in a request and none of the available representations for the
response have a media type that is listed as acceptable, the origin
server can either honor the header field by sending a 406 (Not
Acceptable) response or disregard the header field by treating the
response as if it is not subject to content negotiation.
(from https://www.greenbytes.de/tech/webdav/rfc7231.html#rfc.section.5.3.2.p.7)
For web services, the server will be responsible to denote the type of format that it intends to support, whether it is using JSON or XML.
Based on the data received from the client, the server should validate the format provided by the client. If it fits the specified format, then the server will respond accordingly to the intend of the end point. On the other hand, if it doesn't fit, the server should respond gracefully, indicating that the format (JSON/XML) is not supported by the web services.
I hope that answers your question. Have a nice day!

HTTP Status Code Priority and Processing

Let's say a web application gets the following request:
POST /some/endpoint HTTP/1.1
Host: <something>
Accept: application/json
Accept-Language: pt
Content-Type: application/json
If-Match: "blabla"
Some body
If the server doesn't support HTTP 1.1 and the endpoint /some/endpoint does not exist, the former problem should likely be checked first, and a 505 rather than 404 should be returned.
If it just so happens that none of the endpoints of the server accept POST and the endpoint /some/endpoint doesn't exist, the latter should get priority, and 404 should be returned rather than 405.
If the Accept can't be provided and the body can't be appropriately decoded/validated, probably 406 should take precedence over 400.
These are cases where intuition might suffice. But there are a myriad other ones where it is not clear which of two non-2XX status codes should be preferred/checked first. For example, should Content-Type (resulting in 415) or Accept-Language (406) be returned if both would fail? 415 or 412? And on it goes...
Much of the time errors are pairwise independent: if the aspect that is relevant to one error being thrown (such as a particular header value) is fixed, the success/error status of another will not be affected. In those cases, the wrong error "priority" is perhaps only a nuisance. But sometimes it may be the case that these errors are not independent: I might have a resources as HTML in Portuguese, but in JSON only in English (humour me), so that if a client expects me to prioritise Accept-Language over Accept, and I do the opposite, the result will be quite bad.
The question should be evident now: are there any standards about which errors should be prioritised?
I haven't come across any relevant RFCs, or even much serious and general discussion. I know of the webmachine diagram, which sort of helps, but primarily just seems to describe a particular (well thought out) implementation rather than any standard.
Obviously, you can’t expect this question to be answered “no,” even though that’s probably the correct answer.
So let me address a particular point of yours instead:
I might have a resources as HTML in Portuguese, but in JSON only in English (humour me), so that if a client expects me to prioritise Accept-Language over Accept, and I do the opposite, the result will be quite bad.
In your example, you tell the server that Portuguese JSON is good, but all other combinations are equally bad. If that’s not the case, you can elaborate your preferences like this:
Accept: text/json
Accept-Language: pt, en;q=0.1
The server can then multiply your weights, getting 1×0.1=0.1 for English JSON and 0×1=0 for Portuguese HTML, and choosing the former.
(Sidenote 1: there is no text/json media type in the registry. You probably want application/json.)
(Sidenote 2: 415 Unsupported Media Type is not a correct response code for the scenarios you mention. It concerns the request body. If you cannot honor the Accept header, you can respond with 406 Not Acceptable, just as with Accept-Language.)
TL;DR: The specifications give the server ultimate authority in how it honors the request, even allowing the server to ignore the acceptable formats the client requests. However, the specifications instruct the server to make a best effort and to respond in a way that best helps the client recover from errors.
The specifications provide guidance, even if they don't (or can't) prioritize all possible error modes.
RFC 2616 § 10.4.7 says:
HTTP/1.1 servers are allowed to return responses which are
not acceptable according to the accept headers sent in the
request. In some cases, this may even be preferable to sending a
406 response. User agents are encouraged to inspect the headers of
an incoming response to determine if it is acceptable.
RFC 7231 § 3 says:
An origin server might be provided with, or be capable of generating,
multiple representations that are each intended to reflect the
current state of a target resource. In such cases, some algorithm is
used by the origin server to select one of those representations as
most applicable to a given request, usually based on content
negotiation.
RFC 7231 § 3.4 says:
Note that, in all cases, HTTP is not aware of the resource semantics.
The consistency with which an origin server responds to requests ... is determined entirely by whatever entity or algorithm selects
or generates those responses. HTTP pays no attention to the man
behind the curtain.
RFC 7231 § 3.3 says:
Response messages with an error status code
usually contain a payload that represents the error condition, such
that it describes the error state and what next steps are suggested
for resolving it.
RFC 2616 § 14.46 says:
The Warning general-header field is used to carry additional information about the status or transformation of a message which might not be reflected in the message. This information is typically used to warn about a possible lack of semantic transparency from caching operations or transformations applied to the entity body of the message.
(Emphases all mine.)
Section 3 of RFC 7231 gives the origin server ultimate authority to decide the appropriate response, even if that response is repugnant. Simultaneously, section 3 encourages the origin server to satisfy the request, or provide notice that it satisfied some of the request (Vary), or provide selectable options ("Passive negotiation").
Even though the server has ultimate authority, the specification makes clear to me that the responses should help the user resolve the problem. In my mind, the best error code is the one that helps the user best fix the problem!
Considering your pair-wise examples:
"If the server doesn't support HTTP 1.1 and the endpoint /some/endpoint does not exist, the former problem should likely be checked first, and a 505 rather than 404 should be returned."
No. Per the spec, an HTTP 1.1 client can GET from 1.0 server by protocol downgrade, so this kind of version negotiation is handled by the specification. Send a 404 (or a 301 if that's known) so the user can correct it.
"If it just so happens that none of the endpoints of the server accept POST and the endpoint /some/endpoint doesn't exist, the latter should get priority, and 404 should be returned rather than 405."
Yes, 404. If you're not getting to a resource, the method hardly matters.
"If the Accept can't be provided and the body can't be appropriately decoded/validated, probably 406 should take precedence over 400."
Never send 400 when you know 406 applies. You're giving the client less information, which is less helpful. However, the origin server is free to ignore the Accept header per RFC 7231 § 5.3.2:
If the [Accept] header field is
present in a request and none of the available representations for
the response have a media type that is listed as acceptable, the
origin server can either honor the header field by sending a 406 (Not
Acceptable) response or disregard the header field by treating the
response as if it is not subject to content negotiation.
"I might have a resources as HTML in Portuguese, but in JSON only in English (humour me), so that if a client expects me to prioritise Accept-Language over Accept, and I do the opposite, the result will be quite bad."
I disagree that the result will be bad. See RFC 7231 § 5.3.5:
the origin server can either disregard the [Accept-Language] header field by treating the response as if it is not subject to content negotiation or honor the header field by sending a 406 (Not Acceptable) response. However, the latter is not encouraged, as doing so can prevent users from accessing content that they might be able to use (with translation software, for example).
This pattern of specification language occurs more than once. "The server may disregard [whatever the client requested] by treating the response as if it's not subject to [this part of the specification], or the server may honor [the client request] and send [an applicable error code]. But, it's better to [send something intelligible] than only send [an inscrutable error code]."
At the end of the day, it's your API. HTTP provides only a window into your semantics. Document what you accept, how you respond, and with what. Send intelligible responses (HATEOAS is good) and, when applicable, the most specific error codes available.

Response code for "accept type not supported"

What is the proper response code for a request with an Accept header that I don't support?
For example if a request with an Accept header application/json comes in but the only response types I support are text/plain and text/html, what response code should I return?
That would be HTTP response 406 according the RFC 7231:
6.5.6. 406 Not Acceptable
The 406 (Not Acceptable) status code indicates that the target
resource does not have a current representation that would be
acceptable to the user agent, according to the proactive negotiation
header fields received in the request (Section 5.3), and the server
is unwilling to supply a default representation.
The server SHOULD generate a payload containing a list of available
representation characteristics and corresponding resource identifiers
from which the user or user agent can choose the one most
appropriate. A user agent MAY automatically select the most
appropriate choice from that list. However, this specification does
not define any standard for such automatic selection, as described in
Section 6.4.1.
source: https://www.rfc-editor.org/rfc/rfc7231#section-6.5.6

Appropriate HTTP status code for request specifying invalid Content-Encoding header?

What status code should be returned if a client sends an HTTP request and specifies a Content-Encoding header which cannot be decoded by the server?
Example
A client POSTs JSON data to a REST resource and encodes the entity body using the gzip coding. However, the server can only decode DEFLATE codings because it failed the gzip class in server school.
What HTTP response code should be returned? I would say 415 Unsupported Media Type but it's not the entity's Content-Type that is the problem -- it's the encoding of the otherwise supported entity body.
Which is more appropriate: 415? 400? Perhaps a custom response code?
Addendum: I have, of course, thoroughly checked rfc2616. If the answer is there I may need some new corrective eyewear, but I don't believe that it is.
Update:
This has nothing to do with sending a response that might be unacceptable to a client. The problem is that the client is sending the server what may or may not be a valid media type in an encoding the server cannot understand (as per the Content-Encoding header the client packaged with the request message).
It's an edge-case and wouldn't be encountered when dealing with browser user-agents, but it could crop up in REST APIs accepting entity bodies to create/modify resources.
As i'm reading it, 415 Unsupported Media Type sounds like the most appropriate.
From RFC 2616:
10.4.16 415 Unsupported Media Type
The server is refusing to service the request because the entity of the request is in a format not supported by the requested resource for the requested method.
Yeah, the text part says "media type" rather than "encoding", but the actual description doesn't include any mention of that distinction.
The new hotness, RFC 7231, is even explicit about it:
6.5.13. 415 Unsupported Media Type
The 415 (Unsupported Media Type) status code indicates that the
origin server is refusing to service the request because the payload
is in a format not supported by this method on the target resource.
The format problem might be due to the request's indicated
Content-Type or Content-Encoding, or as a result of inspecting the
data directly.
They should make that the final question on Who Wants To Be a Millionaire!
Well the browser made a request that the server cannot service because the information the client provided is in a format that cannot be handled by the server. However, this isn't the server's fault for not supporting the data the client provided, it's the client's fault for not listening to the server's Acccept-* headers and providing data in an inappropriate encoding. That would make it a Client Error (400 series error code).
My first instinct is 400 Bad Request is the appropriate response in this case.
405 Method Not Allowed isn't right because it refers to the HTTP verb being one that isn't allowed.
406 Not Acceptable looks like it might have promise, but it refers to the server being unable to provide data to the client that satisfies the Accept-* request headers that it sent. This doesn't seem like it would fit your case.
412 Precondition Failed is rather vaguely defined. It might be appropriate, but I wouldn't bet on it.
415 Unsupported Media Type isn't right because it's not the data type that's being rejected, it's the encoding format.
After that we get into the realm of non-standard response codes.
422 Unprocessable Entity describes a response that should be returned if the request was well-formed but if it was semantically incorrect in some way. This seems like a good fit, but it's a WebDAV extension to HTTP and not standard.
Given the above, I'd personally opt for 400 Bad Request. If any other HTTP experts have a better candidate though, I'd listen to them instead. ;)
UPDATE: I'd previously been referencing the HTTP statuses from their page on Wikipedia. Whilst the information there seems to be accurate, it's also less than thorough. Looking at the specs from W3C gives a lot more information on HTTP 406, and it's leading me to think that 406 might be the right code after all.
10.4.7 406 Not Acceptable
The resource identified by the request is only capable of generating
response entities which have content characteristics not acceptable
according to the accept headers sent in the request.
Unless it was a HEAD request, the response SHOULD include an entity
containing a list of available entity characteristics and location(s)
from which the user or user agent can choose the one most appropriate.
The entity format is specified by the media type given in the
Content-Type header field. Depending upon the format and the
capabilities of the user agent, selection of the most appropriate
choice MAY be performed automatically. However, this specification
does not define any standard for such automatic selection.
Note: HTTP/1.1 servers are allowed to return responses which are
not acceptable according to the accept headers sent in the
request. In some cases, this may even be preferable to sending a
406 response. User agents are encouraged to inspect the headers of
an incoming response to determine if it is acceptable.
If the response could be unacceptable, a user agent SHOULD temporarily
stop receipt of more data and query the user for a decision on further
actions.
While it does mention the Content-Type header explicitly, the wording mentions "entity characteristics", which you could read as covering stuff like GZIP versus DEFLATE compression.
One thing worth noting is that the spec says that it may be appropriate to just send the data as is, along with the headers to tell the client what format it's in and what encoding it uses, and just leave it for the client to sort out. So if the client sends a header indicating it accepts GZIP compression, but the server can only generate a response with DEFLATE, then sending that along with headers saying it's DEFLATE should be okay (depending on the context).
Client: Give me a GZIPPED page.
Server: Sorry, no can do. I can DEFLATE pack it for you. Here's the DEFLATE packed page. Is that okay for you?
Client: Welllll... I didn't really want DEFLATE, but I can decode it okay so I'll take it.
(or)
Client: I think I'll have to clear that with my user. Hold on.

Is using the HTTP Content-Range header appropriate when sending a file in chunks using the POST method?

I am working on an existing Silverlight file uploader that breaks files into multiple chunks and transmits the file using multiple HTTP requests.
Currently, it sends the start and total byte information on the querystring, but as learning exercise, I'd like to use a more standards-based approach.
I've previously used the HTTP Content-Range header when implementing an endpoint that serves content. Is this header also appropriate to use when posting content from a client to the server?
Yes.
RFC 2616 (HTTP 1.1), Section 14 begins by stating:
For entity-header fields, both sender and recipient refer to either
the client or the server, depending on who sends and who receives the
entity.
Other than that, Section 14.16, which defines the Content-Range header, does not appear to contain any language limiting its use to either the request or response.
Probably not, at least as of 2014 (the original answer is from 2011).
The updated HTTP 1.1 specification, rfc7231 (4.3.3), says the following about valid POST responses:
An origin server indicates response semantics by choosing an
appropriate status code depending on the result of processing the
POST request; almost all of the status codes defined by this
specification might be received in a response to POST (the exceptions
being 206 (Partial Content), 304 (Not Modified), and 416 (Range Not
Satisfiable)).
Given that this language was explicitly added to the updated spec, I doubt the authors intended that the Content-Range header be used with the POST method.

Resources