Subject: Changing etag and getlastmodified on move/rename

From: "Lisa Dusseault" <[email-masked]>
Date: Wed, 6 Aug 2003 16:13:14 -0700

What's the general behavior for changing etag and getlastmodified when a resource is simply renamed via a MOVE, or when it's moved to another directory?  

Do any clients benefit if the ETag is the same after a MOVE?  Would the client get confused if the ETag is the same but the getlastmodified value is different after a MOVE?

Lisa

---

From: "Julian Reschke" <[email-masked]>
Date: Thu, 7 Aug 2003 09:03:36 +0200

> From: [email-masked]
> [mailto:[email-masked]]On Behalf Of Lisa Dusseault
> Sent: Thursday, August 07, 2003 1:13 AM
> To: Webdav WG
> Subject: Changing etag and getlastmodified on move/rename
> 
> 
> 
> 
> What's the general behavior for changing etag and getlastmodified 
> when a resource is simply renamed via a MOVE, or when it's moved 
> to another directory?  
> 
> Do any clients benefit if the ETag is the same after a MOVE?
> Would the client get confused if the ETag is the same but the 
> getlastmodified value is different after a MOVE?

It shouldn't. Also, the other combination can occur as well (ETag changes, but getlastmodified doesn't). This is because the ETag must be unique for all representations produced for a particular URL (+ variant-selecting headers), *not* the resource.

Consider:

/a/b with etag "1"
/a/c with etag "1"
MOVE /a/b -> a/c

The resulting ETag for "/a/c" MUST NOT be 1.

If a server needs a way to robustly identify a resource indepedantly of the URL, it should use DAV:resource-id.

Julian

--
<green/>bytes GmbH -- http://www.greenbytes.de -- tel:+492512807760

---

From: "Lisa Dusseault" <[email-masked]>
Date: Mon, 11 Aug 2003 10:38:28 -0700

> It shouldn't. Also, the other combination can occur as well 
> (ETag changes, but getlastmodified doesn't). This is because 
> the ETag must be unique for all representations produced for 
> a particular URL (+ variant-selecting headers), *not* the resource.
> 
> Consider:
> 
> /a/b with etag "1"
> /a/c with etag "1"
> MOVE /a/b -> a/c
> 

Wouldn't the "getlastmodified" value change during this operation as well?  I'm assuming that at the beginning /a/b and /a/c had different content, which is why the ETag had to changed when the MOVE caused the content /a/c to be overwritten with the content from /a/b.  If that's the case then the result of a GET to /a/c is different after the move, so the 'getlastmodified' must also change.

Lisa

---

From: "Julian Reschke" <[email-masked]>
Date: Mon, 11 Aug 2003 20:40:31 +0200

> Sent: Monday, August 11, 2003 7:38 PM
> To: 'Julian Reschke'; 'Webdav WG'
> Subject: RE: Changing etag and getlastmodified on move/rename
> 
> 
> 
> Wouldn't the "getlastmodified" value change during this operation 
> as well?  I'm assuming that at the beginning /a/b and /a/c had 
> different content, which is why the ETag had to changed when the 
> MOVE caused the content /a/c to be overwritten with the content 
> from /a/b.  If that's the case then the result of a GET to /a/c 
> is different after the move, so the 'getlastmodified' must also change.

Most of the time yes, but not always: if /a/b and /a/c might have had the same DAV:getlastmodified property before the MOVE, in which case the date for /a/c may not change (one of the reasons why ETags are better than dates).

Seems that the HTTP caching (lastmodified and etag) aren't very compatible with WebDAV namespace operations.

---

From: "Lisa Dusseault" <[email-masked]>
Date: Mon, 11 Aug 2003 13:54:37 -0700

> Most of the time yes, but not always: if /a/b and /a/c might 
> have had the same DAV:getlastmodified property before the 
> MOVE, in which case the date for /a/c may not change (one of 
> the reasons why ETags are better than dates).
> 

The 'getlastmodified' property probably shouldn't be preserved across most MOVE operations.  Recall that the meaning of 'getlastmodified' isn't defined as the time that a user last made changes to the content of a resource.  Rather, it's the date at which the results of a GET request to that URL last changed.  That's because it's tied to the Last-Modified header definition in HTTP.

Consider the case where a MOVE operation overwrites an existing resource with different content.  Clearly the HTTP Last-Modified header value must now be set to the timestamp of the MOVE operation, because this operation invalidates previously cached copies of the destination resource.

Consider next the case where a MOVE operation creates a new resource with content from somewhere else.  Even though that content wasn't new content, it is new at that URL.  A client may get confused trying to synchronize a resource which didn't even exist before time T, yet its 'getlastmodified' or Last-Modified value is prior to time T.  I think the safest thing to do in this case is again to update the value to the timestamp of the MOVE operation.

If we want a property which instead tells us the last time a user made changes to the body of a file, we would have to define a new property which would happen to have the same value as 'getlastmodified' much of the time.  But the new property would probably be client writable so that a synchronizing or backup client could tell the server when the file was last changed.

Lisa

---

From: Geoffrey M Clemm <[email-masked]>
Date: Mon, 11 Aug 2003 17:08:52 -0400

I agree that a WebDAV client would prefer that the Last-Modified header
(and the DAV:getlastmodified property) be based on the URL
(and therefore change on every MOVE) rather than be based on
the resource (and therefore not change on a MOVE), but 2616
explicitly states that a possible implementation of the Last-Modified
value is the file system modification time.  This is based on
the pragmatic observation that it would be prohibitively expensive
for a variety of WebDAV servers to modify (or supplement)
the last-modification semantics of their underlying repository
(which is resource based, not URL based).

Cheers,
Geoff

Lisa wrote on 08/11/2003 04:54:37 PM:

> The 'getlastmodified' property probably shouldn't be preserved 
> across most MOVE operations.  Recall that the meaning of 
> 'getlastmodified' isn't defined as the time that a user last made 
> changes to the content of a resource.  Rather, it's the date at 
> which the results of a GET request to that URL last changed.  That's
> because it's tied to the Last-Modified header definition in HTTP.
> 
> Consider the case where a MOVE operation overwrites an existing 
> resource with different content.  Clearly the HTTP Last-Modified 
> header value must now be set to the timestamp of the MOVE operation,
> because this operation invalidates previously cached copies of the 
> destination resource.
> 
> Consider next the case where a MOVE operation creates a new resource
> with content from somewhere else.  Even though that content wasn't 
> new content, it is new at that URL.  A client may get confused 
> trying to synchronize a resource which didn't even exist before time
> T, yet its 'getlastmodified' or Last-Modified value is prior to time
> T.  I think the safest thing to do in this case is again to update 
> the value to the timestamp of the MOVE operation.
> 
> If we want a property which instead tells us the last time a user 
> made changes to the body of a file, we would have to define a new 
> property which would happen to have the same value as 
> 'getlastmodified' much of the time.  But the new property would 
> probably be client writable so that a synchronizing or backup client
> could tell the server when the file was last changed.
> 
> Lisa
> 
> 
>

---

From: "Lisa Dusseault" <[email-masked]>
Date: Mon, 11 Aug 2003 16:09:13 -0700

> Seems that the HTTP caching (lastmodified and etag) aren't 
> very compatible with WebDAV namespace operations.
> 

HTTP caching is very carefully defined.  The "Last-Modified" header isn't defined as the last time the user did a PUT request, it's defined very carefully in terms of when the entity changed:
" The Last-Modified entity-header field indicates the date and time at which the origin server believes the variant was last modified. "

If the variant was last changed through either a local file system move overwrite, or through a WebDAV MOVE operation that targetted the URL where that variant is accessed, then Last-Modified has changed according to the definition.  HTTP doesn't say how it behaves in terms of MOVE because to HTTP, MOVE doesn't exist.  But it does define things carefully enough so that you can deduce that a MOVE must change the Last-Modified value.  The reason for this is because Last-Modified was designed for caching, not for display.  If a MOVE request overwrites a resource with different content, caching agents need to know to update their cached copy.  

We've noticed that Apache doesn't change the Last-Modified date when a file is moved in the server's file system.  It accepts the file system's say-so, even when the file has been overwritten during a local move.  However Apache simply doesn't have the information that the file was changed so it can't -- in essence this is the "origin server believes" phrase of the spec.  Thus, Apache can break caching.  A client can ask for a file with a "Last-Modified-Since" value, and Apache may return a 412 Precondition Failed response even when the file has been changed due to a local file-system move.  Clearly that's wrong.

The design of HTTP caching isn't very compatible with how clients want to display the last time a user edited a file, and it isn't very compatible with how the Windows file system works.  But HTTP caching wasn't designed to solve either of those problems.

Lisa

---

From: "Julian Reschke" <[email-masked]>
Date: Sun, 17 Aug 2003 12:51:09 +0200

Lisa,

you are right that WebDAV absolutely can't overrule what RFC2616 (HTTP/1.1) says about the Last-Modified header and caching. Thus

1) We probably should clarify the COPY/MOVE behaviour. Currently the draft says:

"COPY/MOVE behaviour: This property value is dependent on the final 
            state of the destination resource, not the value of the 
            property on the source resource. It MUST NOT be set in 
            PROPPATCH during a cross-server copy. "

How is the previous DAV:getlastmodified date of the destination resource relevant?

I think the only safe way to respect RFC2616 semantics is to require that after a COPY/MOVE, DAV:getlastmodified is set to the current date.

2) I also agree that this is likely to cause complaints from people who actually want a time stamp for *resource* modifications. A proper way to address this may be to define a new optional property (if we make it optional, we may be able to get it into RFC52518bis), for instance:

   Name:    modificationdate 
   Namespace:   DAV: 
   Purpose:     Records the time and date the resource was modified. 
   Value:   date-time   
   COPY/MOVE behaviour: This property value SHOULD be kept during a 
            MOVE operation, but is re-initialized when a resource is 
            created with a COPY. It should not be set in a remote COPY. 
   Description: The creationdate property should be defined on all DAV 
            compliant resources.  If present, it contains a timestamp 
            of the moment when the resource was last modified (i.e., the 
            moment when content and/or propertoes last changed).
            This property is live and 
            protected. The Internet date-time format is defined in 
            [RFC3339], see the ABNF in section 5.6. 
    
   <!ELEMENT modificationdate (#PCDATA) > 
    
Julian

---

From: "Lisa Dusseault" <[email-masked]>
Date: Sun, 17 Aug 2003 19:08:50 -0700

I agree with all of this.  I have no problems putting an optional modificationdate in RFC2518bis if we can get agreement quickly because I think it could be implemented extremely quickly in several implementations.  

Lisa

> -----Original Message-----
> From: Julian Reschke [mailto:[email-masked]] 
> Sent: Sunday, August 17, 2003 3:51 AM
> To: Lisa Dusseault; 'Julian Reschke'; 'Webdav WG'
> you are right that WebDAV absolutely can't overrule what 
> RFC2616 (HTTP/1.1) says about the Last-Modified header and 
> caching. Thus
> 
> I think the only safe way to respect RFC2616 semantics is to 
> require that after a COPY/MOVE, DAV:getlastmodified is set to 
> the current date.
> 
> 
> 2) I also agree that this is likely to cause complaints from 
> people who actually want a time stamp for *resource* 
> modifications. A proper way to address this may be to define 
> a new optional property (if we make it optional, we may be 
> able to get it into RFC52518bis), for instance:
> 
>    Name:    modificationdate 
>    Namespace:   DAV:

---

From: Geoffrey M Clemm <[email-masked]>
Date: Mon, 18 Aug 2003 11:01:06 -0400

Since RFC2616 explicitly states that a server may use
the file system last-modified dates for the value of the
Last-Modified header, I suggest that we also add words
to the effect that:

"To deal correctly with servers that use the native
repository last-modified times which are not updated by a MOVE,
a conservative caching mechanism will store the results of the previous
getlastmodified date, and only assume the cache is valid if
the current getlastmodified date is equal to the stored
getlastmodified date".

Cheers,
Geoff

[email-masked] wrote on 08/17/2003 10:08:50 PM:

> 
> I agree with all of this.  I have no problems putting an optional 
> modificationdate in RFC2518bis if we can get agreement quickly 
> because I think it could be implemented extremely quickly in several
> implementations. 
> 
> Lisa
>