Subject: 304 or 412 for If-Modified-Since?

From: Cyrus Daboo <[email-masked]>
Date: Tue, 29 Jun 2010 21:29:40 -0400

Hi folks,
RFC 2616 in Section 14.25 "If-Modified-Since" states that a 304 should be 
returned if the resource is not modified.

RFC 4918 in Section 12.1 "412 Precondition Failed" states that a 412 should 
be returned when a conditional header fails to hold.

So what should clients expect from WebDAV servers?

Second, does If-Modified-Since make sense for PROPFIND or REPORT requests?

-- 
Cyrus Daboo

---

From: Julian Reschke <[email-masked]>
Date: Wed, 30 Jun 2010 07:11:07 +0200

On 30.06.2010 03:29, Cyrus Daboo wrote:
> Hi folks,
> RFC 2616 in Section 14.25 "If-Modified-Since" states that a 304 should
> be returned if the resource is not modified.

Yes.

> RFC 4918 in Section 12.1 "412 Precondition Failed" states that a 412
> should be returned when a conditional header fails to hold.

That should be reported as an RFC 4918 erratum. WebDAV can't override 
normative requirements from HTTP/1.1. (

> So what should clients expect from WebDAV servers?

They should expect that headers defined in RFC 2616 work as advertised 
there.

> Second, does If-Modified-Since make sense for PROPFIND or REPORT requests?

If the resource being addressed responds to GET, and does to with a 
Last-Modified header, then it makes sense for consistency. However, GET 
in a collection *usually* only returns information based on the state of 
the collection and its direct members, so it wouldn't be useful for 
PROPFIND/Depth=Infinity, and might not be useful at all for REPORT.

Of course the same question could be asked about If-None-Match.

I think making PROPFIND/REPORT responses more Web-friendly (adding a way 
to GET those) would help with this issue (hint, hint).

Best regards, Julian

---

From: Elias Sinderson <[email-masked]>
Date: Wed, 30 Jun 2010 17:01:47 +1000

Hi Everyone,

I had responded privately to Cyrus earlier, with the intention of 
writing a better response to the list. I see that Julian has responded 
in the meantime and, while we agree on most all points, I am hoping for 
some thoughtful discussion / clarification of the last issue.

> be returned if the resource is not modified.
Basically, yes, a conditional request with a valid If-Modified-Since 
header is expected to result in a 304 response if the resource has not 
been modified.

There is further clarification in Section 14, where specific request 
headers are defined, for the other If-* headers and their interaction 
with If-Modified-Since. Whether the server returns 304 vs 412 in the 
case of If-None-Match is dependent on the requested method (GET / HEAD 
vs. others). WRT If-Unmodified-Since, the server is required to return a 
412 if the requested variant has been modified, and If-Match behaves 
similarly.

Confusing, yes, and I suspect that there are a few broken 
implementations of this in the wild, both in actual server behavior and 
in what client libraries expect in various situations.

> So what should clients expect from WebDAV servers?
The text you reference from 4918 does not override the normative text in 
2616. Note the introductory text in Section 12 --

/"These HTTP codes are not redefined, but their use is somewhat extended 
by WebDAV methods and requirements."/

The following subsections apply to the methods defined in the WebDAV 
spec, not the base HTTP methods...

> Second, does If-Modified-Since make sense for PROPFIND or REPORT 
My reading of the specs is that yes, this makes sense -- For these 
methods, the If-* headers apply to the resources that are in the scope 
of the request, with the 412 appearing in the <D: status> element 
associated with a given <D:href>.

So, as above, Julian and I are in agreement on all of the points except 
for this last... I've referenced 4918 briefly to look for some 
clarification of this issue but not found anything. I'm hoping that 
someone can provide a reference or some logical explanation to put my 
mind at ease.

Cheers,
Elias

---

From: Julian Reschke <[email-masked]>
Date: Wed, 30 Jun 2010 09:22:18 +0200

Hi Elias,

nice to see you back on the mailing list! :-)

On 30.06.2010 09:01, Elias Sinderson wrote:
> ...
> ...

Indeed. In HTTPbis we still plan to add guidelines on defining new 
headers, and we probably add a paragraph about what to do when defining 
new conditional headers.

> ...
> ...

Agreed. But then it *does* redefine them :-)

> spec, not the base HTTP methods...

That might have been the intent, but it doesn't say that, right?

> associated with a given <D:href>.

We're now talking about multistatus/depth processing, right?

So we need to distinguish two cases:

- applying the condition to the requested resource (which may cause the 
whole request to fail with 412, and which needs to be in sync with HTTP/1.1)

- once the server *does* decide to execute the request, how the 
condition is applied during Depth:1/infinity processing.

The second case indeed is interesting, I assume you're looking at it 
because of collection syncing?

It's *tempting* to claim that RFC 4918 already defines this, but I think 
it would overly optimistic. Better define it properly, and potentially 
add a way for the server to signal that it does this (DAV header comes 
to mind).

> ...

Best regards, Julian

---

From: Elias Sinderson <[email-masked]>
Date: Thu, 01 Jul 2010 09:37:56 +1000

On 30.06.2010, Julian Reschke wrote:
> In HTTPbis we still plan to add guidelines on defining new headers, 
> and we probably add a paragraph about what to do when defining new 
> conditional headers.
I think this would be well received by the broader community.

> That might have been the intent, but it doesn't say that, right?
Correct, a clarification would help here. (Assuming my interpretation is 
correct!)

>> methods, the If-* headers apply to the resources that are in the 
>> scope of the request, with the 412 appearing in the <D: status> 
>> element associated with a given <D:href>.
Yes ...

> - applying the condition to the requested resource (which may cause 
> the whole request to fail with 412, and which needs to be in sync with 
> HTTP/1.1)
Agreed. The depth 0 case is pretty well understood (or, at least, can be 
inferred from the related text in 2616 and 4918).

> because of collection syncing?
More or less -- there are obviously application / domain specific 
scenarios, but they all seem to collapse to this basic idea. As you 
said, it is interesting ... more details on this below.

> It's *tempting* to claim that RFC 4918 already defines this, but I 
> think it would overly optimistic. Better define it properly, and 
> potentially add a way for the server to signal that it does this (DAV 
> header comes to mind).

Yes, well, that would explain why I couldn't find anything relevant when 
I referenced the specs!   :)

With some further analysis, my earlier statement obviously does not 
hold. Here are my current thoughts --

For If-Modified-Since, depth requests can only really be evaluated 
correctly by iterating over the entire set of resources in scope. Given 
the unfortunate diversity in how timestamps are managed by different 
systems, the only reliable way to support this would be to specify that 
the server must consider the entire set of resources in scope and treat 
If-Modified-Since as if it applies to everything. That is, we can't 
indicate any optimizations in the spec wrt evaluation of a collections 
children / descendants. Given that, however, this is a rather 
straightforward feature to support since a single date is used across 
multiple comparisons and there may be some obvious performance 
optimizations to be made for a specific architecture.

If-None-Match is more interesting. For this, we need something akin to 
CTags. I thought this had been discussed on the dist-auth list 
previously but a quick search of the archives came up empty. Cyrus has 
written up a quickie draft proposal on this idea for CalDAV [1], so 
maybe it was only discussed on that list? A critical behavior to address 
is whether CTag changes 'bubble up' to parent containers. The existing 
writeup doesn't specify this, but it is necessary if CTags are to 
support the semantics necessary for efficient evaluation of PROPFIND / 
REPORT type methods at depth. While obviously a performance hit for 
servers to maintain, it would provide some (perhaps more?) performance 
benefit downstream when evaluating requests with depth 1 or infinity.

Have you considered this at any length before?

Regards,
Elias
________________
[1] 
<http://svn.calendarserver.org/repository/calendarserver/CalendarServer/trunk/doc/Extensions/caldav-ctag.txt>