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); }
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); }
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); } }
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(); }
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); }
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); }
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); } }
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()))); }
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()); }
/// <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(); } } }
private static VivendiResource GetResourceInternal(HttpContext context, Uri uri) => TryGetResourceInternal(context, uri, out _, out _, out _) ?? throw WebDAVException.ResourceNotFound(uri);
private static VivendiDocument GetDocumentInternal(HttpContext context, Uri uri) => GetResourceInternal(context, uri) as VivendiDocument ?? throw WebDAVException.ResourceCollectionsImmutable();
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); }
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); } })); }