private IActionResult BuildResultForStatusCode(ExceptionContext context, WebDavStatusCode statusCode, string optionalMessge)
        {
            switch (statusCode)
            {
            case WebDavStatusCode.NotModified:
                // 304 must not return a body
                return(new StatusCodeResult((int)statusCode));
            }

            var result = new WebDavResult <multistatus>(
                statusCode,
                new multistatus()
            {
                response = new[]
                {
                    new response()
                    {
                        href             = context.HttpContext.Request.GetEncodedUrl(),
                        ItemsElementName = new[] { ItemsChoiceType2.status, },
                        Items            = new object[] { new Status(context.HttpContext.Request.Protocol, statusCode, optionalMessge).ToString() },
                    },
                },
            });
            var dispatcher = context.HttpContext.RequestServices.GetService <IWebDavDispatcher>();

            return(new WebDavIndirectResult(dispatcher, result, _responseLogger));
        }
Пример #2
0
        /// <inheritdoc />
        public async Task <IWebDavResult> LockAsync(string path, lockinfo info, CancellationToken cancellationToken)
        {
            if (_lockManager == null)
            {
                throw new NotSupportedException();
            }

            var owner      = info.owner;
            var recursive  = (_context.RequestHeaders.Depth ?? DepthHeader.Infinity) == DepthHeader.Infinity;
            var accessType = LockAccessType.Write;
            var shareType  = info.lockscope.ItemElementName == ItemChoiceType.exclusive
                ? LockShareMode.Exclusive
                : LockShareMode.Shared;
            var timeout = _timeoutPolicy?.SelectTimeout(
                _context.RequestHeaders.Timeout?.Values ?? new[] { TimeoutHeader.Infinite })
                          ?? TimeoutHeader.Infinite;

            var href = GetHref(path);
            var l    = new Lock(
                path,
                href,
                recursive,
                owner,
                accessType,
                shareType,
                timeout);

            Debug.Assert(_lockManager != null, "_lockManager != null");
            var lockResult = await _lockManager.LockAsync(l, cancellationToken);

            if (lockResult.ConflictingLocks != null)
            {
                // Lock cannot be acquired
                if (lockResult.ConflictingLocks.ChildLocks.Count == 0)
                {
                    return(new WebDavResult <error>(WebDavStatusCode.Locked, CreateError(lockResult.ConflictingLocks.GetLocks())));
                }

                var errorResponses = new List <response>();
                if (lockResult.ConflictingLocks.ChildLocks.Count != 0 ||
                    lockResult.ConflictingLocks.ReferenceLocks.Count != 0)
                {
                    errorResponses.Add(CreateErrorResponse(
                                           WebDavStatusCode.Forbidden,
                                           lockResult.ConflictingLocks.ChildLocks.Concat(lockResult.ConflictingLocks.ReferenceLocks)));
                }

                if (lockResult.ConflictingLocks.ParentLocks.Count != 0)
                {
                    var errorResponse = CreateErrorResponse(
                        WebDavStatusCode.Forbidden,
                        lockResult.ConflictingLocks.ChildLocks);
                    errorResponse.error = CreateError(new IActiveLock[0]);
                    errorResponses.Add(errorResponse);
                }

                errorResponses.Add(new response()
                {
                    href             = GetHref(l.Path),
                    ItemsElementName = new[] { ItemsChoiceType2.status, },
                    Items            = new object[]
                    {
                        new Status(_context.RequestProtocol, WebDavStatusCode.FailedDependency).ToString(),
                    },
                });

                var multistatus = new multistatus()
                {
                    response = errorResponses.ToArray(),
                };

                return(new WebDavResult <multistatus>(WebDavStatusCode.MultiStatus, multistatus));
            }

            var activeLock = lockResult.Lock;

            Debug.Assert(activeLock != null, "activeLock != null");
            try
            {
                var selectionResult = await _rootFileSystem.SelectAsync(path, cancellationToken);

                WebDavStatusCode statusCode;
                if (selectionResult.IsMissing)
                {
                    if (_context.RequestHeaders.IfNoneMatch != null)
                    {
                        throw new WebDavException(WebDavStatusCode.PreconditionFailed);
                    }

                    if (selectionResult.MissingNames.Count > 1)
                    {
                        return(new WebDavResult(WebDavStatusCode.Conflict));
                    }

                    var current = selectionResult.Collection;
                    var docName = selectionResult.MissingNames.Single();
                    await current.CreateDocumentAsync(docName, cancellationToken);

                    statusCode = WebDavStatusCode.Created;
                }
                else
                {
                    await _context
                    .RequestHeaders.ValidateAsync(selectionResult.TargetEntry, cancellationToken)
                    ;

                    statusCode = WebDavStatusCode.OK;
                }

                var activeLockXml = activeLock.ToXElement();
                var result        = new prop()
                {
                    Any = new[] { new XElement(WebDavXml.Dav + "lockdiscovery", activeLockXml) },
                };
                var webDavResult = new WebDavResult <prop>(statusCode, result);
                webDavResult.Headers["Lock-Token"] = new[] { new LockTokenHeader(new Uri(activeLock.StateToken)).ToString() };
                return(webDavResult);
            }
            catch
            {
                await _lockManager
                .ReleaseAsync(activeLock.Path, new Uri(activeLock.StateToken, UriKind.RelativeOrAbsolute), cancellationToken)
                ;

                throw;
            }
        }