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();
}
}
}