private async Task<IReadOnlyList<EntityVersion<WebResourceName, string>>> GetVersions (DateTimeRange? range, string entityType)
{
var entities = new List<EntityVersion<WebResourceName, string>>();
try
{
var responseXml = await _webDavClient.ExecuteWebDavRequestAndReadResponse (
_serverUrl,
"REPORT",
1,
null,
null,
"application/xml",
string.Format (
@"<?xml version=""1.0""?>
<C:calendar-query xmlns:C=""urn:ietf:params:xml:ns:caldav"">
<D:prop xmlns:D=""DAV:"">
<D:getetag/>
</D:prop>
<C:filter>
<C:comp-filter name=""VCALENDAR"">
<C:comp-filter name=""{0}"">
{1}
</C:comp-filter>
</C:comp-filter>
</C:filter>
</C:calendar-query>
",
entityType,
range == null ? string.Empty : string.Format (@"<C:time-range start=""{0}"" end=""{1}""/>",
range.Value.From.ToString (s_calDavDateTimeFormatString),
range.Value.To.ToString (s_calDavDateTimeFormatString))
));
XmlNodeList responseNodes = responseXml.XmlDocument.SelectNodes ("/D:multistatus/D:response", responseXml.XmlNamespaceManager);
// ReSharper disable once LoopCanBeConvertedToQuery
// ReSharper disable once PossibleNullReferenceException
foreach (XmlElement responseElement in responseNodes)
{
var urlNode = responseElement.SelectSingleNode ("D:href", responseXml.XmlNamespaceManager);
var etagNode = responseElement.SelectSingleNode ("D:propstat/D:prop/D:getetag", responseXml.XmlNamespaceManager);
if (urlNode != null &&
etagNode != null &&
_serverUrl.AbsolutePath != UriHelper.DecodeUrlString (urlNode.InnerText))
{
var uri = new WebResourceName (urlNode.InnerText);
entities.Add (EntityVersion.Create (uri, HttpUtility.GetQuotedEtag (etagNode.InnerText)));
}
}
}
catch (WebDavClientException x)
{
// Workaround for Synology NAS, which returns 404 insteaod of an empty response if no events are present
if (x.StatusCode == HttpStatusCode.NotFound && await IsResourceCalender())
return entities;
throw;
}
return entities;
}