Bug 331774 - WebDAV(S) kioslave shows last modified timestamps on Zimbra shares as 2106-02-07 07:28 (unit32 max)
Summary: WebDAV(S) kioslave shows last modified timestamps on Zimbra shares as 2106-02...
Status: RESOLVED DOWNSTREAM
Alias: None
Product: kio
Classification: Frameworks and Libraries
Component: webdav (show other bugs)
Version: 4.12.2
Platform: Kubuntu Linux
: NOR normal
Target Milestone: ---
Assignee: kdelibs bugs
URL: https://bugzilla.zimbra.com/show_bug....
Keywords:
Depends on:
Blocks:
 
Reported: 2014-03-05 16:40 UTC by Malte S. Stretz
Modified: 2014-05-08 11:44 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments
Screenshot (115.58 KB, image/png)
2014-03-05 16:41 UTC, Malte S. Stretz
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Malte S. Stretz 2014-03-05 16:40:50 UTC
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
Comment 1 Malte S. Stretz 2014-03-05 16:41:21 UTC
Created attachment 85425 [details]
Screenshot
Comment 2 Malte S. Stretz 2014-03-05 16:58:05 UTC
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
Comment 3 Dawit Alemayehu 2014-03-08 20:32:07 UTC
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.
Comment 4 Malte S. Stretz 2014-03-10 18:38:36 UTC
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.
Comment 5 Malte S. Stretz 2014-03-10 18:44:44 UTC
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.
Comment 6 Malte S. Stretz 2014-03-10 18:55:17 UTC
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();
}
Comment 7 Dawit Alemayehu 2014-03-20 13:10:29 UTC
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
Comment 8 Malte S. Stretz 2014-05-08 10:28:42 UTC
Update from Zimbra #87477: The format issue will be fixed in Zimbra 8.5.0. I think we can close this bug.
Comment 9 Dawit Alemayehu 2014-05-08 11:44:28 UTC
(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.