2016-10-03 07:55:15 +00:00
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 {
/// <summary>
/// This is the base class for <see cref="IWebDavMethodHandler" /> implementations.
/// </summary>
public abstract class WebDavMethodHandlerBase {
private const int DepthInfinity = - 1 ;
/// <summary>
/// Retrieves a store item through the specified
/// <see cref="Uri" /> from the
/// specified
/// <see cref="WebDavServer" /> and
/// <see cref="IWebDavStore" />.
/// </summary>
/// <param name="server">The <see cref="WebDavServer" /> that hosts the <paramref name="store" />.</param>
/// <param name="store">The <see cref="IWebDavStore" /> from which to retrieve the store item.</param>
2017-11-24 10:10:22 +00:00
/// <param name="fileName">The store-relative path to the store item.</param>
2016-10-03 07:55:15 +00:00
/// <returns>
/// The retrieved store item.
/// </returns>
/// <exception cref="System.ArgumentNullException"><para>
2017-11-24 10:10:22 +00:00
/// <paramref name="fileName" /> is <c>null</c>.</para>
2016-10-03 07:55:15 +00:00
/// <para>
/// <paramref name="server" /> is <c>null</c>.</para>
/// <para>
/// <paramref name="store" /> is <c>null</c>.</para></exception>
/// <exception cref="WebDAVSharp.Server.Exceptions.WebDavNotFoundException">If the item was not found.</exception>
2017-11-24 10:10:22 +00:00
/// <exception cref="WebDavConflictException"><paramref name="fileName" /> refers to a document in a collection, where the collection does not exist.</exception>
/// <exception cref="WebDavNotFoundException"><paramref name="fileName" /> refers to a document that does not exist.</exception>
2016-10-03 07:55:15 +00:00
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 ;
}
/// <summary>
/// Get the parent collection from the requested
/// <see cref="Uri" />.
/// <see cref="WebDavException" /> 409 Conflict possible.
/// </summary>
/// <param name="server">The <see cref="WebDavServer" /> through which the request came in from the client.</param>
/// <param name="store">The <see cref="IWebDavStore" /> that the <see cref="WebDavServer" /> is hosting.</param>
/// <returns>
/// The parrent collection as an <see cref="IWebDavStoreCollection" />
/// </returns>
/// <exception cref="WebDAVSharp.Server.Exceptions.WebDavUnauthorizedException"></exception>
/// <exception cref="WebDAVSharp.Server.Exceptions.WebDavConflictException">
/// </exception>
/// <exception cref="WebDavUnauthorizedException">When the user is unauthorized and doesn't have access</exception>
/// <exception cref="WebDavConflictException">When the parent collection doesn't exist</exception>
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/<remove>/"
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 ( '/' , '\\' ) ;
}
}
/// <summary>
/// Get the item in the collection from the requested
/// <see cref="Uri" />.
/// <see cref="WebDavException" /> 409 Conflict possible.
/// </summary>
/// <param name="collection">The parent collection as a <see cref="IWebDavStoreCollection" /></param>
/// <param name="childUri">The <see cref="Uri" /> object containing the specific location of the child</param>
/// <returns>
/// The <see cref="IWebDavStoreItem" /> from the <see cref="IWebDavStoreCollection" />
/// </returns>
/// <exception cref="WebDAVSharp.Server.Exceptions.WebDavUnauthorizedException">If user is not authorized to get access to the item</exception>
/// <exception cref="WebDAVSharp.Server.Exceptions.WebDavNotFoundException">If item not found.</exception>
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('/', '\\')));
2016-10-03 09:46:05 +00:00
return Path . GetFileName ( fileName . Trim ( '/' , '\\' ) ) ;
2016-10-03 07:55:15 +00:00
}
/// <summary>
/// Gets the Depth header : 0, 1 or infinity
/// </summary>
/// <param name="request">The <see cref="IHttpListenerContext" /> with the response included</param>
/// <returns>
/// The values 0, 1 or -1 (for infinity)
/// </returns>
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 ;
}
/// <summary>
/// Gets the Overwrite header : T or F
/// </summary>
/// <param name="request">The <see cref="IHttpListenerRequest"/> has the header included</param>
/// <returns>The <see cref="bool"/> true if overwrite, false if no overwrite</returns>
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
}
/// <summary>
/// Gets the Timeout header : Second-number
/// </summary>
/// <param name="request">The request with the request included</param>
/// <returns>The value of the Timeout header as a string</returns>
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" ;
}
/// <summary>
/// Gets the Destination header as an URI
/// </summary>
/// <param name="request">The <see cref="IHttpListenerRequest"/> has the header included</param>
/// <returns>The <see cref="Uri"/> containing the destination</returns>
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 ( ) ;
}
}
}