在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>"8d8d122a66625ca990252fae652cd2e5"</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 ...
所以問題是:如何確保我的同步標記仍然有效?所以,如果令牌有效並且沒有返回任何內容,我知道我的本地緩存是最新的,或者如果同步令牌無效,我需要進行完全同步!
服務器不必處理隨機令牌,令牌對客戶端完全不透明。此外,服務器不會過期令牌,它*可以*,這是不同的;-)我猜測SabreDAV將每個更改都附加了不斷增長的修訂版本號,同步令牌就是指這一點。當然,服務器最終可能必須刪除墓碑,但這可能是獨立運行的數據庫維護過程。 P.S. .:很可能仍然是一個SabreDAV錯誤。 – hnh
關於PS:一個不影響正確客戶端的錯誤!此外,不要做這樣的事情「」+ syncToken「 - 總是正確地對令牌進行XML編碼,它們可能包含特殊的XML字符 –
hnh