- From: Jeffrey Mogul <mogul@pa.dec.com>
- Date: Wed, 25 Feb 98 14:04:30 PST
- To: http-wg@cuckoo.hpl.hp.com
[Warning: lengthy analysis follows.] Dave Kristol writes: 14.25 If-Match If the request would, without the If-Match header field, result in anything other than a 2xx status, then the If-Match header MUST be ignored. This paragraph implies to me that I should test I-M-S before I-M, because it's possible that I-M-S could produce a 304. (Note that Apache 1.2.5 does the I-M test first, on the theory that I-M is a more accurate test. I'm using Apache as a reference because I'm assuming that Roy had a strong hand in the code. So I would expect it to reflect the desired behavior.) First of all, I think it's a mistake to refer to the Apache implementation to try to figure out what your implementation should do. It's quite possible that Apache does the right thing; however, the IESG expects us to document multiple "independent" implementations based on the specification, and it seems to me that basing your decision on how Apache did it subverts this goal. If the spec is wrong or ambiguous, we need to fix it, but not on the basis that any particular existing implementation has already chosen one option. I should also point out that this specific topic was discussed on the HTTP-WG mailing list in mid-November (1997), resulting in some changes that might not have appeared in a release of Apache that came out in early January. So that version of Apache wouldn't necessarily agree with the specification anyway (although the Apache people know better than I do what kind of schedule they followed). Anyway, the specific "issue" to look at is IMS_INM_MISMATCH, which cites as a "fix" my message: http://www.ics.uci.edu/pub/ietf/http/hypermail/1997q4/0117.html and a follow-up: http://www.ics.uci.edu/pub/ietf/http/hypermail/1997q4/0160.html Let me start by addressing your questions regarding If-None-Match, since that is what we have already discussed and resolved (?): 14.26 If-None-Match If any of the entity tags match the entity tag of the entity that would have been returned in the response to a similar GET request (without the If-None-Match header) on that resource, or if "*" is given and any current entity exists for that resource, then the server MUST NOT perform the requested method, unless required to do so because the resource's modification date fails to match that supplied in an If- Modified-Since header field in the request. Instead, if the request method was GET or HEAD, the server SHOULD respond with a 304 (Not Modified) response, including the cache-related entity-header fields (particularly ETag) of one of the entities that matched. For all other request methods, the server MUST respond with a status of 412 (Precondition Failed). The problem is, if I test I-M-S first, then I-N-M, I can run afoul of this part of 14.26: If none of the entity tags match, then the server MAY perform the requested method as if the If-None-Match header field did not exist, but MUST also ignore any If-Modified-Since header field(s) in the request. That is, if no entity tags match, then the server MUST not return a 304 (Not Modified) response. I'm not sure there is a contradiction. The first paragraph you cite from 14.26 says (if I'm not confused by my own words!) if (any entity tags match) { if (IMS-date != last-modified) { MUST perform method } else { MUST NOT perform method if (method == GET or HEAD) return 304 else return 412 } } else { unspecified behavior } The second paragraph says, in effect if (no entity tags match) { process request, ignoring any IMS header } else { unspecified behavior MUST NOT return 304 } The composition of these two conditionals should be obvious ... Dave asks: Also, I'm uncertain what the proper behavior is for I-N-M if an Etag match succeeds and there's no I-M-S, or if there's an I-M-S and the file has been modified since the I-M-S date. Return 412 (Precondition Failed)? The response isn't well specified. It is possible to edit the first quoted paragraph, by deleting inapplicable clauses, to answer these two questions: for I-N-M if an Etag match succeeds and there's no I-M-S, "If any of the entity tags match ... the server MUST NOT perform the requested method" (since the "unless" clause in that sentence isn't triggered). "[If] the request method was GET or HEAD, the server SHOULD respond with a 304 ... [for] all other methods, ... respond with a status of 412." if there's an I-M-S and the file has been modified since the I-M-S date. "the server ... is required to do so [i.e., perform the method] because the resource's modification date fails to match that supplied in an If-Modified-Since header field in the request." I suspect the english here could be a bit clearer, but I don't think it's actually ambiguous or contradictory. Now, back to If-Match. You're basically asking what to do if you see this request: GET /foo.html HTTP/1.1 Host: research.bell-labs.com If-Match: "xyzzy" If-Modified-Since: Wed, 25 Feb 98 14:51:40 GMT To me, this looks like a meaningless (or at best, highly unlikely) request. What it appears to mean is that the client only wants the entity-body of /foo.html if the resource HAS been changed since the last-modified date of the client's current cache entry for /foo.html, AND if the (strong) entity tag HAS NOT changed. In other words, I can't see much of a reason for combining If-Match and IMS. It might make more sense to combine If-Match and If-Unmodified-Since, e.g.: GET /foo.html HTTP/1.1 Host: research.bell-labs.com If-Match: "xyzzy" If-Unmodified-Since: Wed, 25 Feb 98 14:51:40 GMT but then I think the only question is whether this means that the request is performed if all of the "If-*" conditions are met, or if at least one of them is met. The language in the spec for If-Match is: If none of the entity tags match ..., the server MUST NOT perform the requested method, and MUST return a 412 (Precondition Failed) response. [...] If the request would, without the If-Match header field, result in anything other than a 2xx status, then the If-Match header MUST be ignored. and the language for If-Unmodified-Since is: If the requested variant has been modified since the specified time, the server MUST NOT perform the requested operation, and MUST return a 412 (Precondition Failed). If the request normally (i.e., without the If-Unmodified-Since header) would result in anything other than a 2xx status, the If-Unmodified- Since header should be ignored. It turns out that there *is* a contradition here: if none of the entity tags match AND if the variant has been modified, then each header "wants" to cause us to return 412, but the rules for each header individually says "ignore me because my buddy wants us to return 412". So I think the phrase "2xx status" in both quotes above should be "2xx or 412 status". With that fix applied (I'll submit this as an "issue"), I think the meaning of a request with both IM and IUS is straightforward: if ((no entity tags match the If-Match value) or (last-modified date not same as IUS value)) { return 412 } else { process request, ignoring If-Match and If-Unmodified-Since hdrs } Clear? -Jeff
Received on Wednesday, 25 February 1998 14:07:52 UTC