2015-06-20 45 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