Exemplo n.º 1
0
        /// <summary>
        ///  Locks a file or directory at the URL specified.
        /// </summary>
        /// <param name="uri">The URI of the file or directory to lock.</param>
        /// <returns>The <see cref="Task"/> representing the asynchronous operation.</returns>
        public async Task <bool> LockAsync(Uri uri)
        {
            uri = UriHelper.GetCombinedUriWithTrailingSlash(this.BaseUri, uri, true, false);

            if (this.permanentLocks.ContainsKey(uri))
            {
                return(true); // Lock already set.
            }
            var lockInfo = new LockInfo();

            lockInfo.LockScope = LockScope.CreateExclusiveLockScope();
            lockInfo.LockType  = LockType.CreateWriteLockType();
            var response = await this.webDavClient.LockAsync(uri, WebDavTimeoutHeaderValue.CreateInfiniteWebDavTimeout(), WebDavDepthHeaderValue.Infinity, lockInfo);

            if (!response.IsSuccessStatusCode)
            {
                return(false); // Lock already exists.
            }
            var lockToken = WebDavHelper.GetLockTokenFromWebDavResponseMessage(response);

            var prop = await WebDavResponseContentParser.ParsePropResponseContentAsync(response.Content);

            var lockDiscovery = prop.LockDiscovery;

            if (lockDiscovery == null)
            {
                return(false);
            }

            var url         = uri.ToString();
            var lockGranted = lockDiscovery.ActiveLock.FirstOrDefault(x => url.EndsWith(UriHelper.AddTrailingSlash(x.LockRoot.Href, false), StringComparison.OrdinalIgnoreCase));

            if (lockGranted == null)
            {
                // Try with file expected.
                lockGranted = lockDiscovery.ActiveLock.FirstOrDefault(x => url.EndsWith(UriHelper.AddTrailingSlash(x.LockRoot.Href, true), StringComparison.OrdinalIgnoreCase));
            }

            if (lockGranted == null)
            {
                return(false);
            }

            var permanentLock = new PermanentLock(this.webDavClient, lockToken, uri, lockGranted.Timeout);

            if (!this.permanentLocks.TryAdd(uri, permanentLock))
            {
                throw new WebDavException("Lock with lock root " + uri.ToString() + " already exists.");
            }

            return(response.IsSuccessStatusCode);
        }
        /// <summary>
        /// Gets a <see cref="LockToken"/> from a <see cref="WebDavResponseMessage"/>.
        /// </summary>
        /// <param name="responseMessage">The <see cref="WebDavResponseMessage"/> whose <see cref="LockToken"/> should be retrieved.</param>
        /// <returns>The <see cref="LockToken"/> of the <see cref="WebDavResponseMessage"/> or null if the WebDavResponseMessage does not contain a lock token.</returns>
        public static LockToken GetLockTokenFromWebDavResponseMessage(WebDavResponseMessage responseMessage)
        {
            // Try to get lock token from response header.
            if (responseMessage.Headers.TryGetValues(WebDavRequestHeader.LockTocken, out IEnumerable <string> lockTokenHeaderValues))
            {
                var lockTokenHeaderValue = lockTokenHeaderValues.FirstOrDefault();

                if (lockTokenHeaderValue != null)
                {
                    return(new LockToken(lockTokenHeaderValue));
                }
            }

            // If lock token was not submitted by response header, it should be found in the response content.
            try
            {
                var prop = WebDavResponseContentParser.ParsePropResponseContentAsync(responseMessage.Content).Result;
                return(new LockToken(prop.LockDiscovery.ActiveLock[0].LockToken.Href));
            }
            catch (Exception)
            {
                return(null);
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Retrieves a list of files and directories of the directory at the <see cref="Uri"/> specified using the <see cref="PropFind"/> specified.
        /// </summary>
        /// <param name="uri">The <see cref="Uri"/> of the directory which content should be listed. Has to be an absolute URI (including the base URI) or a relative URI (relative to base URI).</param>
        /// <param name="propFind">The <see cref="PropFind"/> to use. Different PropFind  types can be created using the static methods of the class <see cref="PropFind"/>.</param>
        /// <returns>The <see cref="Task"/> representing the asynchronous operation.</returns>
        public async Task <IList <WebDavSessionListItem> > ListAsync(Uri uri, PropFind propFind)
        {
            if (propFind == null)
            {
                throw new ArgumentException("Argument propFind must not be null.");
            }

            uri = UriHelper.GetCombinedUriWithTrailingSlash(this.BaseUri, uri, true, false);
            var response = await this.webDavClient.PropFindAsync(uri, WebDavDepthHeaderValue.One, propFind);

            // Remember the original port to include it in the hrefs later.
            var port = UriHelper.GetPort(uri);

            if (response.StatusCode != WebDavStatusCode.MultiStatus)
            {
                throw new WebDavException(string.Format("Error while executing ListAsync (wrong response status code). Expected status code: 207 (MultiStatus); actual status code: {0} ({1})", (int)response.StatusCode, response.StatusCode));
            }

            var multistatus = await WebDavResponseContentParser.ParseMultistatusResponseContentAsync(response.Content);

            var itemList = new List <WebDavSessionListItem>();

            foreach (var responseItem in multistatus.Response)
            {
                var webDavSessionItem = new WebDavSessionListItem();

                Uri href = null;

                if (!string.IsNullOrEmpty(responseItem.Href))
                {
                    if (Uri.TryCreate(responseItem.Href, UriKind.RelativeOrAbsolute, out href))
                    {
                        var fullQualifiedUri = UriHelper.CombineUri(uri, href, true);
                        fullQualifiedUri      = UriHelper.SetPort(fullQualifiedUri, port);
                        webDavSessionItem.Uri = fullQualifiedUri;
                    }
                }

                // Skip the folder which contents were requested, only add children.
                if (href != null && WebUtility.UrlDecode(UriHelper.RemovePort(uri).ToString().Trim('/')).EndsWith(WebUtility.UrlDecode(UriHelper.RemovePort(href).ToString().Trim('/')), StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }

                foreach (var item in responseItem.Items)
                {
                    var propStat = item as Propstat;

                    // Do not items where no properties could be found.
                    if (propStat == null || propStat.Status.ToLower().Contains("404 not found"))
                    {
                        continue;
                    }

                    // Do not add hidden items.
                    if (!string.IsNullOrEmpty(propStat.Prop.IsHidden) && propStat.Prop.IsHidden.Equals("1"))
                    {
                        continue;
                    }

                    webDavSessionItem.ContentClass    = propStat.Prop.ContentClass;
                    webDavSessionItem.ContentLanguage = propStat.Prop.GetContentLanguage;

                    if (!string.IsNullOrEmpty(propStat.Prop.GetContentLength))
                    {
                        webDavSessionItem.ContentLength = long.Parse(propStat.Prop.GetContentLength, CultureInfo.InvariantCulture);
                    }

                    webDavSessionItem.ContentType = propStat.Prop.GetContentType;

                    if (propStat.Prop.CreationDateSpecified && !string.IsNullOrEmpty(propStat.Prop.CreationDate))
                    {
                        webDavSessionItem.CreationDate = DateTime.Parse(propStat.Prop.CreationDate, CultureInfo.InvariantCulture);
                    }

                    webDavSessionItem.DefaultDocument = propStat.Prop.DefaultDocument;
                    webDavSessionItem.DisplayName     = propStat.Prop.DisplayName;
                    webDavSessionItem.ETag            = propStat.Prop.GetEtag;

                    if (!string.IsNullOrEmpty(propStat.Prop.GetLastModified))
                    {
                        webDavSessionItem.LastModified = DateTime.Parse(propStat.Prop.GetLastModified, CultureInfo.InvariantCulture);
                    }

                    if (!string.IsNullOrEmpty(propStat.Prop.IsReadonly))
                    {
                        webDavSessionItem.IsReadonly = propStat.Prop.IsReadonly.Equals("1");
                    }

                    if (!string.IsNullOrEmpty(propStat.Prop.IsRoot))
                    {
                        webDavSessionItem.IsRoot = propStat.Prop.IsRoot.Equals("1");
                    }

                    if (!string.IsNullOrEmpty(propStat.Prop.IsStructuredDocument))
                    {
                        webDavSessionItem.IsStructuredDocument = propStat.Prop.IsStructuredDocument.Equals("1");
                    }

                    if (!string.IsNullOrEmpty(propStat.Prop.LastAccessed))
                    {
                        webDavSessionItem.LastAccessed = DateTime.Parse(propStat.Prop.LastAccessed, CultureInfo.InvariantCulture);
                    }

                    webDavSessionItem.Name       = propStat.Prop.Name;
                    webDavSessionItem.ParentName = propStat.Prop.ParentName;

                    if (!string.IsNullOrEmpty(propStat.Prop.QuotaAvailableBytes))
                    {
                        webDavSessionItem.QuotaAvailableBytes = long.Parse(propStat.Prop.QuotaAvailableBytes, CultureInfo.InvariantCulture);
                    }

                    if (!string.IsNullOrEmpty(propStat.Prop.QuotaUsedBytes))
                    {
                        webDavSessionItem.QuotaUsedBytes = long.Parse(propStat.Prop.QuotaUsedBytes, CultureInfo.InvariantCulture);
                    }

                    // Make sure that the IsDirectory property is set if it's a directory.
                    if (!string.IsNullOrEmpty(propStat.Prop.IsCollection))
                    {
                        webDavSessionItem.IsCollection = propStat.Prop.IsCollection.Equals("1");
                    }
                    else if (propStat.Prop.ResourceType != null && propStat.Prop.ResourceType.Collection != null)
                    {
                        webDavSessionItem.IsCollection = true;
                    }

                    // Make sure that the name property is set.
                    // Naming priority:
                    // 1. displayname (only if it doesn't contain raw unicode, otherwise there are problems with non western characters)
                    // 2. name
                    // 3. (part of) URI.
                    if (!TextHelper.StringContainsRawUnicode(propStat.Prop.DisplayName))
                    {
                        webDavSessionItem.Name = propStat.Prop.DisplayName;
                    }

                    if (string.IsNullOrEmpty(webDavSessionItem.Name))
                    {
                        webDavSessionItem.Name = propStat.Prop.Name;
                    }

                    if (string.IsNullOrEmpty(webDavSessionItem.Name) && href != null)
                    {
                        webDavSessionItem.Name = WebUtility.UrlDecode(href.ToString().Split('/').Last(x => !string.IsNullOrEmpty(x)));
                    }
                }

                itemList.Add(webDavSessionItem);
            }

            return(itemList);
        }