using System; using System.IO; using System.Linq; using System.Web; using WebDAVSharp.Server.Adapters; using WebDAVSharp.Server.Exceptions; using WebDAVSharp.Server.Stores; namespace WebDAVSharp.Server.MethodHandlers { /// /// This is the base class for implementations. /// public abstract class WebDavMethodHandlerBase { private const int DepthInfinity = -1; /// /// Retrieves a store item through the specified /// from the /// specified /// and /// . /// /// The to retrieve the store item for. /// The that hosts the . /// The from which to retrieve the store item. /// /// The retrieved store item. /// /// /// is null. /// /// is null. /// /// is null. /// If the item was not found. /// refers to a document in a collection, where the collection does not exist. /// refers to a document that does not exist. public static IWebDavStoreItem GetItem(WebDavServer server, IWebDavStore store, String fileName) { if (server == null) throw new ArgumentNullException("server"); if (store == null) throw new ArgumentNullException("store"); if (fileName == null) throw new ArgumentNullException("fileName"); //Uri prefixUri = uri.GetPrefixUri(server); //String prefixUri = server.ServiceUrl; IWebDavStoreCollection collection = store.Root; IWebDavStoreItem item = null; //if (prefixUri.Segments.Length == uri.Segments.Length) if (fileName == "/") return collection; var dirNames = fileName.Split(new char[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries); //for (int index = prefixUri.Segments.Length; index < uri.Segments.Length; index++) { for (int index = 0; index < dirNames.Length; index++) { var dirName = dirNames[index]; //string segmentName = Uri.UnescapeDataString(uri.Segments[index]); //IWebDavStoreItem nextItem = collection.GetItemByName(segmentName.TrimEnd('/', '\\')); IWebDavStoreItem nextItem = collection.GetItemByName(dirName); if (nextItem == null) throw new WebDavNotFoundException(); //throw new WebDavConflictException(); if (index == dirNames.Length - 1) item = nextItem; else { collection = nextItem as IWebDavStoreCollection; if (collection == null) throw new WebDavNotFoundException(); } } if (item == null) throw new WebDavNotFoundException(); return item; } /// /// Get the parent collection from the requested /// . /// 409 Conflict possible. /// /// The through which the request came in from the client. /// The that the is hosting. /// The object containing the specific location of the child /// /// The parrent collection as an /// /// /// /// /// When the user is unauthorized and doesn't have access /// When the parent collection doesn't exist public static IWebDavStoreCollection GetParentCollection(WebDavServer server, IWebDavStore store, String fileName) { String parentDirName = ExtractParentName(fileName); //Uri parentCollectionUri = childUri.GetParentUri(); IWebDavStoreCollection collection; try { collection = GetItem(server, store, parentDirName) as IWebDavStoreCollection; } catch (UnauthorizedAccessException) { throw new WebDavUnauthorizedException(); } catch (WebDavNotFoundException) { throw new WebDavConflictException(); } if (collection == null) throw new WebDavConflictException(); return collection; } public static string ExtractParentName(string fileName) { if (fileName == null) throw new ArgumentNullException("fileName"); if (fileName == "/") { //TODO: better throw error? //throw new InvalidOperationException("Cannot get parent of root"); return fileName; } //get path without the last part "dir1/dir2//" return Path.GetDirectoryName(fileName.Trim('/', '\\')).Replace('\\', '/'); } public string ExtractLocalPath(WebDavServer server, string absoluteUri) { var serviceLocalPath = new Uri(server.ServiceUrl).LocalPath.Trim('/'); var startPos = absoluteUri.IndexOf(serviceLocalPath); absoluteUri = Uri.UnescapeDataString(absoluteUri); if (startPos > -1) { return '/' + absoluteUri.Substring(startPos + serviceLocalPath.Length).Trim('/', '\\'); }else { return '/' + absoluteUri.Trim('/', '\\'); } } /// /// Get the item in the collection from the requested /// . /// 409 Conflict possible. /// /// The parent collection as a /// The object containing the specific location of the child /// /// The from the /// /// If user is not authorized to get access to the item /// If item not found. public static IWebDavStoreItem GetItemFromCollection(IWebDavStoreCollection collection, String fileName) { IWebDavStoreItem item; try { item = collection.GetItemByName(ExtractFileName(fileName)); } catch (UnauthorizedAccessException) { throw new WebDavUnauthorizedException(); } catch (WebDavNotFoundException) { throw new WebDavNotFoundException(); } if (item == null) throw new WebDavNotFoundException(); return item; } public static string ExtractFileName(string fileName) { //Uri.UnescapeDataString(childUri.Segments.Last().TrimEnd('/', '\\'))); return Path.GetFileName(fileName.Trim('/', '\\')); } /// /// Gets the Depth header : 0, 1 or infinity /// /// The with the response included /// /// The values 0, 1 or -1 (for infinity) /// public static int GetDepthHeader(HttpRequest request) { // get the value of the depth header as a string string depth = request.Headers["Depth"]; // check if the string is valid or not infinity // if so, try to parse it to an int if (String.IsNullOrEmpty(depth) || depth.Equals("infinity")) return DepthInfinity; int value; if (!int.TryParse(depth, out value)) return DepthInfinity; if (value == 0 || value == 1) return value; // else, return the infinity value return DepthInfinity; } /// /// Gets the Overwrite header : T or F /// /// The has the header included /// The true if overwrite, false if no overwrite public static bool GetOverwriteHeader(HttpRequest request) { // get the value of the Overwrite header as a string string overwrite = request.Headers["Overwrite"]; // check if the string is valid and if it equals T return overwrite != null && overwrite.Equals("T"); // else, return false } /// /// Gets the Timeout header : Second-number /// /// The request with the request included /// The value of the Timeout header as a string public static string GetTimeoutHeader(HttpRequest request) { // get the value of the timeout header as a string string timeout = request.Headers["Timeout"]; // check if the string is valid or not infinity // if so, try to parse it to an int if (!String.IsNullOrEmpty(timeout) && !timeout.Equals("infinity") && !timeout.Equals("Infinite, Second-4100000000")) return timeout; // else, return the timeout value as if it was requested to be 4 days return "Second-345600"; } /// /// Gets the Destination header as an URI /// /// The has the header included /// The containing the destination public static Uri GetDestinationHeader(HttpRequest request) { // get the value of the Destination header as a string string destinationUri = request.Headers["Destination"]; // check if the string is valid if (!String.IsNullOrEmpty(destinationUri)) return new Uri(destinationUri); // else, throw exception throw new WebDavConflictException(); } } }