This was already reported in the Zimbra Bugzilla as well (cf. URL) since I don't know who is at fault here. I'll attach a screenshot. Reproducible: Always Steps to Reproduce: 1. Go to webdavs://zimbraserver/dav/username/Briefcase 2. Upload a file 3. Look at the timestamp Actual Results: The timestamp is 2106-02-07 07:28 Expected Results: It should be more or less the current time (ie. when the file was modified) Zimbra 8.0.6
Created attachment 85425 [details] Screenshot
Here's what the client and server says (huh? two different date formats?): PROPFIND /dav/stretzm/Briefcase/ HTTP/1.1 Host: zimbratest.example.com:8080 Connection: keep-alive User-Agent: Mozilla/5.0 (X11; Linux x86_64) KHTML/4.12.2 (like Gecko) Konqueror/4.12 Pragma: no-cache Cache-control: no-cache Accept: text/html, text/*;q=0.9, image/jpeg;q=0.9, image/png;q=0.9, image/*;q=0.9, */*;q=0.8 Accept-Encoding: gzip, deflate, x-gzip, x-deflate Accept-Charset: utf-8,*;q=0.5 Accept-Language: en-US,en;q=0.9 Authorization: Basic xxx Depth: 0 Content-Type: text/xml; charset=utf-8 Content-Length: 288 <?xml version="1.0" encoding="utf-8" ?><D:propfind xmlns:D="DAV:"><D:prop><D:creationdate/><D:getcontentlength/><D:displayname/><D:source/><D:getcontentlanguage/><D:getcontenttype/><D:getlastmodified/><D:getetag/><D:supportedlock/><D:lockdiscovery/><D:resourcetype/></D:prop></D:propfind> HTTP/1.1 207 Multi-Status Date: Wed, 05 Mar 2014 16:52:45 GMT Access-Control-Allow-Origin: *.example.com Strict-Transport-Security: max-age=31536000 DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule DAV: version-control, addressbook, extended-mkcol, calendar-proxy DAV: calendarserver-principal-property-search Content-Type: text/xml;charset=UTF-8 Transfer-Encoding: chunked 379 <?xml version="1.0" encoding="UTF-8"?> <D:multistatus xmlns:D="DAV:"> <D:response> <D:href>/dav/stretzm/Briefcase/</D:href> <D:propstat> <D:status>HTTP/1.1 200 OK</D:status> <D:prop> <D:resourcetype> <D:collection/> </D:resourcetype> <D:getlastmodified>Thu, 20 Sep 2012 15:40:37 -0000 (GMT)</D:getlastmodified> <D:getcontentlength>0</D:getcontentlength> <D:displayname>Briefcase</D:displayname> <D:getetag>"1-1"</D:getetag> <D:creationdate>2012-09-20T17:40:37+02:00</D:creationdate> </D:prop> </D:propstat> <D:propstat> <D:status>HTTP/1.1 404 Not Found</D:status> <D:prop> <D:lockdiscovery/> <D:supportedlock/> <D:getcontenttype/> <D:source/> <D:getcontentlanguage/> </D:prop> </D:propstat> </D:response> </D:multistatus> 0 PROPFIND /dav/stretzm/Briefcase/ HTTP/1.1 Host: zimbratest.example.com:8080 Connection: keep-alive User-Agent: Mozilla/5.0 (X11; Linux x86_64) KHTML/4.12.2 (like Gecko) Konqueror/4.12 Pragma: no-cache Cache-control: no-cache Accept: text/html, text/*;q=0.9, image/jpeg;q=0.9, image/png;q=0.9, image/*;q=0.9, */*;q=0.8 Accept-Encoding: gzip, deflate, x-gzip, x-deflate Accept-Charset: utf-8,*;q=0.5 Accept-Language: en-US,en;q=0.9 Authorization: Basic xxx Depth: 0 Content-Type: text/xml; charset=utf-8 Content-Length: 288 <?xml version="1.0" encoding="utf-8" ?><D:propfind xmlns:D="DAV:"><D:prop><D:creationdate/><D:getcontentlength/><D:displayname/><D:source/><D:getcontentlanguage/><D:getcontenttype/><D:getlastmodified/><D:getetag/><D:supportedlock/><D:lockdiscovery/><D:resourcetype/></D:prop></D:propfind> HTTP/1.1 207 Multi-Status Date: Wed, 05 Mar 2014 16:52:45 GMT Access-Control-Allow-Origin: *.example.com Strict-Transport-Security: max-age=31536000 DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule DAV: version-control, addressbook, extended-mkcol, calendar-proxy DAV: calendarserver-principal-property-search Content-Type: text/xml;charset=UTF-8 Transfer-Encoding: chunked 379 <?xml version="1.0" encoding="UTF-8"?> <D:multistatus xmlns:D="DAV:"> <D:response> <D:href>/dav/stretzm/Briefcase/</D:href> <D:propstat> <D:status>HTTP/1.1 200 OK</D:status> <D:prop> <D:resourcetype> <D:collection/> </D:resourcetype> <D:getlastmodified>Thu, 20 Sep 2012 15:40:37 -0000 (GMT)</D:getlastmodified> <D:getcontentlength>0</D:getcontentlength> <D:displayname>Briefcase</D:displayname> <D:getetag>"1-1"</D:getetag> <D:creationdate>2012-09-20T17:40:37+02:00</D:creationdate> </D:prop> </D:propstat> <D:propstat> <D:status>HTTP/1.1 404 Not Found</D:status> <D:prop> <D:lockdiscovery/> <D:supportedlock/> <D:getcontenttype/> <D:source/> <D:getcontentlanguage/> </D:prop> </D:propstat> </D:response> </D:multistatus> 0 PROPFIND /dav/stretzm/Briefcase/Texaco%20Barrels.JPG HTTP/1.1 Host: zimbratest.example.com:8080 Connection: keep-alive User-Agent: Mozilla/5.0 (X11; Linux x86_64) KHTML/4.12.2 (like Gecko) Konqueror/4.12 Pragma: no-cache Cache-control: no-cache Accept: text/html, text/*;q=0.9, image/jpeg;q=0.9, image/png;q=0.9, image/*;q=0.9, */*;q=0.8 Accept-Encoding: gzip, deflate, x-gzip, x-deflate Accept-Charset: utf-8,*;q=0.5 Accept-Language: en-US,en;q=0.9 Authorization: Basic xxx Depth: 0 Content-Type: text/xml; charset=utf-8 Content-Length: 288 <?xml version="1.0" encoding="utf-8" ?><D:propfind xmlns:D="DAV:"><D:prop><D:creationdate/><D:getcontentlength/><D:displayname/><D:source/><D:getcontentlanguage/><D:getcontenttype/><D:getlastmodified/><D:getetag/><D:supportedlock/><D:lockdiscovery/><D:resourcetype/></D:prop></D:propfind> HTTP/1.1 207 Multi-Status Date: Wed, 05 Mar 2014 16:53:13 GMT Access-Control-Allow-Origin: *.example.com Strict-Transport-Security: max-age=31536000 DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule DAV: version-control, addressbook, extended-mkcol, calendar-proxy DAV: calendarserver-principal-property-search Content-Type: text/xml;charset=UTF-8 Transfer-Encoding: chunked 38B <?xml version="1.0" encoding="UTF-8"?> <D:multistatus xmlns:D="DAV:"> <D:response> <D:href>/dav/stretzm/Briefcase/Texaco%20Barrels.JPG</D:href> <D:propstat> <D:status>HTTP/1.1 200 OK</D:status> <D:prop> <D:getcontenttype>image/jpeg</D:getcontenttype> <D:resourcetype/> <D:getlastmodified>Fri, 12 Oct 2012 13:13:06 -0000 (GMT)</D:getlastmodified> <D:getcontentlength>2266518</D:getcontentlength> <D:displayname>Texaco Barrels.JPG</D:displayname> <D:getetag>"4011-4011"</D:getetag> <D:creationdate>2012-10-12T15:13:06+02:00</D:creationdate> </D:prop> </D:propstat> <D:propstat> <D:status>HTTP/1.1 404 Not Found</D:status> <D:prop> <D:lockdiscovery/> <D:supportedlock/> <D:source/> <D:getcontentlanguage/> </D:prop> </D:propstat> </D:response> </D:multistatus> 0 PROPFIND /dav/stretzm/Briefcase/Texaco%20Barrels.JPG HTTP/1.1 Host: zimbratest.example.com:8080 Connection: keep-alive User-Agent: Mozilla/5.0 (X11; Linux x86_64) KHTML/4.12.2 (like Gecko) Konqueror/4.12 Pragma: no-cache Cache-control: no-cache Accept: text/html, text/*;q=0.9, image/jpeg;q=0.9, image/png;q=0.9, image/*;q=0.9, */*;q=0.8 Accept-Encoding: gzip, deflate, x-gzip, x-deflate Accept-Charset: utf-8,*;q=0.5 Accept-Language: en-US,en;q=0.9 Authorization: Basic xxx Depth: 0 Content-Type: text/xml; charset=utf-8 Content-Length: 288 <?xml version="1.0" encoding="utf-8" ?><D:propfind xmlns:D="DAV:"><D:prop><D:creationdate/><D:getcontentlength/><D:displayname/><D:source/><D:getcontentlanguage/><D:getcontenttype/><D:getlastmodified/><D:getetag/><D:supportedlock/><D:lockdiscovery/><D:resourcetype/></D:prop></D:propfind> HTTP/1.1 207 Multi-Status Date: Wed, 05 Mar 2014 16:53:19 GMT Access-Control-Allow-Origin: *.example.com Strict-Transport-Security: max-age=31536000 DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule DAV: version-control, addressbook, extended-mkcol, calendar-proxy DAV: calendarserver-principal-property-search Content-Type: text/xml;charset=UTF-8 Transfer-Encoding: chunked 38B <?xml version="1.0" encoding="UTF-8"?> <D:multistatus xmlns:D="DAV:"> <D:response> <D:href>/dav/stretzm/Briefcase/Texaco%20Barrels.JPG</D:href> <D:propstat> <D:status>HTTP/1.1 200 OK</D:status> <D:prop> <D:getcontenttype>image/jpeg</D:getcontenttype> <D:resourcetype/> <D:getlastmodified>Fri, 12 Oct 2012 13:13:06 -0000 (GMT)</D:getlastmodified> <D:getcontentlength>2266518</D:getcontentlength> <D:displayname>Texaco Barrels.JPG</D:displayname> <D:getetag>"4011-4011"</D:getetag> <D:creationdate>2012-10-12T15:13:06+02:00</D:creationdate> </D:prop> </D:propstat> <D:propstat> <D:status>HTTP/1.1 404 Not Found</D:status> <D:prop> <D:lockdiscovery/> <D:supportedlock/> <D:source/> <D:getcontentlanguage/> </D:prop> </D:propstat> </D:response> </D:multistatus> 0
There are multiple reasons why this is broken. The first one is the fact that the server uses unknown dateTime format for the "getlastmodified" property. According to RFC 2518, section 13.7 (http://tools.ietf.org/html/rfc2518#section-13.7), the format that should be used for getlastmodified is: Value: HTTP-date ; defined in section 3.3.1 of [RFC2068] And RFC2068 section 3.3.1(http://tools.ietf.org/html/rfc2068#section-3.3.1) states the following as acceptable formats: HTTP-date = rfc1123-date | rfc850-date | asctime-date We use KDateTime to parse dates using both the RFC and ISO formats. Unfortunately, the dateTime format the server returns <D:getlastmodified>Fri, 12 Oct 2012 13:13:06 -0000 (GMT)</D:getlastmodified> is neither RFC nor ISO complaint. To be compliant, it should have been specified as: <D:getlastmodified>Fri, 12 Oct 2012 13:13:06 GMT</D:getlastmodified> And that is where the second issue shows up. The kio_http dateTime parser long HttpProtocol::parseDateTime( const QString& input, const QString& type ) { if ( type == QLatin1String("dateTime.tz") ) { return KDateTime::fromString( input, KDateTime::ISODate ).toTime_t(); } else if ( type == QLatin1String("dateTime.rfc1123") ) { return KDateTime::fromString( input, KDateTime::RFCDate ).toTime_t(); } // format not advertised... try to parse anyway time_t time = KDateTime::fromString( input, KDateTime::RFCDate ).toTime_t(); if ( time != 0 ) return time; return KDateTime::fromString( input, KDateTime::ISODate ).toTime_t(); } fails to check whether the parsed string is actually a valid KDateTime object before calling toTime_t() on the assumption that invalid ones return a -1. It does not! The result is an an overflow for uint32, 2^32 -1, which results in the display of an incorrect date/time: 2^32-1 = 4294967295 $ date --date='@4294967295' Sun Feb 7 01:28:15 EST 2106 I have a patch that fixes the incorrect assumption in kio_http's date/time parser since that assumption also impacts the date/time stamps returned as part of the cache directives. However, unless we work around the issue for the incorrect format returned by this server or the server is fixed to return a complaint format per the RFC, the patch I have won't resolve this issue.
I updated the Bugzilla bug with your comments on the RFC violations. Maybe you'd like to subscribe to https://bugzilla.zimbra.com/show_bug.cgi?id=87477 as well. The date format used here is RFC 822 (http://tools.ietf.org/html/rfc822#section-5.1). Looks like somebody mixed that up with RFC 850. Which has the worst definition of a time format I ever saw (http://tools.ietf.org/html/rfc850#section-2.1.4). Hmmm... RFC 850 was obsoleted by RFC 1036 which explicitly allows the RFC 822 format (http://tools.ietf.org/html/rfc1036#section-2.1.2). A colleague told me that most other WebDAV clients interpret the malformed dates correctly. Not sure if it is worth having a workaround here for Zimbra though.
Wait... actually the used RFC 822 format should be accepted by the client (though not generated by Zimbra) as stated in RFC 2068: 3.3.1 Full Date HTTP applications have historically allowed three different formats for the representation of date/time stamps: Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123 Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036 Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format The first format is preferred as an Internet standard and represents a fixed-length subset of that defined by RFC 1123 (an update to RFC 822). The second format is in common use, but is based on the obsolete RFC 850 [12] date format and lacks a four-digit year. HTTP/1.1 clients and servers that parse the date value MUST accept all three formats (for compatibility with HTTP/1.0), though they MUST only generate the RFC 1123 format for representing HTTP-date values in header fields.
Hmm... reading the specs properly helps. Only a "fixed-length subset of that defined by RFC 1123" is allowed. Anyway, further down the RFC says: Note: Recipients of date values are encouraged to be robust in accepting date values that may have been sent by non-HTTP applications, as is sometimes the case when retrieving or posting messages via proxies/gateways to SMTP or NNTP. A simple workaround for this case would be to do a quick string replace on the header before parsing, something along the lines (sorry if the code is wrong, I haven't written any C++/Qt code in a while): else if ( type == QLatin1String("dateTime.rfc1123") ) { input.replace(QRegExp("[+-]0000 (GMT)", "GMT"); return KDateTime::fromString( input, KDateTime::RFCDate ).toTime_t(); }
Git commit daf5c44b166041a049d24c1bd9c20582b6a1d3f2 by Dawit Alemayehu. Committed on 16/01/2013 at 12:57. Pushed by adawit into branch 'KDE/4.12'. - Fix incorrect use of KDateTime::toTime_t(). It does not return a literal -1 for invalid dates. - Changed the cache related date/time variables to be 64 bit so they can accomodate much longer date ranges. REVIEW: 116784 M +61 -71 kioslave/http/http.cpp M +6 -9 kioslave/http/http.h http://commits.kde.org/kdelibs/daf5c44b166041a049d24c1bd9c20582b6a1d3f2
Update from Zimbra #87477: The format issue will be fixed in Zimbra 8.5.0. I think we can close this bug.
(In reply to comment #8) > Update from Zimbra #87477: The format issue will be fixed in Zimbra 8.5.0. I > think we can close this bug. Thanks for the heads up.