Ejemplo n.º 1
0
    protected sealed override HttpStatusCode ProcessRequestInternal(HttpContext context)
    {
        // get the source and destination
        var source            = context.GetDocument();
        var destinationHeader = context.Request.Headers["Destination"];

        if (string.IsNullOrEmpty(destinationHeader) || !Uri.TryCreate(destinationHeader, UriKind.RelativeOrAbsolute, out var destinationUri))
        {
            throw WebDAVException.RequestHeaderInvalidDestination();
        }
        var destination = context.TryGetDocument(destinationUri, out var destinationCollection, out var destinationName);

        // check if there already is such a document
        if (destination != null)
        {
            // fail if it's not a document or the same path
            if (source.Path == destination.Path)
            {
                throw WebDAVException.ResourceIsIdentical();
            }

            // ensure override is allowed and delete the old document
            if (!string.Equals(context.Request.Headers["Overwrite"], "T", StringComparison.OrdinalIgnoreCase))
            {
                throw WebDAVException.ResourceAlreadyExists();
            }
            destination.Delete();
        }

        // copy or move the source document to the destination
        PerformOperation(source, destinationUri, destinationCollection, destinationName);

        // return success and indicate whether a document was replaces
        return(destination == null ? HttpStatusCode.Created : HttpStatusCode.NoContent);
    }
Ejemplo n.º 2
0
    protected XmlElement ReadXml(HttpContext context, string documentElementName)
    {
        // parse the request as XML
        var doc = new XmlDocument();

        using (var reader = new StreamReader(context.Request.InputStream, context.Request.ContentEncoding))
        {
            try
            {
                doc.Load(reader);
            }
            catch (XmlException)
            {
                throw WebDAVException.RequestInvalidXml();
            }
        }

        // ensure and return the proper document element
        var documentElement = doc.DocumentElement;

        if (documentElement == null || documentElement.LocalName != documentElementName || documentElement.NamespaceURI != DAV)
        {
            throw WebDAVException.RequestXmlInvalidRootElement(documentElementName);
        }
        return(documentElement);
    }
Ejemplo n.º 3
0
 public void ProcessRequest(HttpContext context)
 {
     // process the request
     try
     {
         using var scope             = new TransactionScope();
         context.Response.StatusCode = (int)ProcessRequestInternal(context);
         scope.Complete();
     }
     catch (VivendiException e) { HandleException(context, WebDAVException.FromVivendiException(e)); }
     catch (WebDAVException e) { HandleException(context, e); }
 }
Ejemplo n.º 4
0
    protected override HttpStatusCode ProcessRequestInternal(HttpContext context)
    {
        // try to find the resource and return the appropriate response if there is one
        var res = context.TryGetResource();

        if (res != null)
        {
            return(HttpStatusCode.MethodNotAllowed);
        }

        // we don't support creations of collections
        throw WebDAVException.ResourceCollectionsImmutable();
    }
Ejemplo n.º 5
0
        public async Task <bool> Connect(string url, string username, string passw, string dom)
        {
            client = new Client(new NetworkCredential {
                UserName = username, Password = passw
            });
            client.BasePath = "/";
            client.Server   = url;
            c.Server        = url;
            c.User          = username;
            c.Pass          = passw;
            c.BasePath      = "/";
            try
            {
                IDictionary <string, string> headers = new Dictionary <string, string>();
                headers.Add("Depth", "0");
                HttpResponseMessage response = null;

                Uri ServerAdress = new Uri(url);
                response = await client.HttpRequest(ServerAdress, Prop, headers, Encoding.UTF8.GetBytes(PropFindRequestContent)).ConfigureAwait(false);

                if (response.StatusCode != (HttpStatusCode)207)
                {
                    connectSuccess = false;
                    WebDAVException ex = new WebDAVException((int)response.StatusCode, string.Format("Не удалось подключиться к серверу (Status Code: {0})", response.StatusCode));
                    throw ex;
                }
                connectSuccess = true;
                //ConnectDiag.Hide();
            }
            catch (WebDAVException ex)
            {
                connectSuccess = false;
                //ConnectDiag.Hide();
                System.Console.WriteLine(ex.ToString());
                Informator.ShowError("Connection failure");
            }
            catch (WebException e)
            {
                //ConnectDiag.Hide();
                connectSuccess = false;
                Informator.ShowError(e.Message);
            }
            catch (Exception e)
            {
                //ConnectDiag.Hide();
                connectSuccess = false;
                Exception ex = e.InnerException ?? e;
                Informator.ShowError("Unable to connect to the remote server.\nReason: " + ex.Message, null);
            }
            return(connectSuccess);
        }
Ejemplo n.º 6
0
    public static Uri VerifyUri(this HttpContext context, Uri uri)
    {
        // if it's a relative URI, return an absolute one
        if (!uri.IsAbsoluteUri)
        {
            return(new Uri(context.Request.Url, uri));
        }

        // ensure the URI is at the same server
        if (!new Uri(context.Request.Url, "/").IsBaseOf(uri))
        {
            throw WebDAVException.RequestDifferentStore(uri);
        }
        return(uri);
    }
Ejemplo n.º 7
0
 private void HandleException(HttpContext context, WebDAVException e)
 {
     context.Response.TrySkipIisCustomErrors = true;
     context.Response.StatusCode             = e.StatusCode;
     if (e.PostConditionCode != null)
     {
         var doc = new XmlDocument();
         doc.AppendChild(doc.CreateElement("error", DAV)).AppendChild(doc.CreateElement(e.PostConditionCode, DAV));
         WriteXml(context, doc);
     }
     else
     {
         context.Response.Write(e.Message);
     }
 }
Ejemplo n.º 8
0
    protected override HttpStatusCode ProcessRequestInternal(HttpContext context)
    {
        // determine which elements should be set or removed
        var resources             = Enumerable.Repeat(context.GetResource(), 1);
        var propertyupdateElement = ReadXml(context, "propertyupdate");
        var actions = new Dictionary <PropertyName, XmlElement?>();

        foreach (var element in propertyupdateElement.ChildNodes.OfType <XmlElement>().Where(e => e.NamespaceURI == DAV))
        {
            // check if it's a set or remove operation
            bool isSet;
            switch (element.LocalName)
            {
            case "set":
                isSet = true;
                break;

            case "remove":
                isSet = false;
                break;

            default:
                continue;
            }

            // find the single prop child
            var propElements = element.ChildNodes.OfType <XmlElement>().Where(e => e.LocalName == "prop" && e.NamespaceURI == DAV);
            if (propElements.Count() != 1)
            {
                throw WebDAVException.RequestXmlInvalidSetOrRemoveElement();
            }

            // store all property names and their values
            foreach (var valueElement in propElements.Single().ChildNodes.OfType <XmlElement>())
            {
                actions[new PropertyName(valueElement)] = isSet ? valueElement : null;
            }
        }

        // ensure there is something to do
        if (actions.Count == 0)
        {
            throw WebDAVException.RequestXmlInvalidProperyUpdateEement();
        }

        // perform the actions and build the response
        return(ProcessRequestInternal(context, resources, actions.Keys, (prop, res, _) => prop.Set(res, actions[prop.Name] ?? throw WebDAVException.PropertyNotRemovable())));
    }
Ejemplo n.º 9
0
    private static VivendiDocument?TryGetDocumentInternal(HttpContext context, Uri uri, out VivendiCollection parentCollection, out string name)
    {
        // try to get the resource
        var res = TryGetResourceInternal(context, uri, out parentCollection, out name, out var isCollection);

        if (res == null)
        {
            // if the URI ends with a slash also treat it as a collection
            if (isCollection)
            {
                throw WebDAVException.ResourceCollectionsImmutable();
            }
            return(null);
        }

        // ensure the value is a document
        return(res as VivendiDocument ?? throw WebDAVException.ResourceCollectionsImmutable());
    }
Ejemplo n.º 10
0
        /// <summary>
        /// List all files present on the server.
        /// </summary>
        /// <returns>A list of files (entries without a trailing slash) and directories (entries with a trailing slash)</returns>
        private async Task <Item> Get(Uri listUri, string path)
        {
            // Depth header: http://webdav.org/specs/rfc4918.html#rfc.section.9.1.4
            IDictionary <string, string> headers = new Dictionary <string, string>();

            headers.Add("Depth", "0");


            HttpResponseMessage response = null;

            try
            {
                response = await HttpRequest(listUri, PropFind, headers, Encoding.UTF8.GetBytes(PropFindRequestContent)).ConfigureAwait(false);

                if (response.StatusCode != HttpStatusCode.OK &&
                    (int)response.StatusCode != HttpStatusCode_MultiStatus)
                {
                    WebDAVException ex = new WebDAVException((int)response.StatusCode, string.Format("Failed retrieving item/folder (Status Code: {0})", response.StatusCode));
                    throw ex;
                }

                using (var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
                {
                    var result = ResponseParser.ParseItem(stream);

                    if (result == null)
                    {
                        WebDAVException ex = new WebDAVException("Failed deserializing data returned from server.");
                        throw ex;
                    }

                    return(result);
                }
            }
            finally
            {
                if (response != null)
                {
                    response.Dispose();
                }
            }
        }
Ejemplo n.º 11
0
 private static VivendiResource GetResourceInternal(HttpContext context, Uri uri) => TryGetResourceInternal(context, uri, out _, out _, out _) ?? throw WebDAVException.ResourceNotFound(uri);
Ejemplo n.º 12
0
 private static VivendiDocument GetDocumentInternal(HttpContext context, Uri uri) => GetResourceInternal(context, uri) as VivendiDocument ?? throw WebDAVException.ResourceCollectionsImmutable();
Ejemplo n.º 13
0
    private static VivendiResource?TryGetResourceInternal(HttpContext context, Uri uri, out VivendiCollection parentCollection, out string name, out bool isCollection)
    {
        // ensure authentication
        if (!context.User.Identity.IsAuthenticated)
        {
            throw new UnauthorizedAccessException();
        }
        var userName = context.User.Identity.Name;

        if (string.IsNullOrEmpty(userName))
        {
            throw new UnauthorizedAccessException();
        }

        // ensure the URI refers to the same store
        var localPath = uri.LocalPath;
        var prefix    = context.Request.ApplicationPath;

        if (!localPath.StartsWith(prefix, Vivendi.PathComparison) || (localPath = localPath.Substring(prefix.Length)).Length > 0 && localPath[0] != '/')
        {
            throw WebDAVException.RequestDifferentStore(uri);
        }

        // check for empty segments before splitting
        if (localPath.Contains("//"))
        {
            throw WebDAVException.RequestInvalidPath(uri);
        }
        var segments = localPath.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);

        // super users specify the real user in the first segment
        if (ConfigurationManager.AppSettings.GetValues("SuperUser")?.Any(su => string.Equals(userName, su, StringComparison.OrdinalIgnoreCase)) ?? false)
        {
            if (segments.Length == 0)
            {
                // the Windows Redirector does not like it if there is no root
                parentCollection = VivendiCollection.CreateStaticRoot();
            }
            else
            {
                parentCollection = GetRoot(context, segments[0], true);
            }
        }
        else
        {
            // strip away the domain part if there is one
            var domainSep = userName.IndexOf('\\');
            parentCollection = GetRoot(context, domainSep > -1 ? userName.Substring(domainSep + 1) : userName, false);
        }

        // traverse all parts starting at the root
        name         = string.Empty;
        isCollection = localPath.Length > 0 && localPath[localPath.Length - 1] == '/';
        var result = parentCollection as VivendiResource;

        foreach (var segment in segments)
        {
            // ensure that the parent is a collection and get the next child
            parentCollection = result as VivendiCollection ?? throw WebDAVException.ResourceParentNotFound(uri);
            name             = segment;
            result           = parentCollection.GetChild(name);
        }

        // ensure that no document URI ends in a trailing slash
        if (isCollection && result != null && !(result is VivendiCollection))
        {
            throw WebDAVException.ResourceParentNotFound(uri);
        }
        return(result);
    }
Ejemplo n.º 14
0
    protected override HttpStatusCode ProcessRequestInternal(HttpContext context)
    {
        // initialize the variables and check if there is a request body
        var resource      = context.GetResource();
        var allpropCount  = 0;
        var propnameCount = 0;
        var propCount     = 0;
        var propertyNames = Property.All.Select(p => p.Name);

        if (context.Request.ContentLength == 0)
        {
            // handle an empty request as allprop
            allpropCount = 1;
        }
        else
        {
            // determine what properties should be queried
            var propfindElement = ReadXml(context, "propfind");
            foreach (var element in propfindElement.ChildNodes.OfType <XmlElement>().Where(e => e.NamespaceURI == DAV))
            {
                switch (element.LocalName)
                {
                case "allprop":
                    allpropCount++;
                    break;

                case "propname":
                    propnameCount++;
                    break;

                case "prop":
                    propCount++;
                    propertyNames = element.ChildNodes.OfType <XmlElement>().Select(e => new PropertyName(e)).Distinct();
                    break;
                }
            }

            // ensure the request is valid
            if (allpropCount + propnameCount + propCount != 1)
            {
                throw WebDAVException.RequestXmlInvalidPropfindElement();
            }
        }

        // check the requested depth
        var resources = Enumerable.Repeat(resource, 1);

        switch (context.Request.Headers["Depth"])
        {
        case null:
        case "":
        case "infinity":
            // return a more informative error that infinite depths are not allowed
            throw WebDAVException.RequestHeaderInifiniteDepthNotSupported();

        case "1":
            // also return all children if the resource is a collection
            if (resource is VivendiCollection collection)
            {
                resources = resources.Concat(collection.Children);
            }
            break;

        case "0":
            break;

        default:
            throw WebDAVException.RequestHeaderInvalidDepth();
        }

        // build the response
        return(ProcessRequestInternal(context, resources, propertyNames, (prop, res, val) => { if (propnameCount == 0)
                                                                                               {
                                                                                                   prop.Get(res, val);
                                                                                               }
                                      }));
    }