Compare-and-swap for HTTP PUT? - http

Is there a way to make a compare-and-swap-style mechanism the only way to modify certain resources, whilst following the HTTP standard?
There's an If-Match header which implements the correct behaviour however this header is optional: as far as I can tell, if If-Match is not provided, the server should honour the PUT. (That is, it's up to the client to decide whether it wants to compare-and-swap, or just swap.) Would it be acceptable to respond with 412 Precondition Failed if the client tries to PUT or POST without providing an If-Match header?

No, but you can use status code 428 Precondition Required (see http://greenbytes.de/tech/webdav/rfc6585.html#status-428).

Related

What are proper status codes for CORS preflight requests?

What status code should a well-written HTTP server return when it gets a CORS preflight (OPTIONS) request?
200, 204 or something else?
Should the status code be different in case origin is allowed (and corresponding headers will be set) or not allowed (and CORS headers will not be set or will not match the origin)?
The gist of it is, just use 200.
A little more generally: You should just send back the same status code for the CORS preflight OPTIONS request that you’d send back for any other OPTIONS request. The relevant specs don’t require or recommend anything more than that.
What the specs say: The Fetch spec at https://fetch.spec.whatwg.org/ is where requirements for the CORS protocol are defined, and it says the status can be anything in the range 200-299.
That’s from the CORS-preflight fetch algorithm, in a step saying it can be any “ok status":
If a CORS check for request and response returns success and response’s status is an ok status, run these substeps: …
And as far as what an “ok status” is, the spec says this:
An ok status is any status in the range 200 to 299, inclusive.
Beyond that though, the Fetch spec doesn’t recommend any particular status within 200-299.
The other relevant spec here is the HTTP 1.1 spec, which has a section defining semantics of all HTTP response status codes, and within that, a section that defines Successful 2xx codes.
And within that section there’s a specific section for 200 OK, which says this:
The 200 (OK) status code indicates that the request has succeeded.
The payload sent in a 200 response depends on the request method.
For the methods defined by this specification, the intended meaning
of the payload can be summarized as:
…
OPTIONS a representation of the communications options;
So a response to a CORS preflight OPTIONS just needs to be:
an indication that the request has succeeded
a representation of the communication options (which in this case includes the Access-Control-Allow-Methods and Access-Control-Allow-Headers response headers)
That’s what 200 OK is defined by the HTTP spec to be, so you can stop right there.
But if you read through the rest of the 2xx codes in that section, you can confirm the semantics of none of them make sense for an OPTIONS response—except for 204 No Content.
Now as far as 204 No Content goes, there’s nothing wrong with using it for OPTIONS responses—but there’s also not really any point. That’s because:
unlike for some other methods, the HTTP spec defines no use for an OPTIONS payload
therefore in practice, clients don’t expect any payload (content) to come back for an OPTIONS (and wouldn’t do anything with any payload that did come back)
…so there’s no practical purpose in using a specific 204 status code in an OPTIONS response to explicitly tell clients there’s no payload.
Should the status code be different in case origin is allowed (and corresponding headers will be set) or not allowed (and CORS headers will not be set or will not match the origin)?
No. There’s no standard-defined code other than 200 or 204 you could use anyway—but regardless of that, the specs don’t require it to be any different and don’t define any different use if it is. And think about it: What is any existing client code going to do any differently due to any difference in the status codes for those two cases?
If the answer to that is, “Nothing”, then there’s no point in making it different.
Given all the above, the bottom line is: just send 200 OK for CORS preflight OPTIONS responses. Sending any code other than just 200 OK isn’t necessary or useful.
I used 204. Now it's not working cross-browser anymore. Use 200. Firefox started rejecting CORS requests if 204 is received in the preflight. It wasted me almost 2 hours debugging it.
Lesson to learn: When in doubt about web standards don't choose what makes sense spec wise(i.e. 204 for no content)...choose what most people do(the easy/stupid choice)
I am using basic auth passed through headers from an AJAX call and both Firefox and Chrome are using 204 for (preflight/options).

What HTTP status code use when the required header is not specified?

If the user sends request to the server and the link requires specific custom headers to be set in order to work. In this case the error code should be 400, 403 or 422 ?
The HTTP specification requires any client to treat the response as 400 by default if it does not understand the specific meaning of the final two digits. So you must always design with the assumption that some clients will treat the response as 400.
If you can find a 4xx status code whose special extra handling works better for your application, then use it. When the client understands enough to do that extra handling you are slightly better off than if you had sent the default status.
The currently registered status codes which seem to match your servers meaning are:
403 Forbidden - this is about server refusing the request until it is somehow changed. Preferrably with the reason stated in the response body.
406 Not Acceptible - this is more specifically about values in the request headers not being right. Most commonly used for the Accept: header values.
412 Precondition Failed - this is about the problems with headers involved with negotiating which response body would be sent. Most commonly used for the If-* header values.
The 403 seems to be most accurate for when a server refused to deliver anything unless the custom headers is sent.

how to use HTTP 412 code

I am developing a RESTful web service. The web service receives XML from clients, it should reject some bad requests containing some error related to our business logic(say, the payment value below a minimum value). If rejecting request, a customised error code and error message will be written in a response XML(inside http response body). I also want to return a HTTP code in the status line, so client can recognize rejection right away without looking into the response boday. Some people suggest using HTTP code 412, however by looking at the definition of HTTP 412:
412 Precondition Failed
The precondition given in one or more of the request-header fields evaluated to false when it was tested on the server. This response code allows the client to place preconditions on the current resource metainformation (header field data) and thus prevent the requested method from being applied to a resource other than the one intended.
I don't quite understand what it represents for. Could someone explain the appropriate usage of 412 please? or in this case are there any better choices?
It's for use with conditional requests: http://greenbytes.de/tech/webdav/draft-ietf-httpbis-p4-conditional-25.html.
You may want to look at 422 or 409 instead.

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.

Correct behavior with If-Match the header?

According to RFC 2616, generation of entity tags by HTTP servers is optional. However, I couldn't find what a conditionally compliant HTTP server should do if it receives an If-Match (or If-None-Match) header. Should it just ignore those headers or should it respond with 412 Precondition Failed?
UPD: Just to clarify, I'm assuming that the server in question does not support entity tags.
In contrast to an If-None-Match header (ignorance of which only harms performance), an IF-MATCH request should almost certainly fail and return a HTTP/412 if the server cannot match the requested entity. Probably the most common use of the IF-MATCH header is when the client is doing a Range request, and unless the server can confirm that the resource was not modified, it should not return the requested range because the result could be data corruption on the client.
Now, if the server knows it's not a Range request or knows that the client entity must, in fact, match (e.g. because the server never allows updates to its entities) then acting as if the header wasn't present may make sense in that limited circumstance.
There is a handy HTTP response status codes activity diagram that you can use to answer this question.
If you don’t support ETag and the request contains a If-Match value other than *, you would respond with a 412. And If-None-Match with values other than * can be completely ignored.
While the RFC2616 is implicit on the matter, you can deduce from, say 14.26 (If-None-Match), that if the server cannot match the resource with the tag, then it should go ahead with request). The 412 code, based upon my understanding of RFC2616 is intended for requests which modify state (e.g. PUT, POST, DELETE).
So, in essence, if the tag doesn't match (and when it's absent on server side is only one of many possible scenarios), then the server should go ahead with the request.

Resources