2015-06-20 105 views
0

previous question中,我询问了如何与DaviCal服务器同步数据。我最终得出结论,在DaviCal上存在一个错误,因为使用无效的同步令牌查询CalDav服务器时,服务器应该返回一个错误,而是返回服务器上的整套事件。CalDav同步令牌失效

所以我开始寻找替代CalDav服务器。我使用SabreDav。我遵循他们非常方便的教程here

在那里说:

注意事项

注意,一台服务器可以自由地“忘记”先前已发布的任何同步令牌。在这种情况下,可能需要再次进行完全同步。

如果提供的同步令牌未被服务器识别,则会发出HTTP错误。 SabreDAV发出403.

这看起来很有前途:正是我所需要的!

所以我做的是让我的同步令牌是http://sabre.io/ns/sync/15

然后提交我的REPORT查询,如下所示(也许这就是我做的事情错了?!)

string syncToken = "http://sabre.io/ns/sync/15"; 
string body = " <d:sync-collection xmlns:d=\"DAV:\"> " + 
       " <d:sync-token>" + syncToken + "</d:sync-token> " + 
       " <d:sync-level>1</d:sync-level> " + 
       " <d:prop> " + 
       "  <d:getetag/> " + 
       " </d:prop> " + 
       " </d:sync-collection> "; 
Request = (HttpWebRequest)HttpWebRequest.Create("http://my.sabredav.com/calendars/example/home/"); 
Request.Credentials = new NetworkCredential("my_user", "my_pwd"); 
Request.Method = "REPORT"; 
Request.ContentType = "application/xml"; 
// 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(); 

所以,当我发送使用请求的有效同步令牌http://sabre.io/ns/sync/15我刚刚得到,我得到一个空响应:

<?xml version="1.0"?> 
    <d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.or /ns/"> 
    <d:sync-token>http://sabre.io/ns/sync/15</d:sync-token> 
</d:multistatus> 

到目前为止好。

如果我用以前的同步令牌,我知道的是,在某些时候有效(在这种情况下http://sabre.io/ns/sync/14 - 通过的可能性是对上号......)我得到改变预期:

<?xml version="1.0"?> 
    <d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/"> 
    <d:response> 
     <d:href>/calendarserver.php/calendars/admin/default/23b351ee-7677-46e3-b5c5-5263e8fca351.ics</d:href> 
     <d:propstat> 
     <d:prop> 
     <d:getetag>&quot;8d8d122a66625ca990252fae652cd2e5&quot;</d:getetag> 
     </d:prop> 
     <d:status>HTTP/1.1 200 OK</d:status> 
     </d:propstat> 
    </d:response> 
    <d:sync-token>http://sabre.io/ns/sync/15</d:sync-token> 
    </d:multistatus> 

但问题是,如果我使用随机同步令牌,我肯定知道从未发出:http://sabre.io/ns/sync/1234312231344324

我得到了同样的答案,当我使用的是最新(当前)令牌:

<?xml version="1.0"?> 
    <d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/"> 
    <d:sync-token>http://sabre.io/ns/sync/15</d:sync-token> 
    </d:multistatus> 

SabreDav说它应该抛出一个错误403,但显然,这不是我在这里得到的...但是,如果我使用INVALID同步令牌格式,比如说token1234,那么确实会得到一个错误403 ...

所以问题是:如何确保我的同步标记仍然有效?所以,如果令牌有效并且没有返回任何内容,我知道我的本地缓存是最新的,或者如果同步令牌无效,我需要进行完全同步!

+0

服务器不必处理随机令牌,令牌对客户端完全不透明。此外,服务器不会过期令牌,它*可以*,这是不同的;-)我猜测SabreDAV将每个更改都附加了不断增长的修订版本号,同步令牌就是指这一点。当然,服务器最终可能必须删除墓碑,但这可能是独立运行的数据库维护过程。 P.S. .:很可能仍然是一个SabreDAV错误。 – hnh

+1

关于PS:一个不影响正确客户端的错误!此外,不要做这样的事情“”+ syncToken“ - 总是正确地对令牌进行XML编码,它们可能包含特殊的XML字符 – hnh

回答

0

这的确是saber/dav中的一个bug。随时打开一个错误报告,这是我们的雷达。它从来不是一个主要问题,因为“行为良好的客户”永远不会提供我们从未发布的同步标记。

它发生的原因是因为数字在我们的数据库中只是一个不断增加的记录ID。要获取所有更改,请使用>执行简单的SQL查询。

如果您明确要在您的客户端中测试无效令牌,我会建议仅使用完全不同的格式(不以http://sabre.io/ns/sync开头的内容)提供同步令牌。

+0

好的,我当然不会使用sync-如果有一个过期的同步令牌,我必须能够测试我的客户端 - 这就是为什么我尝试了随机数字的原因 那么,问题可能只是 - **是什么**服务器忘记同步令牌和** **如何可以测试我的客户使用过期同步令牌? – neggenbe

+0

我认为埃弗特说sabreDAV永不过期的令牌。 – hnh

+0

好等等教程sabreDav评论是毫无意义? – neggenbe