title: CalDav sync-token expiry
body: <p>In a <a href="https://stackoverflow.com/questions/27605220/davical-sync-token-web-request/27720483?noredirect=1#comment49876706_27720483">previous question</a>, I asked about syncing data with a DaviCal server. I ended up concluding that there was a bug on DaviCal as when querying a CalDav server with an invalid sync token, the server should return an error but, instead, it returns the whole set of events on the server.</p>
  <p>So I started looking for an alternative CalDav server. I use SabreDav. I followed their very handy tutorial <a href="http://sabre.io/dav/building-a-caldav-client/" rel="nofollow noreferrer">here</a>.</p>
  <p>On there it says:</p>
  <blockquote>
  <p>Caveats</p>
  <p>Note that a server is free to 'forget' any sync-tokens that have been previously issued. In this case it may be needed to do a full-sync again.</p>
  <p>In case the supplied sync-token is not recognized by the server, a HTTP error is emitted. SabreDAV emits a 403.</p>
  </blockquote>
  <p>That looks promising : exactly what I need !</p>
  <p>So what I do is getting my sync-token which is <code>http://sabre.io/ns/sync/15</code>.</p>
  <p>I then submit my <code>REPORT</code> query as follows (maybe that's where I do things wrong?!)</p>
  <pre><code>string syncToken = &quot;http://sabre.io/ns/sync/15&quot;;
  string body = &quot; &lt;d:sync-collection xmlns:d=\&quot;DAV:\&quot;&gt; &quot; +
                &quot;   &lt;d:sync-token&gt;&quot; + syncToken + &quot;&lt;/d:sync-token&gt; &quot; +
                &quot;   &lt;d:sync-level&gt;1&lt;/d:sync-level&gt; &quot; +
                &quot;   &lt;d:prop&gt; &quot; +
                &quot;     &lt;d:getetag/&gt; &quot; +
                &quot;   &lt;/d:prop&gt; &quot; +
                &quot; &lt;/d:sync-collection&gt; &quot;;
  Request = (HttpWebRequest)HttpWebRequest.Create(&quot;http://my.sabredav.com/calendars/example/home/&quot;);
  Request.Credentials = new NetworkCredential(&quot;my_user&quot;, &quot;my_pwd&quot;);
  Request.Method = &quot;REPORT&quot;;
  Request.ContentType = &quot;application/xml&quot;;
  // set the body of the request...
  Request.ContentLength = body.Length;
  using (Stream reqStream = Request.GetRequestStream()) {
      // Write the string to the destination as a text file.
      byte[] encodedBody = Encoding.UTF8.GetBytes(body);
      reqStream.Write(encodedBody, 0, encodedBody.Length);
      reqStream.Close();
  }
      
  // Send the method request and get the response from the server.
  Response = (HttpWebResponse)Request.GetResponse();
  </code></pre>
  <p>So when I send the request using the valid sync-token <code>http://sabre.io/ns/sync/15</code> I just got, I get an empty response:</p>
  <pre><code>&lt;?xml version=&quot;1.0&quot;?&gt;
      &lt;d:multistatus xmlns:d=&quot;DAV:&quot; xmlns:s=&quot;http://sabredav.org/ns&quot; xmlns:cal=&quot;urn:ietf:params:xml:ns:caldav&quot; xmlns:cs=&quot;http://calendarserver.or /ns/&quot;&gt;
      &lt;d:sync-token&gt;http://sabre.io/ns/sync/15&lt;/d:sync-token&gt;
  &lt;/d:multistatus&gt;
  </code></pre>
  <p>So far so good.</p>
  <p>If I use a previous sync-token that I know was valid at some point (<code>http://sabre.io/ns/sync/14</code> in this case - by chance it is the previous number...) I get changes as expected:</p>
  <pre><code>    &lt;?xml version=&quot;1.0&quot;?&gt;
      &lt;d:multistatus xmlns:d=&quot;DAV:&quot; xmlns:s=&quot;http://sabredav.org/ns&quot; xmlns:cal=&quot;urn:ietf:params:xml:ns:caldav&quot; xmlns:cs=&quot;http://calendarserver.org/ns/&quot;&gt;
       &lt;d:response&gt;
        &lt;d:href&gt;/calendarserver.php/calendars/admin/default/23b351ee-7677-46e3-b5c5-5263e8fca351.ics&lt;/d:href&gt;
        &lt;d:propstat&gt;
         &lt;d:prop&gt;
          &lt;d:getetag&gt;&amp;quot;8d8d122a66625ca990252fae652cd2e5&amp;quot;&lt;/d:getetag&gt;
         &lt;/d:prop&gt;
         &lt;d:status&gt;HTTP/1.1 200 OK&lt;/d:status&gt;
        &lt;/d:propstat&gt;
       &lt;/d:response&gt;
       &lt;d:sync-token&gt;http://sabre.io/ns/sync/15&lt;/d:sync-token&gt;
      &lt;/d:multistatus&gt;
  </code></pre>
  <p>But the issue is, that if I use a RANDOM sync token that I definitely know has never been issued: <code>http://sabre.io/ns/sync/1234312231344324</code></p>
  <p>I get the SAME answer as when I was using the latest (current) token:</p>
  <pre><code>    &lt;?xml version=&quot;1.0&quot;?&gt;
      &lt;d:multistatus xmlns:d=&quot;DAV:&quot; xmlns:s=&quot;http://sabredav.org/ns&quot; xmlns:cal=&quot;urn:ietf:params:xml:ns:caldav&quot; xmlns:cs=&quot;http://calendarserver.org/ns/&quot;&gt;
       &lt;d:sync-token&gt;http://sabre.io/ns/sync/15&lt;/d:sync-token&gt;
      &lt;/d:multistatus&gt;
  </code></pre>
  <p>SabreDav says it's supposed to throw an error 403, but clearly, it's not what I get here... However, if I use INVALID sync-token format, say <code>token1234</code>, I do indeed get an error 403...</p>
  <p>So the question is: HOW can I make sure my sync-token is still valid ? So, if the token is valid and nothing is returned, I know my local cache is up to date or, in case the sync-token is INVALID, I need to do full sync!</p>