diff --git a/src/FubarDev.WebDavServer/Properties/Resources.Designer.cs b/src/FubarDev.WebDavServer/Properties/Resources.Designer.cs index 7398bb3b..7b75ced2 100644 --- a/src/FubarDev.WebDavServer/Properties/Resources.Designer.cs +++ b/src/FubarDev.WebDavServer/Properties/Resources.Designer.cs @@ -1,6 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. +// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -11,32 +12,46 @@ namespace FubarDev.WebDavServer.Properties { using System; - [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [System.Diagnostics.DebuggerNonUserCodeAttribute()] - [System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { - private static System.Resources.ResourceManager resourceMan; + private static global::System.Resources.ResourceManager resourceMan; - private static System.Globalization.CultureInfo resourceCulture; + private static global::System.Globalization.CultureInfo resourceCulture; - [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal Resources() { } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] - internal static System.Resources.ResourceManager ResourceManager { + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { get { - if (object.Equals(null, resourceMan)) { - System.Resources.ResourceManager temp = new System.Resources.ResourceManager("FubarDev.WebDavServer.Properties.Resources", typeof(Resources).Assembly); + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("FubarDev.WebDavServer.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; } } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] - internal static System.Globalization.CultureInfo Culture { + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { get { return resourceCulture; } @@ -45,303 +60,471 @@ internal static System.Globalization.CultureInfo Culture { } } - internal static string ArgumentOutOfRange_BiggerThanCollection { + /// + /// Looks up a localized string similar to Array lengths must be the same.. + /// + internal static string Arg_ArrayLengthsDiffer { get { - return ResourceManager.GetString("ArgumentOutOfRange_BiggerThanCollection", resourceCulture); + return ResourceManager.GetString("Arg_ArrayLengthsDiffer", resourceCulture); } } - internal static string ArgumentOutOfRange_Count { + /// + /// Looks up a localized string similar to Destination array is not long enough to copy all the items in the collection. Check array index and length.. + /// + internal static string Arg_ArrayPlusOffTooSmall { get { - return ResourceManager.GetString("ArgumentOutOfRange_Count", resourceCulture); + return ResourceManager.GetString("Arg_ArrayPlusOffTooSmall", resourceCulture); } } - internal static string ArgumentOutOfRange_Index { + /// + /// Looks up a localized string similar to Only supported array types for CopyTo on BitArrays are Boolean[], Int32[] and Byte[].. + /// + internal static string Arg_BitArrayTypeUnsupported { get { - return ResourceManager.GetString("ArgumentOutOfRange_Index", resourceCulture); + return ResourceManager.GetString("Arg_BitArrayTypeUnsupported", resourceCulture); } } - internal static string ArgumentOutOfRange_ListInsert { + /// + /// Looks up a localized string similar to HashSet capacity is too big.. + /// + internal static string Arg_HSCapacityOverflow { get { - return ResourceManager.GetString("ArgumentOutOfRange_ListInsert", resourceCulture); + return ResourceManager.GetString("Arg_HSCapacityOverflow", resourceCulture); } } - internal static string ArgumentOutOfRange_NeedNonNegNum { + /// + /// Looks up a localized string similar to Hashtable's capacity overflowed and went negative. Check load factor, capacity and the current size of the table.. + /// + internal static string Arg_HTCapacityOverflow { get { - return ResourceManager.GetString("ArgumentOutOfRange_NeedNonNegNum", resourceCulture); + return ResourceManager.GetString("Arg_HTCapacityOverflow", resourceCulture); } } - internal static string ArgumentOutOfRange_NeedNonNegNumRequired { + /// + /// Looks up a localized string similar to Insufficient space in the target location to copy the information.. + /// + internal static string Arg_InsufficientSpace { get { - return ResourceManager.GetString("ArgumentOutOfRange_NeedNonNegNumRequired", resourceCulture); + return ResourceManager.GetString("Arg_InsufficientSpace", resourceCulture); } } - internal static string ArgumentOutOfRange_SmallCapacity { + /// + /// Looks up a localized string similar to Multi dimension array is not supported on this operation.. + /// + internal static string Arg_MultiRank { get { - return ResourceManager.GetString("ArgumentOutOfRange_SmallCapacity", resourceCulture); + return ResourceManager.GetString("Arg_MultiRank", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The lower bound of target array must be zero.. + /// + internal static string Arg_NonZeroLowerBound { + get { + return ResourceManager.GetString("Arg_NonZeroLowerBound", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Only single dimensional arrays are supported for the requested action.. + /// + internal static string Arg_RankMultiDimNotSupported { + get { + return ResourceManager.GetString("Arg_RankMultiDimNotSupported", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The value '{0}' is not of type '{1}' and cannot be used in this generic collection.. + /// + internal static string Arg_WrongType { + get { + return ResourceManager.GetString("Arg_WrongType", resourceCulture); } } + /// + /// Looks up a localized string similar to An item with the same key has already been added.. + /// internal static string Argument_AddingDuplicate { get { return ResourceManager.GetString("Argument_AddingDuplicate", resourceCulture); } } + /// + /// Looks up a localized string similar to The input array length must not exceed Int32.MaxValue / {0}. Otherwise BitArray.Length would exceed Int32.MaxValue.. + /// internal static string Argument_ArrayTooLarge { get { return ResourceManager.GetString("Argument_ArrayTooLarge", resourceCulture); } } + /// + /// Looks up a localized string similar to At least one object must implement IComparable.. + /// internal static string Argument_ImplementIComparable { get { return ResourceManager.GetString("Argument_ImplementIComparable", resourceCulture); } } + /// + /// Looks up a localized string similar to Type of argument is not compatible with the generic comparer.. + /// internal static string Argument_InvalidArgumentForComparison { get { return ResourceManager.GetString("Argument_InvalidArgumentForComparison", resourceCulture); } } + /// + /// Looks up a localized string similar to Target array type is not compatible with the type of items in the collection.. + /// internal static string Argument_InvalidArrayType { get { return ResourceManager.GetString("Argument_InvalidArrayType", resourceCulture); } } + /// + /// Looks up a localized string similar to Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection.. + /// internal static string Argument_InvalidOffLen { get { return ResourceManager.GetString("Argument_InvalidOffLen", resourceCulture); } } - internal static string Arg_ArrayLengthsDiffer { - get { - return ResourceManager.GetString("Arg_ArrayLengthsDiffer", resourceCulture); - } - } - - internal static string Arg_ArrayPlusOffTooSmall { - get { - return ResourceManager.GetString("Arg_ArrayPlusOffTooSmall", resourceCulture); - } - } - - internal static string Arg_BitArrayTypeUnsupported { + /// + /// Looks up a localized string similar to Larger than collection size.. + /// + internal static string ArgumentOutOfRange_BiggerThanCollection { get { - return ResourceManager.GetString("Arg_BitArrayTypeUnsupported", resourceCulture); + return ResourceManager.GetString("ArgumentOutOfRange_BiggerThanCollection", resourceCulture); } } - internal static string Arg_HSCapacityOverflow { + /// + /// Looks up a localized string similar to Count must be positive and count must refer to a location within the string/array/collection.. + /// + internal static string ArgumentOutOfRange_Count { get { - return ResourceManager.GetString("Arg_HSCapacityOverflow", resourceCulture); + return ResourceManager.GetString("ArgumentOutOfRange_Count", resourceCulture); } } - internal static string Arg_HTCapacityOverflow { + /// + /// Looks up a localized string similar to Index was out of range. Must be non-negative and less than the size of the collection.. + /// + internal static string ArgumentOutOfRange_Index { get { - return ResourceManager.GetString("Arg_HTCapacityOverflow", resourceCulture); + return ResourceManager.GetString("ArgumentOutOfRange_Index", resourceCulture); } } - internal static string Arg_InsufficientSpace { + /// + /// Looks up a localized string similar to Index must be within the bounds of the List.. + /// + internal static string ArgumentOutOfRange_ListInsert { get { - return ResourceManager.GetString("Arg_InsufficientSpace", resourceCulture); + return ResourceManager.GetString("ArgumentOutOfRange_ListInsert", resourceCulture); } } - internal static string Arg_MultiRank { + /// + /// Looks up a localized string similar to Non-negative number required.. + /// + internal static string ArgumentOutOfRange_NeedNonNegNum { get { - return ResourceManager.GetString("Arg_MultiRank", resourceCulture); + return ResourceManager.GetString("ArgumentOutOfRange_NeedNonNegNum", resourceCulture); } } - internal static string Arg_NonZeroLowerBound { + /// + /// Looks up a localized string similar to Non-negative number required.. + /// + internal static string ArgumentOutOfRange_NeedNonNegNumRequired { get { - return ResourceManager.GetString("Arg_NonZeroLowerBound", resourceCulture); + return ResourceManager.GetString("ArgumentOutOfRange_NeedNonNegNumRequired", resourceCulture); } } - internal static string Arg_RankMultiDimNotSupported { + /// + /// Looks up a localized string similar to capacity was less than the current size.. + /// + internal static string ArgumentOutOfRange_SmallCapacity { get { - return ResourceManager.GetString("Arg_RankMultiDimNotSupported", resourceCulture); + return ResourceManager.GetString("ArgumentOutOfRange_SmallCapacity", resourceCulture); } } - internal static string Arg_WrongType { + /// + /// Looks up a localized string similar to Not an accepted list of conditions. + /// + internal static string ConditionListNotAcceptible { get { - return ResourceManager.GetString("Arg_WrongType", resourceCulture); + return ResourceManager.GetString("ConditionListNotAcceptible", resourceCulture); } } + /// + /// Looks up a localized string similar to Destination array is not long enough to copy all the items in the collection. Check array index and length.. + /// internal static string CopyTo_ArgumentsTooSmall { get { return ResourceManager.GetString("CopyTo_ArgumentsTooSmall", resourceCulture); } } + /// + /// Looks up a localized string similar to The specified TValueCollection creates collections that have IsReadOnly set to true by default. TValueCollection must be a mutable ICollection.. + /// internal static string Create_TValueCollectionReadOnly { get { return ResourceManager.GetString("Create_TValueCollectionReadOnly", resourceCulture); } } + /// + /// Looks up a localized string similar to {0} is not a valid condition (ETag not ending with ']'). + /// + internal static string ETagNotEndingWithBracket { + get { + return ResourceManager.GetString("ETagNotEndingWithBracket", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The LinkedList node does not belong to current LinkedList.. + /// internal static string ExternalLinkedListNode { get { return ResourceManager.GetString("ExternalLinkedListNode", resourceCulture); } } + /// + /// Looks up a localized string similar to Index {0} is out of range.. + /// internal static string IndexOutOfRange { get { return ResourceManager.GetString("IndexOutOfRange", resourceCulture); } } - internal static string InvalidOperation_EmptyQueue { + /// + /// Looks up a localized string similar to Target array type is not compatible with the type of items in the collection.. + /// + internal static string Invalid_Array_Type { get { - return ResourceManager.GetString("InvalidOperation_EmptyQueue", resourceCulture); + return ResourceManager.GetString("Invalid_Array_Type", resourceCulture); } } - internal static string InvalidOperation_EmptyStack { + /// + /// Looks up a localized string similar to {0} is not a valid Coded-URL (not ending with '>'). + /// + internal static string InvalidCodedUrl { get { - return ResourceManager.GetString("InvalidOperation_EmptyStack", resourceCulture); + return ResourceManager.GetString("InvalidCodedUrl", resourceCulture); } } - internal static string InvalidOperation_EnumEnded { + /// + /// Looks up a localized string similar to Argument must be one of "0", "1", or "infinity". + /// + internal static string InvalidDepthHeaderValue { get { - return ResourceManager.GetString("InvalidOperation_EnumEnded", resourceCulture); + return ResourceManager.GetString("InvalidDepthHeaderValue", resourceCulture); } } - internal static string InvalidOperation_EnumFailedVersion { + /// + /// Looks up a localized string similar to {0} is not a valid lock token. + /// + internal static string InvalidLockTokenFormat { get { - return ResourceManager.GetString("InvalidOperation_EnumFailedVersion", resourceCulture); + return ResourceManager.GetString("InvalidLockTokenFormat", resourceCulture); } } - internal static string InvalidOperation_EnumNotStarted { + /// + /// Looks up a localized string similar to Queue empty.. + /// + internal static string InvalidOperation_EmptyQueue { get { - return ResourceManager.GetString("InvalidOperation_EnumNotStarted", resourceCulture); + return ResourceManager.GetString("InvalidOperation_EmptyQueue", resourceCulture); } } - internal static string InvalidOperation_EnumOpCantHappen { + /// + /// Looks up a localized string similar to Stack empty.. + /// + internal static string InvalidOperation_EmptyStack { get { - return ResourceManager.GetString("InvalidOperation_EnumOpCantHappen", resourceCulture); + return ResourceManager.GetString("InvalidOperation_EmptyStack", resourceCulture); } } - internal static string Invalid_Array_Type { + /// + /// Looks up a localized string similar to Enumeration already finished.. + /// + internal static string InvalidOperation_EnumEnded { get { - return ResourceManager.GetString("Invalid_Array_Type", resourceCulture); + return ResourceManager.GetString("InvalidOperation_EnumEnded", resourceCulture); } } - internal static string LinkedListEmpty { + /// + /// Looks up a localized string similar to Collection was modified; enumeration operation may not execute.. + /// + internal static string InvalidOperation_EnumFailedVersion { get { - return ResourceManager.GetString("LinkedListEmpty", resourceCulture); + return ResourceManager.GetString("InvalidOperation_EnumFailedVersion", resourceCulture); } } - internal static string LinkedListNodeIsAttached { + /// + /// Looks up a localized string similar to Enumeration has not started. Call MoveNext.. + /// + internal static string InvalidOperation_EnumNotStarted { get { - return ResourceManager.GetString("LinkedListNodeIsAttached", resourceCulture); + return ResourceManager.GetString("InvalidOperation_EnumNotStarted", resourceCulture); } } - internal static string NotSupported_KeyCollectionSet { + /// + /// Looks up a localized string similar to Enumeration has either not started or has already finished.. + /// + internal static string InvalidOperation_EnumOpCantHappen { get { - return ResourceManager.GetString("NotSupported_KeyCollectionSet", resourceCulture); + return ResourceManager.GetString("InvalidOperation_EnumOpCantHappen", resourceCulture); } } - internal static string NotSupported_SortedListNestedWrite { + /// + /// Looks up a localized string similar to The LinkedList is empty.. + /// + internal static string LinkedListEmpty { get { - return ResourceManager.GetString("NotSupported_SortedListNestedWrite", resourceCulture); + return ResourceManager.GetString("LinkedListEmpty", resourceCulture); } } - internal static string NotSupported_ValueCollectionSet { + /// + /// Looks up a localized string similar to The LinkedList node already belongs to a LinkedList.. + /// + internal static string LinkedListNodeIsAttached { get { - return ResourceManager.GetString("NotSupported_ValueCollectionSet", resourceCulture); + return ResourceManager.GetString("LinkedListNodeIsAttached", resourceCulture); } } - internal static string ReadOnly_Modification { + /// + /// Looks up a localized string similar to {0} is not a valid list (not ending with a ')'). + /// + internal static string ListNotEndingWithBracket { get { - return ResourceManager.GetString("ReadOnly_Modification", resourceCulture); + return ResourceManager.GetString("ListNotEndingWithBracket", resourceCulture); } } - internal static string UnsupportedAccessType { + /// + /// Looks up a localized string similar to {0} is not a valid list (not starting with a '('). + /// + internal static string ListNotStartingWithBracket { get { - return ResourceManager.GetString("UnsupportedAccessType", resourceCulture); + return ResourceManager.GetString("ListNotStartingWithBracket", resourceCulture); } } - internal static string UnsupportedShareMode { + /// + /// Looks up a localized string similar to Mutating a key collection derived from a dictionary is not allowed.. + /// + internal static string NotSupported_KeyCollectionSet { get { - return ResourceManager.GetString("UnsupportedShareMode", resourceCulture); + return ResourceManager.GetString("NotSupported_KeyCollectionSet", resourceCulture); } } - internal static string InvalidCodedUrl { + /// + /// Looks up a localized string similar to This operation is not supported on SortedList nested types because they require modifying the original SortedList.. + /// + internal static string NotSupported_SortedListNestedWrite { get { - return ResourceManager.GetString("InvalidCodedUrl", resourceCulture); + return ResourceManager.GetString("NotSupported_SortedListNestedWrite", resourceCulture); } } - internal static string InvalidDepthHeaderValue { + /// + /// Looks up a localized string similar to Mutating a value collection derived from a dictionary is not allowed.. + /// + internal static string NotSupported_ValueCollectionSet { get { - return ResourceManager.GetString("InvalidDepthHeaderValue", resourceCulture); + return ResourceManager.GetString("NotSupported_ValueCollectionSet", resourceCulture); } } - internal static string ConditionListNotAcceptible { + /// + /// Looks up a localized string similar to The collection is read-only. + /// + internal static string ReadOnly_Modification { get { - return ResourceManager.GetString("ConditionListNotAcceptible", resourceCulture); + return ResourceManager.GetString("ReadOnly_Modification", resourceCulture); } } - internal static string ETagNotEndingWithBracket { + /// + /// Looks up a localized string similar to Unknown unit {0}. + /// + internal static string UnknownUnit { get { - return ResourceManager.GetString("ETagNotEndingWithBracket", resourceCulture); + return ResourceManager.GetString("UnknownUnit", resourceCulture); } } - internal static string ListNotStartingWithBracket { + /// + /// Looks up a localized string similar to The access type {0} is not supported. + /// + internal static string UnsupportedAccessType { get { - return ResourceManager.GetString("ListNotStartingWithBracket", resourceCulture); + return ResourceManager.GetString("UnsupportedAccessType", resourceCulture); } } - internal static string ListNotEndingWithBracket { + /// + /// Looks up a localized string similar to The share mode {0} is not supported. + /// + internal static string UnsupportedShareMode { get { - return ResourceManager.GetString("ListNotEndingWithBracket", resourceCulture); + return ResourceManager.GetString("UnsupportedShareMode", resourceCulture); } } - internal static string InvalidLockTokenFormat { + /// + /// Looks up a localized string similar to The URI must be absolute. + /// + internal static string UriMustBeAbsolute { get { - return ResourceManager.GetString("InvalidLockTokenFormat", resourceCulture); + return ResourceManager.GetString("UriMustBeAbsolute", resourceCulture); } } - internal static string UnknownUnit { + /// + /// Looks up a localized string similar to The URI must not be absolute. + /// + internal static string UriMustNotBeAbsolute { get { - return ResourceManager.GetString("UnknownUnit", resourceCulture); + return ResourceManager.GetString("UriMustNotBeAbsolute", resourceCulture); } } } diff --git a/src/FubarDev.WebDavServer/Properties/Resources.de.Designer.cs b/src/FubarDev.WebDavServer/Properties/Resources.de.Designer.cs index a460105f..50ef0656 100644 --- a/src/FubarDev.WebDavServer/Properties/Resources.de.Designer.cs +++ b/src/FubarDev.WebDavServer/Properties/Resources.de.Designer.cs @@ -1,6 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. +// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -11,32 +12,46 @@ namespace FubarDev.WebDavServer.Properties { using System; - [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [System.Diagnostics.DebuggerNonUserCodeAttribute()] - [System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources_de { - private static System.Resources.ResourceManager resourceMan; + private static global::System.Resources.ResourceManager resourceMan; - private static System.Globalization.CultureInfo resourceCulture; + private static global::System.Globalization.CultureInfo resourceCulture; - [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal Resources_de() { } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] - internal static System.Resources.ResourceManager ResourceManager { + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { get { - if (object.Equals(null, resourceMan)) { - System.Resources.ResourceManager temp = new System.Resources.ResourceManager("FubarDev.WebDavServer.Properties.Resources_de", typeof(Resources_de).Assembly); + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("FubarDev.WebDavServer.Properties.Resources.de", typeof(Resources_de).Assembly); resourceMan = temp; } return resourceMan; } } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] - internal static System.Globalization.CultureInfo Culture { + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { get { return resourceCulture; } @@ -45,303 +60,471 @@ internal static System.Globalization.CultureInfo Culture { } } - internal static string ArgumentOutOfRange_BiggerThanCollection { + /// + /// Looks up a localized string similar to Array lengths must be the same.. + /// + internal static string Arg_ArrayLengthsDiffer { get { - return ResourceManager.GetString("ArgumentOutOfRange_BiggerThanCollection", resourceCulture); + return ResourceManager.GetString("Arg_ArrayLengthsDiffer", resourceCulture); } } - internal static string ArgumentOutOfRange_Count { + /// + /// Looks up a localized string similar to Destination array is not long enough to copy all the items in the collection. Check array index and length.. + /// + internal static string Arg_ArrayPlusOffTooSmall { get { - return ResourceManager.GetString("ArgumentOutOfRange_Count", resourceCulture); + return ResourceManager.GetString("Arg_ArrayPlusOffTooSmall", resourceCulture); } } - internal static string ArgumentOutOfRange_Index { + /// + /// Looks up a localized string similar to Only supported array types for CopyTo on BitArrays are Boolean[], Int32[] and Byte[].. + /// + internal static string Arg_BitArrayTypeUnsupported { get { - return ResourceManager.GetString("ArgumentOutOfRange_Index", resourceCulture); + return ResourceManager.GetString("Arg_BitArrayTypeUnsupported", resourceCulture); } } - internal static string ArgumentOutOfRange_ListInsert { + /// + /// Looks up a localized string similar to HashSet capacity is too big.. + /// + internal static string Arg_HSCapacityOverflow { get { - return ResourceManager.GetString("ArgumentOutOfRange_ListInsert", resourceCulture); + return ResourceManager.GetString("Arg_HSCapacityOverflow", resourceCulture); } } - internal static string ArgumentOutOfRange_NeedNonNegNum { + /// + /// Looks up a localized string similar to Hashtable's capacity overflowed and went negative. Check load factor, capacity and the current size of the table.. + /// + internal static string Arg_HTCapacityOverflow { get { - return ResourceManager.GetString("ArgumentOutOfRange_NeedNonNegNum", resourceCulture); + return ResourceManager.GetString("Arg_HTCapacityOverflow", resourceCulture); } } - internal static string ArgumentOutOfRange_NeedNonNegNumRequired { + /// + /// Looks up a localized string similar to Insufficient space in the target location to copy the information.. + /// + internal static string Arg_InsufficientSpace { get { - return ResourceManager.GetString("ArgumentOutOfRange_NeedNonNegNumRequired", resourceCulture); + return ResourceManager.GetString("Arg_InsufficientSpace", resourceCulture); } } - internal static string ArgumentOutOfRange_SmallCapacity { + /// + /// Looks up a localized string similar to Multi dimension array is not supported on this operation.. + /// + internal static string Arg_MultiRank { get { - return ResourceManager.GetString("ArgumentOutOfRange_SmallCapacity", resourceCulture); + return ResourceManager.GetString("Arg_MultiRank", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The lower bound of target array must be zero.. + /// + internal static string Arg_NonZeroLowerBound { + get { + return ResourceManager.GetString("Arg_NonZeroLowerBound", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Only single dimensional arrays are supported for the requested action.. + /// + internal static string Arg_RankMultiDimNotSupported { + get { + return ResourceManager.GetString("Arg_RankMultiDimNotSupported", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The value '{0}' is not of type '{1}' and cannot be used in this generic collection.. + /// + internal static string Arg_WrongType { + get { + return ResourceManager.GetString("Arg_WrongType", resourceCulture); } } + /// + /// Looks up a localized string similar to An item with the same key has already been added.. + /// internal static string Argument_AddingDuplicate { get { return ResourceManager.GetString("Argument_AddingDuplicate", resourceCulture); } } + /// + /// Looks up a localized string similar to The input array length must not exceed Int32.MaxValue / {0}. Otherwise BitArray.Length would exceed Int32.MaxValue.. + /// internal static string Argument_ArrayTooLarge { get { return ResourceManager.GetString("Argument_ArrayTooLarge", resourceCulture); } } + /// + /// Looks up a localized string similar to At least one object must implement IComparable.. + /// internal static string Argument_ImplementIComparable { get { return ResourceManager.GetString("Argument_ImplementIComparable", resourceCulture); } } + /// + /// Looks up a localized string similar to Type of argument is not compatible with the generic comparer.. + /// internal static string Argument_InvalidArgumentForComparison { get { return ResourceManager.GetString("Argument_InvalidArgumentForComparison", resourceCulture); } } + /// + /// Looks up a localized string similar to Target array type is not compatible with the type of items in the collection.. + /// internal static string Argument_InvalidArrayType { get { return ResourceManager.GetString("Argument_InvalidArrayType", resourceCulture); } } + /// + /// Looks up a localized string similar to Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection.. + /// internal static string Argument_InvalidOffLen { get { return ResourceManager.GetString("Argument_InvalidOffLen", resourceCulture); } } - internal static string Arg_ArrayLengthsDiffer { - get { - return ResourceManager.GetString("Arg_ArrayLengthsDiffer", resourceCulture); - } - } - - internal static string Arg_ArrayPlusOffTooSmall { - get { - return ResourceManager.GetString("Arg_ArrayPlusOffTooSmall", resourceCulture); - } - } - - internal static string Arg_BitArrayTypeUnsupported { + /// + /// Looks up a localized string similar to Larger than collection size.. + /// + internal static string ArgumentOutOfRange_BiggerThanCollection { get { - return ResourceManager.GetString("Arg_BitArrayTypeUnsupported", resourceCulture); + return ResourceManager.GetString("ArgumentOutOfRange_BiggerThanCollection", resourceCulture); } } - internal static string Arg_HSCapacityOverflow { + /// + /// Looks up a localized string similar to Count must be positive and count must refer to a location within the string/array/collection.. + /// + internal static string ArgumentOutOfRange_Count { get { - return ResourceManager.GetString("Arg_HSCapacityOverflow", resourceCulture); + return ResourceManager.GetString("ArgumentOutOfRange_Count", resourceCulture); } } - internal static string Arg_HTCapacityOverflow { + /// + /// Looks up a localized string similar to Index was out of range. Must be non-negative and less than the size of the collection.. + /// + internal static string ArgumentOutOfRange_Index { get { - return ResourceManager.GetString("Arg_HTCapacityOverflow", resourceCulture); + return ResourceManager.GetString("ArgumentOutOfRange_Index", resourceCulture); } } - internal static string Arg_InsufficientSpace { + /// + /// Looks up a localized string similar to Index must be within the bounds of the List.. + /// + internal static string ArgumentOutOfRange_ListInsert { get { - return ResourceManager.GetString("Arg_InsufficientSpace", resourceCulture); + return ResourceManager.GetString("ArgumentOutOfRange_ListInsert", resourceCulture); } } - internal static string Arg_MultiRank { + /// + /// Looks up a localized string similar to Non-negative number required.. + /// + internal static string ArgumentOutOfRange_NeedNonNegNum { get { - return ResourceManager.GetString("Arg_MultiRank", resourceCulture); + return ResourceManager.GetString("ArgumentOutOfRange_NeedNonNegNum", resourceCulture); } } - internal static string Arg_NonZeroLowerBound { + /// + /// Looks up a localized string similar to Non-negative number required.. + /// + internal static string ArgumentOutOfRange_NeedNonNegNumRequired { get { - return ResourceManager.GetString("Arg_NonZeroLowerBound", resourceCulture); + return ResourceManager.GetString("ArgumentOutOfRange_NeedNonNegNumRequired", resourceCulture); } } - internal static string Arg_RankMultiDimNotSupported { + /// + /// Looks up a localized string similar to capacity was less than the current size.. + /// + internal static string ArgumentOutOfRange_SmallCapacity { get { - return ResourceManager.GetString("Arg_RankMultiDimNotSupported", resourceCulture); + return ResourceManager.GetString("ArgumentOutOfRange_SmallCapacity", resourceCulture); } } - internal static string Arg_WrongType { + /// + /// Looks up a localized string similar to Liste der Bedingungen wird nicht akzeptiert. + /// + internal static string ConditionListNotAcceptible { get { - return ResourceManager.GetString("Arg_WrongType", resourceCulture); + return ResourceManager.GetString("ConditionListNotAcceptible", resourceCulture); } } + /// + /// Looks up a localized string similar to Destination array is not long enough to copy all the items in the collection. Check array index and length.. + /// internal static string CopyTo_ArgumentsTooSmall { get { return ResourceManager.GetString("CopyTo_ArgumentsTooSmall", resourceCulture); } } + /// + /// Looks up a localized string similar to The specified TValueCollection creates collections that have IsReadOnly set to true by default. TValueCollection must be a mutable ICollection.. + /// internal static string Create_TValueCollectionReadOnly { get { return ResourceManager.GetString("Create_TValueCollectionReadOnly", resourceCulture); } } + /// + /// Looks up a localized string similar to {0} ist keine gültige Bedingung (ETag endet nicht mit ']'). + /// + internal static string ETagNotEndingWithBracket { + get { + return ResourceManager.GetString("ETagNotEndingWithBracket", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The LinkedList node does not belong to current LinkedList.. + /// internal static string ExternalLinkedListNode { get { return ResourceManager.GetString("ExternalLinkedListNode", resourceCulture); } } + /// + /// Looks up a localized string similar to Index {0} is out of range.. + /// internal static string IndexOutOfRange { get { return ResourceManager.GetString("IndexOutOfRange", resourceCulture); } } - internal static string InvalidOperation_EmptyQueue { + /// + /// Looks up a localized string similar to Target array type is not compatible with the type of items in the collection.. + /// + internal static string Invalid_Array_Type { get { - return ResourceManager.GetString("InvalidOperation_EmptyQueue", resourceCulture); + return ResourceManager.GetString("Invalid_Array_Type", resourceCulture); } } - internal static string InvalidOperation_EmptyStack { + /// + /// Looks up a localized string similar to {0} ist keine gültige Coded-URL (endet nicht mit '>'). + /// + internal static string InvalidCodedUrl { get { - return ResourceManager.GetString("InvalidOperation_EmptyStack", resourceCulture); + return ResourceManager.GetString("InvalidCodedUrl", resourceCulture); } } - internal static string InvalidOperation_EnumEnded { + /// + /// Looks up a localized string similar to Das Argument muss einen der folgenden Werte haben: "0", "1" oder "infinity". + /// + internal static string InvalidDepthHeaderValue { get { - return ResourceManager.GetString("InvalidOperation_EnumEnded", resourceCulture); + return ResourceManager.GetString("InvalidDepthHeaderValue", resourceCulture); } } - internal static string InvalidOperation_EnumFailedVersion { + /// + /// Looks up a localized string similar to {0} ist kein gültiges Lock-Token. + /// + internal static string InvalidLockTokenFormat { get { - return ResourceManager.GetString("InvalidOperation_EnumFailedVersion", resourceCulture); + return ResourceManager.GetString("InvalidLockTokenFormat", resourceCulture); } } - internal static string InvalidOperation_EnumNotStarted { + /// + /// Looks up a localized string similar to Queue empty.. + /// + internal static string InvalidOperation_EmptyQueue { get { - return ResourceManager.GetString("InvalidOperation_EnumNotStarted", resourceCulture); + return ResourceManager.GetString("InvalidOperation_EmptyQueue", resourceCulture); } } - internal static string InvalidOperation_EnumOpCantHappen { + /// + /// Looks up a localized string similar to Stack empty.. + /// + internal static string InvalidOperation_EmptyStack { get { - return ResourceManager.GetString("InvalidOperation_EnumOpCantHappen", resourceCulture); + return ResourceManager.GetString("InvalidOperation_EmptyStack", resourceCulture); } } - internal static string Invalid_Array_Type { + /// + /// Looks up a localized string similar to Enumeration already finished.. + /// + internal static string InvalidOperation_EnumEnded { get { - return ResourceManager.GetString("Invalid_Array_Type", resourceCulture); + return ResourceManager.GetString("InvalidOperation_EnumEnded", resourceCulture); } } - internal static string LinkedListEmpty { + /// + /// Looks up a localized string similar to Collection was modified; enumeration operation may not execute.. + /// + internal static string InvalidOperation_EnumFailedVersion { get { - return ResourceManager.GetString("LinkedListEmpty", resourceCulture); + return ResourceManager.GetString("InvalidOperation_EnumFailedVersion", resourceCulture); } } - internal static string LinkedListNodeIsAttached { + /// + /// Looks up a localized string similar to Enumeration has not started. Call MoveNext.. + /// + internal static string InvalidOperation_EnumNotStarted { get { - return ResourceManager.GetString("LinkedListNodeIsAttached", resourceCulture); + return ResourceManager.GetString("InvalidOperation_EnumNotStarted", resourceCulture); } } - internal static string NotSupported_KeyCollectionSet { + /// + /// Looks up a localized string similar to Enumeration has either not started or has already finished.. + /// + internal static string InvalidOperation_EnumOpCantHappen { get { - return ResourceManager.GetString("NotSupported_KeyCollectionSet", resourceCulture); + return ResourceManager.GetString("InvalidOperation_EnumOpCantHappen", resourceCulture); } } - internal static string NotSupported_SortedListNestedWrite { + /// + /// Looks up a localized string similar to The LinkedList is empty.. + /// + internal static string LinkedListEmpty { get { - return ResourceManager.GetString("NotSupported_SortedListNestedWrite", resourceCulture); + return ResourceManager.GetString("LinkedListEmpty", resourceCulture); } } - internal static string NotSupported_ValueCollectionSet { + /// + /// Looks up a localized string similar to The LinkedList node already belongs to a LinkedList.. + /// + internal static string LinkedListNodeIsAttached { get { - return ResourceManager.GetString("NotSupported_ValueCollectionSet", resourceCulture); + return ResourceManager.GetString("LinkedListNodeIsAttached", resourceCulture); } } - internal static string ReadOnly_Modification { + /// + /// Looks up a localized string similar to {0} ist keine gültige Liste (endet nicht mit ')'). + /// + internal static string ListNotEndingWithBracket { get { - return ResourceManager.GetString("ReadOnly_Modification", resourceCulture); + return ResourceManager.GetString("ListNotEndingWithBracket", resourceCulture); } } - internal static string UnsupportedAccessType { + /// + /// Looks up a localized string similar to {0} ist keine gültige Liste (beginnt nicht mit '('). + /// + internal static string ListNotStartingWithBracket { get { - return ResourceManager.GetString("UnsupportedAccessType", resourceCulture); + return ResourceManager.GetString("ListNotStartingWithBracket", resourceCulture); } } - internal static string UnsupportedShareMode { + /// + /// Looks up a localized string similar to Mutating a key collection derived from a dictionary is not allowed.. + /// + internal static string NotSupported_KeyCollectionSet { get { - return ResourceManager.GetString("UnsupportedShareMode", resourceCulture); + return ResourceManager.GetString("NotSupported_KeyCollectionSet", resourceCulture); } } - internal static string InvalidCodedUrl { + /// + /// Looks up a localized string similar to This operation is not supported on SortedList nested types because they require modifying the original SortedList.. + /// + internal static string NotSupported_SortedListNestedWrite { get { - return ResourceManager.GetString("InvalidCodedUrl", resourceCulture); + return ResourceManager.GetString("NotSupported_SortedListNestedWrite", resourceCulture); } } - internal static string InvalidDepthHeaderValue { + /// + /// Looks up a localized string similar to Mutating a value collection derived from a dictionary is not allowed.. + /// + internal static string NotSupported_ValueCollectionSet { get { - return ResourceManager.GetString("InvalidDepthHeaderValue", resourceCulture); + return ResourceManager.GetString("NotSupported_ValueCollectionSet", resourceCulture); } } - internal static string ConditionListNotAcceptible { + /// + /// Looks up a localized string similar to The collection is read-only. + /// + internal static string ReadOnly_Modification { get { - return ResourceManager.GetString("ConditionListNotAcceptible", resourceCulture); + return ResourceManager.GetString("ReadOnly_Modification", resourceCulture); } } - internal static string ETagNotEndingWithBracket { + /// + /// Looks up a localized string similar to Unbekannte Einheit {0}. + /// + internal static string UnknownUnit { get { - return ResourceManager.GetString("ETagNotEndingWithBracket", resourceCulture); + return ResourceManager.GetString("UnknownUnit", resourceCulture); } } - internal static string ListNotStartingWithBracket { + /// + /// Looks up a localized string similar to Der Access-Typ {0} wird nicht unterstützt. + /// + internal static string UnsupportedAccessType { get { - return ResourceManager.GetString("ListNotStartingWithBracket", resourceCulture); + return ResourceManager.GetString("UnsupportedAccessType", resourceCulture); } } - internal static string ListNotEndingWithBracket { + /// + /// Looks up a localized string similar to Der Share-Modus {0} wird nicht unterstützt. + /// + internal static string UnsupportedShareMode { get { - return ResourceManager.GetString("ListNotEndingWithBracket", resourceCulture); + return ResourceManager.GetString("UnsupportedShareMode", resourceCulture); } } - internal static string InvalidLockTokenFormat { + /// + /// Looks up a localized string similar to Die URI muss absolut sein. + /// + internal static string UriMustBeAbsolute { get { - return ResourceManager.GetString("InvalidLockTokenFormat", resourceCulture); + return ResourceManager.GetString("UriMustBeAbsolute", resourceCulture); } } - internal static string UnknownUnit { + /// + /// Looks up a localized string similar to Die URI darf nicht absolut sein. + /// + internal static string UriMustNotBeAbsolute { get { - return ResourceManager.GetString("UnknownUnit", resourceCulture); + return ResourceManager.GetString("UriMustNotBeAbsolute", resourceCulture); } } } diff --git a/src/FubarDev.WebDavServer/Properties/Resources.de.resx b/src/FubarDev.WebDavServer/Properties/Resources.de.resx index e7e8890c..45a31bf0 100644 --- a/src/FubarDev.WebDavServer/Properties/Resources.de.resx +++ b/src/FubarDev.WebDavServer/Properties/Resources.de.resx @@ -208,4 +208,10 @@ Unbekannte Einheit {0} + + Die URI muss absolut sein + + + Die URI darf nicht absolut sein + diff --git a/src/FubarDev.WebDavServer/Properties/Resources.resx b/src/FubarDev.WebDavServer/Properties/Resources.resx index ec2eb789..2465cd10 100644 --- a/src/FubarDev.WebDavServer/Properties/Resources.resx +++ b/src/FubarDev.WebDavServer/Properties/Resources.resx @@ -267,4 +267,10 @@ Unknown unit {0} + + The URI must be absolute + + + The URI must not be absolute + diff --git a/src/FubarDev.WebDavServer/Utils/DefaultUriComparer.cs b/src/FubarDev.WebDavServer/Utils/DefaultUriComparer.cs index 289391d1..31498343 100644 --- a/src/FubarDev.WebDavServer/Utils/DefaultUriComparer.cs +++ b/src/FubarDev.WebDavServer/Utils/DefaultUriComparer.cs @@ -5,9 +5,10 @@ using System; using System.Collections.Generic; using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; using System.Linq; +using FubarDev.WebDavServer.Properties; + namespace FubarDev.WebDavServer.Utils { /// @@ -15,6 +16,7 @@ namespace FubarDev.WebDavServer.Utils /// public class DefaultUriComparer : IUriComparer { + private static readonly char[] _slash = { '/' }; private readonly IWebDavContextAccessor? _contextAccessor; /// @@ -29,86 +31,105 @@ public DefaultUriComparer(IWebDavContextAccessor? contextAccessor = null) /// public UriComparisonResult Compare(Uri x, Uri y) { - if (TryGetAbsolute(x, out var absoluteX)) - { - x = absoluteX; - } - - if (TryGetAbsolute(y, out var absoluteY)) - { - y = absoluteY; - } + var publicBaseUrl = _contextAccessor?.WebDavContext.PublicBaseUrl; + var infoX = new UriInfo(x, publicBaseUrl); + var infoY = new UriInfo(y, publicBaseUrl); + return Compare(infoX, infoY); + } - if (!IsSameHost(x, y)) - { - return UriComparisonResult.PrecedingDifferentHost; - } + /// + public bool IsSameHost(Uri x, Uri y) + { + var publicBaseUrl = _contextAccessor?.WebDavContext.PublicBaseUrl; + var infoX = new UriInfo(x, publicBaseUrl); + var infoY = new UriInfo(y, publicBaseUrl); + return CompareHosts(infoX, infoY) == UriComparisonResult.Equal; + } - var context = _contextAccessor?.WebDavContext; - var uriX = MakeAbsoluteUri(x, context); - var uriY = MakeAbsoluteUri(y, context); + /// + public bool IsThisServer(Uri uri) + { + return IsThisServer(uri, _contextAccessor?.WebDavContext.PublicBaseUrl); + } - if (uriX is null) + /// + int IComparer.Compare(Uri? x, Uri? y) + { + if (x is null) { - if (uriY is null) + if (y is null) { - // Both are relative URLs, so let's make them absolute - return CompareAbsoluteUris( - new Uri("/" + x.OriginalString), - new Uri("/" + y.OriginalString)); + return 0; } - return InvertResult(CompareWithAbsoluteUri(uriY, x)); + return -10; } - if (uriY is null) + if (y is null) { - return CompareWithAbsoluteUri(uriX, y); + return 10; } - return CompareAbsoluteUris(uriX, uriY); + return (int)Compare(x, y); } - /// - public bool IsSameHost(Uri x, Uri y) + private static UriComparisonResult CompareRelativePaths(string pathX, string pathY) + { + var partsX = pathX.Split(_slash, StringSplitOptions.RemoveEmptyEntries); + var partsY = pathY.Split(_slash, StringSplitOptions.RemoveEmptyEntries); + var minLength = Math.Min(partsX.Length, partsY.Length); + for (var i = 0; i != minLength; ++i) + { + var partX = partsX[i]; + var partY = partsY[i]; + var partCompare = string.Compare(partX, partY, StringComparison.OrdinalIgnoreCase); + switch (partCompare) + { + case < 0: + return UriComparisonResult.FollowingSibling; + case > 0: + return UriComparisonResult.PrecedingSibling; + } + } + + return partsX.Length == partsY.Length + ? UriComparisonResult.Equal + : partsX.Length > partsY.Length + ? UriComparisonResult.Child + : UriComparisonResult.Parent; + } + + private static UriComparisonResult CompareHosts(UriInfo infoX, UriInfo infoY) { - if (!TryGetAbsolute(x, out var absoluteX) - || !TryGetAbsolute(y, out var absoluteY) - || string.IsNullOrEmpty(absoluteX.Host) - || string.IsNullOrEmpty(absoluteY.Host)) + if (!infoX.IsAbsolute + || !infoY.IsAbsolute + || string.IsNullOrEmpty(infoX.Uri.Host) + || string.IsNullOrEmpty(infoY.Uri.Host)) { // It's the same host if one of them are relative URIs // or the host is empty - return true; + return UriComparisonResult.Equal; } - x = absoluteX; - y = absoluteY; - - var uriComponents = string.IsNullOrEmpty(x.Scheme) || string.IsNullOrEmpty(y.Scheme) + var uriComponents = string.IsNullOrEmpty(infoX.Scheme) || string.IsNullOrEmpty(infoX.Scheme) ? UriComponents.Host | UriComponents.Port : UriComponents.Scheme | UriComponents.HostAndPort; - var valueX = x.GetComponents(uriComponents, UriFormat.UriEscaped); - var valueY = y.GetComponents(uriComponents, UriFormat.UriEscaped); + var valueX = infoX.Uri.GetComponents(uriComponents, UriFormat.UriEscaped); + var valueY = infoY.Uri.GetComponents(uriComponents, UriFormat.UriEscaped); - return string.Equals(valueX, valueY, StringComparison.OrdinalIgnoreCase); - } - - /// - public bool IsThisServer(Uri uri) - { - return IsThisServer(uri, null); - } - - /// - int IComparer.Compare(Uri x, Uri y) - { - return (int)Compare(x, y); + return string.Compare(valueX, valueY, StringComparison.OrdinalIgnoreCase) switch + { + < 0 => UriComparisonResult.PrecedingDifferentHost, + 0 => UriComparisonResult.Equal, + > 0 => UriComparisonResult.FollowingDifferentHost, + }; } private static UriComparisonResult InvertResult(UriComparisonResult result) => result switch { + UriComparisonResult.PrecedingDifferentHost => UriComparisonResult.FollowingDifferentHost, + UriComparisonResult.FollowingDifferentHost => UriComparisonResult.PrecedingDifferentHost, UriComparisonResult.PrecedingSibling => UriComparisonResult.FollowingSibling, UriComparisonResult.FollowingSibling => UriComparisonResult.PrecedingSibling, UriComparisonResult.Parent => UriComparisonResult.Child, @@ -116,41 +137,6 @@ private static UriComparisonResult InvertResult(UriComparisonResult result) _ => result, }; - private static string FixUriPath(string path) - { - path = path.TrimEnd('/'); - if (string.IsNullOrEmpty(path)) - { - return "/"; - } - - if (!path.StartsWith("/")) - { - return "/" + path; - } - - return path; - } - - private static bool TryGetAbsolute(Uri uri, [NotNullWhen(true)] out Uri? absoluteUri) - { - if (uri.IsAbsoluteUri) - { - absoluteUri = uri; - return true; - } - - var originalString = uri.OriginalString; - if (originalString.StartsWith("/")) - { - absoluteUri = new Uri(originalString); - return true; - } - - absoluteUri = null; - return false; - } - /// /// Compares a relative URL with an absolute URL. /// @@ -162,18 +148,18 @@ private static bool TryGetAbsolute(Uri uri, [NotNullWhen(true)] out Uri? absolut /// /// This is all just guesswork! /// - private UriComparisonResult CompareWithAbsoluteUri( + private static UriComparisonResult CompareWithAbsoluteUri( Uri absolute, Uri relative) { if (!absolute.IsAbsoluteUri) { - throw new ArgumentException("The URI must be absolute", nameof(absolute)); + throw new ArgumentException(Resources.UriMustBeAbsolute, nameof(absolute)); } - if (!relative.IsAbsoluteUri) + if (relative.IsAbsoluteUri) { - throw new ArgumentException("The URI must not be absolute", nameof(relative)); + throw new ArgumentException(Resources.UriMustNotBeAbsolute, nameof(relative)); } var relativePathParts = relative.OriginalString @@ -254,35 +240,34 @@ private UriComparisonResult CompareWithAbsoluteUri( : UriComparisonResult.FollowingSibling; } - private UriComparisonResult CompareAbsoluteUris( - Uri x, - Uri y) + private static UriComparisonResult Compare(UriInfo infoX, UriInfo infoY) { - if (!x.IsAbsoluteUri) + if (!infoX.IsAbsolute && !infoY.IsAbsolute) { - throw new ArgumentException("The URI must be absolute", nameof(x)); + return CompareRelativePaths(infoX.PathWithSlash, infoY.PathWithSlash); } - if (!y.IsAbsoluteUri) + var hostCompareResult = CompareHosts(infoX, infoY); + if (hostCompareResult != UriComparisonResult.Equal) { - throw new ArgumentException("The URI must be absolute", nameof(y)); + return hostCompareResult; } - var pathX = FixUriPath(x.GetComponents(UriComponents.Path, UriFormat.UriEscaped)); - var pathY = FixUriPath(y.GetComponents(UriComponents.Path, UriFormat.UriEscaped)); - if (string.Equals(pathX, pathY, StringComparison.OrdinalIgnoreCase)) + if (!infoX.IsAbsolute) { - return UriComparisonResult.Equal; + return InvertResult(CompareWithAbsoluteUri(infoY.Uri, infoX.Uri)); } - var uriX = new Uri(pathX); - var uriY = new Uri(pathY); - return uriX.IsBaseOf(uriY) - ? UriComparisonResult.Child - : UriComparisonResult.Parent; + if (!infoY.IsAbsolute) + { + return CompareWithAbsoluteUri(infoX.Uri, infoY.Uri); + } + + // Just assume that the root path is the root path of the WebDAV service + return CompareRelativePaths(infoX.PathWithSlash, infoY.PathWithSlash); } - private bool IsThisServer(Uri uri, IWebDavContext? context) + private bool IsThisServer(Uri uri, Uri? publicBaseUrl) { if (_contextAccessor is null) { @@ -290,81 +275,96 @@ private bool IsThisServer(Uri uri, IWebDavContext? context) return true; } - if (!TryGetAbsolute(uri, out var absoluteUri)) - { - // Relative URIs are always the same server - return true; - } - - uri = absoluteUri; - - context ??= _contextAccessor.WebDavContext; - var publicBaseUrl = context.PublicBaseUrl; - - if (string.IsNullOrEmpty(uri.Host) && uri.Scheme == "file" && uri.AbsolutePath.StartsWith("//")) - { - // This is a relative URI with a host but no scheme - uri = new Uri(publicBaseUrl.Scheme + ":" + uri.AbsolutePath); - } - - if (!string.IsNullOrEmpty(uri.Host)) - { - if (!IsSameHost(publicBaseUrl, uri)) - { - return false; - } - } - - if (string.IsNullOrEmpty(publicBaseUrl.AbsolutePath) || publicBaseUrl.AbsolutePath == "/") + var uriInfo = new UriInfo(uri, publicBaseUrl); + if (!uriInfo.IsAbsolute || publicBaseUrl is null) { + // URL is not absolute return true; } - if (string.IsNullOrEmpty(uri.AbsolutePath) || uri.AbsolutePath == "/") + if (!IsSameHost(publicBaseUrl, uriInfo.Uri)) { return false; } - var basePathText = "/" + publicBaseUrl.GetComponents(UriComponents.Path, UriFormat.UriEscaped).TrimEnd('/'); - if (!basePathText.EndsWith("/")) - { - basePathText += "/"; - } - - var uriPathText = "/" + uri.GetComponents(UriComponents.Path, UriFormat.UriEscaped).TrimEnd('/'); - if (!uriPathText.EndsWith("/")) + // This makes "http://localhost/_dav/" a base path of "/_dav/" + var basePath = "/" + publicBaseUrl.GetComponents(UriComponents.Path, UriFormat.UriEscaped); + if (!basePath.EndsWith("/")) { - uriPathText += "/"; + basePath += "/"; } - var basePath = new Uri(basePathText); - var uriPath = new Uri(uriPathText); + var uriPath = uriInfo.PathWithSlash; - // This seems to be case-sensitive. Is that really what we want/need? - return basePath.IsBaseOf(uriPath); + return uriPath.StartsWith(basePath, StringComparison.OrdinalIgnoreCase); } - private Uri? MakeAbsoluteUri(Uri uri, IWebDavContext? context = null) + private class UriInfo { - if (uri.IsAbsoluteUri) + public UriInfo(Uri originalUri, Uri? publicBaseUri) { - return uri; - } + Scheme = publicBaseUri?.Scheme ?? "http"; - context ??= _contextAccessor?.WebDavContext; - if (context == null) - { - // It is "absolute" in the sense that it is relative to the server root - if (uri.OriginalString.StartsWith("/")) + var uri = originalUri; + if (!uri.IsAbsoluteUri) { - return new Uri(uri.OriginalString); + if (publicBaseUri != null) + { + var basePath = publicBaseUri.OriginalString; + if (!basePath.EndsWith("/")) + { + // Always ensure that the path ends in a slash + publicBaseUri = new Uri(basePath + "/"); + } + + if (uri.OriginalString.StartsWith("///")) + { + uri = new Uri(publicBaseUri, "/" + uri.OriginalString.TrimStart('/')); + } + else if (uri.OriginalString.StartsWith("//")) + { + uri = new Uri(Scheme + "://" + uri.OriginalString.TrimStart('/')); + } + else + { + uri = new Uri(publicBaseUri, uri); + } + } + else + { + if (uri.OriginalString.StartsWith("///")) + { + uri = new Uri("/" + uri.OriginalString.TrimStart('/')); + } + else if (uri.OriginalString.StartsWith("//")) + { + uri = new Uri(Scheme + "://" + uri.OriginalString.TrimStart('/')); + } + else if (uri.OriginalString.StartsWith("/")) + { + uri = new Uri("file://" + uri.OriginalString, UriKind.Absolute); + } + } } - // Not possible without a context - return null; + Uri = uri; + IsAbsolute = uri.IsAbsoluteUri; + + Path = uri.IsAbsoluteUri + ? "/" + uri.GetComponents(UriComponents.Path, UriFormat.UriEscaped) + : new Uri("file:///" + uri.OriginalString).GetComponents(UriComponents.Path, UriFormat.UriEscaped); + PathWithSlash = !Path.EndsWith("/") ? Path + "/" : Path; } - return new Uri(context.PublicBaseUrl, uri); + public string Scheme { get; } + + public Uri Uri { get; } + + public bool IsAbsolute { get; } + + public string Path { get; } + + public string PathWithSlash { get; } } } } diff --git a/src/FubarDev.WebDavServer/Utils/UriComparisonResult.cs b/src/FubarDev.WebDavServer/Utils/UriComparisonResult.cs index d633601d..31909c3e 100644 --- a/src/FubarDev.WebDavServer/Utils/UriComparisonResult.cs +++ b/src/FubarDev.WebDavServer/Utils/UriComparisonResult.cs @@ -14,11 +14,6 @@ public enum UriComparisonResult /// PrecedingDifferentHost = -4, - /// - /// The URL points to a different service on the same host - /// - PrecedingDifferentService, - /// /// The URL points to a path that is a preceding sibling of the target path /// @@ -44,11 +39,6 @@ public enum UriComparisonResult /// FollowingSibling, - /// - /// The URL points to a different service on the same host - /// - FollowingDifferentService, - /// /// The URL points to different host /// diff --git a/test/FubarDev.WebDavServer.Tests/UriComparerTests.cs b/test/FubarDev.WebDavServer.Tests/UriComparerTests.cs index 6d8049b8..b820d4c2 100644 --- a/test/FubarDev.WebDavServer.Tests/UriComparerTests.cs +++ b/test/FubarDev.WebDavServer.Tests/UriComparerTests.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Security.Principal; @@ -135,12 +134,28 @@ public void CompareUrlIsNotThisServerWithSubPath(string url) [Theory] [InlineData("http://test/a", UriComparisonResult.PrecedingDifferentHost)] [InlineData("//test/a", UriComparisonResult.PrecedingDifferentHost)] - [InlineData("/a", UriComparisonResult.PrecedingDifferentHost)] + [InlineData("http://aaa/a", UriComparisonResult.FollowingDifferentHost)] + [InlineData("//aaa/a", UriComparisonResult.FollowingDifferentHost)] + [InlineData("/0", UriComparisonResult.PrecedingSibling)] + [InlineData("/~", UriComparisonResult.FollowingSibling)] + [InlineData("/_dav", UriComparisonResult.Equal)] + [InlineData("", UriComparisonResult.Equal)] + [InlineData("http://localhost/0", UriComparisonResult.PrecedingSibling)] + [InlineData("http://localhost/~", UriComparisonResult.FollowingSibling)] + [InlineData("http://localhost/_dav", UriComparisonResult.Equal)] + [InlineData("//localhost/_dav", UriComparisonResult.Equal)] + [InlineData("///_dav", UriComparisonResult.Equal)] + [InlineData("http://localhost/", UriComparisonResult.Child)] + [InlineData("//localhost/", UriComparisonResult.Child)] + [InlineData("///", UriComparisonResult.Child)] + [InlineData("http://localhost/_dav/a", UriComparisonResult.Parent)] + [InlineData("//localhost/_dav/a", UriComparisonResult.Parent)] + [InlineData("///_dav/a", UriComparisonResult.Parent)] public void TestCompare(string url, UriComparisonResult expected) { var baseUrl = new Uri("http://localhost/_dav"); var comparer = new DefaultUriComparer(new TestWebDavContextAccessor(baseUrl)); - var result = comparer.Compare(new Uri(url, UriKind.RelativeOrAbsolute), baseUrl); + var result = comparer.Compare(baseUrl, new Uri(url, UriKind.RelativeOrAbsolute)); Assert.Equal(expected, result); } @@ -216,463 +231,5 @@ public TestWebDavContext(Uri publicBaseUrl) public IWebDavDispatcher Dispatcher => throw new NotImplementedException(); } } - - /// - /// Default implementation of the interface. - /// - private class DefaultUriComparer : IUriComparer - { - private readonly IWebDavContextAccessor? _contextAccessor; - - /// - /// Initializes a new instance of the class. - /// - /// The accessor for the WebDAV context. - public DefaultUriComparer(IWebDavContextAccessor? contextAccessor = null) - { - _contextAccessor = contextAccessor; - } - - /// - public UriComparisonResult Compare(Uri x, Uri y) - { - var context = _contextAccessor?.WebDavContext; - var publicBaseUrl = context?.PublicBaseUrl; - var infoX = new UriInfo(x, publicBaseUrl); - var infoY = new UriInfo(y, publicBaseUrl); - if (!infoX.IsAbsolute && !infoY.IsAbsolute) - { - return CompareRelativePaths(infoX.PathWithSlash, infoY.PathWithSlash); - } - - if (TryGetAbsolute(x, out var absoluteX)) - { - x = absoluteX; - } - - if (TryGetAbsolute(y, out var absoluteY)) - { - y = absoluteY; - } - - if (!IsSameHost(x, y)) - { - return UriComparisonResult.PrecedingDifferentHost; - } - - var uriX = MakeAbsoluteUri(x, context); - var uriY = MakeAbsoluteUri(y, context); - - if (uriX is null) - { - if (uriY is null) - { - // Both are relative URLs, so let's make them absolute - return CompareAbsoluteUris( - new Uri("/" + x.OriginalString), - new Uri("/" + y.OriginalString)); - } - - return InvertResult(CompareWithAbsoluteUri(uriY, x)); - } - - if (uriY is null) - { - return CompareWithAbsoluteUri(uriX, y); - } - - return CompareAbsoluteUris(uriX, uriY); - } - - /// - public bool IsSameHost(Uri x, Uri y) - { - var publicBaseUrl = _contextAccessor?.WebDavContext.PublicBaseUrl; - var infoX = new UriInfo(x, publicBaseUrl); - var infoY = new UriInfo(y, publicBaseUrl); - return CompareHosts(infoX, infoY) == UriComparisonResult.Equal; - } - - /// - public bool IsThisServer(Uri uri) - { - return IsThisServer(uri, _contextAccessor?.WebDavContext.PublicBaseUrl); - } - - /// - int IComparer.Compare(Uri? x, Uri? y) - { - if (x is null) - { - if (y is null) - { - return 0; - } - - return -10; - } - - if (y is null) - { - return 10; - } - - return (int)Compare(x, y); - } - - private static UriComparisonResult CompareRelativePaths(string pathX, string pathY) - { - var partsX = pathX.Split('/', StringSplitOptions.RemoveEmptyEntries); - var partsY = pathY.Split('/', StringSplitOptions.RemoveEmptyEntries); - var minLength = Math.Min(partsX.Length, partsY.Length); - for (var i = 0; i != minLength; ++i) - { - var partX = partsX[i]; - var partY = partsY[i]; - var partCompare = string.Compare(partX, partY, StringComparison.OrdinalIgnoreCase); - switch (partCompare) - { - case < 0: - return UriComparisonResult.FollowingSibling; - case > 0: - return UriComparisonResult.PrecedingSibling; - } - } - - return partsX.Length == partsY.Length - ? UriComparisonResult.Equal - : partsX.Length > partsY.Length - ? UriComparisonResult.Child - : UriComparisonResult.Parent; - } - - private static UriComparisonResult CompareHosts(UriInfo infoX, UriInfo infoY) - { - if (!infoX.IsAbsolute - || !infoY.IsAbsolute - || string.IsNullOrEmpty(infoX.Uri.Host) - || string.IsNullOrEmpty(infoY.Uri.Host)) - { - // It's the same host if one of them are relative URIs - // or the host is empty - return UriComparisonResult.Equal; - } - - var uriComponents = string.IsNullOrEmpty(infoX.Scheme) || string.IsNullOrEmpty(infoX.Scheme) - ? UriComponents.Host | UriComponents.Port - : UriComponents.Scheme | UriComponents.HostAndPort; - var valueX = infoX.Uri.GetComponents(uriComponents, UriFormat.UriEscaped); - var valueY = infoY.Uri.GetComponents(uriComponents, UriFormat.UriEscaped); - - return string.Compare(valueX, valueY, StringComparison.OrdinalIgnoreCase) switch - { - < 0 => UriComparisonResult.PrecedingDifferentHost, - 0 => UriComparisonResult.Equal, - > 0 => UriComparisonResult.FollowingDifferentHost, - }; - } - - private static UriComparisonResult InvertResult(UriComparisonResult result) - => result switch - { - UriComparisonResult.PrecedingSibling => UriComparisonResult.FollowingSibling, - UriComparisonResult.FollowingSibling => UriComparisonResult.PrecedingSibling, - UriComparisonResult.Parent => UriComparisonResult.Child, - UriComparisonResult.Child => UriComparisonResult.Parent, - _ => result, - }; - - private static string FixUriPath(string path) - { - path = path.TrimEnd('/'); - if (string.IsNullOrEmpty(path)) - { - return "/"; - } - - if (!path.StartsWith("/")) - { - return "/" + path; - } - - return path; - } - - private static bool TryGetAbsolute(Uri uri, [NotNullWhen(true)] out Uri? absoluteUri) - { - if (uri.IsAbsoluteUri) - { - absoluteUri = uri; - return true; - } - - var originalString = uri.OriginalString; - if (originalString.StartsWith("/")) - { - absoluteUri = new Uri(originalString); - return true; - } - - absoluteUri = null; - return false; - } - - /// - /// Compares a relative URL with an absolute URL. - /// - /// The absolute URL. - /// The relative URL. - /// The result of the comparison. - /// The absolute URL is not absolute or the relative isn't - /// relative. - /// - /// This is all just guesswork! - /// - private UriComparisonResult CompareWithAbsoluteUri( - Uri absolute, - Uri relative) - { - if (!absolute.IsAbsoluteUri) - { - throw new ArgumentException("The URI must be absolute", nameof(absolute)); - } - - if (!relative.IsAbsoluteUri) - { - throw new ArgumentException("The URI must not be absolute", nameof(relative)); - } - - var relativePathParts = relative.OriginalString - .Split('/') - .Select(Uri.UnescapeDataString) - .Where(x => !string.IsNullOrEmpty(x)) - .ToList(); - if (relativePathParts.Count == 0) - { - return UriComparisonResult.Equal; - } - - var absolutePathParts = absolute.GetComponents(UriComponents.Path, UriFormat.UriEscaped) - .Split('/') - .Select(Uri.UnescapeDataString) - .Where(x => !string.IsNullOrEmpty(x)) - .ToList(); - if (absolutePathParts.Count == 0) - { - return UriComparisonResult.Parent; - } - - // Find the parts that match the absolute path parts - var startIndex = 0; - var foundCount = 0; - for (var i = 0; i != relativePathParts.Count; ++i) - { - var relativePart = relativePathParts[i]; - var foundIndex = absolutePathParts.FindIndex( - startIndex, - x => string.Equals(x, relativePart, StringComparison.OrdinalIgnoreCase)); - if (foundIndex == -1) - { - break; - } - - if (foundCount != 0 && foundIndex != startIndex) - { - break; - } - - startIndex = foundIndex + 1; - foundCount += 1; - } - - if (foundCount == 0) - { - // The absolute path seems to be the parent of the relative path - return UriComparisonResult.Parent; - } - - if (foundCount == relativePathParts.Count) - { - // Relative path was found in absolute path - if (startIndex == absolutePathParts.Count) - { - // The absolute path ends with the relative path - return UriComparisonResult.Equal; - } - - // The relative path seems to be the parent of the absolute path - return UriComparisonResult.Child; - } - - if (startIndex == absolutePathParts.Count) - { - // The relative path seems to be the child of the absolute path - return UriComparisonResult.Child; - } - - var nextAbsolutePart = absolutePathParts[startIndex]; - var nextRelativePart = relativePathParts[foundCount]; - var result = string.Compare(nextAbsolutePart, nextRelativePart, StringComparison.OrdinalIgnoreCase); - Debug.Assert(result != 0, "The next parts should not be equal"); - - return result < 0 - ? UriComparisonResult.PrecedingSibling - : UriComparisonResult.FollowingSibling; - } - - private UriComparisonResult CompareAbsoluteUris( - Uri x, - Uri y) - { - if (!x.IsAbsoluteUri) - { - throw new ArgumentException("The URI must be absolute", nameof(x)); - } - - if (!y.IsAbsoluteUri) - { - throw new ArgumentException("The URI must be absolute", nameof(y)); - } - - var pathX = FixUriPath(x.GetComponents(UriComponents.Path, UriFormat.UriEscaped)); - var pathY = FixUriPath(y.GetComponents(UriComponents.Path, UriFormat.UriEscaped)); - if (string.Equals(pathX, pathY, StringComparison.OrdinalIgnoreCase)) - { - return UriComparisonResult.Equal; - } - - var uriX = new Uri(pathX); - var uriY = new Uri(pathY); - return uriX.IsBaseOf(uriY) - ? UriComparisonResult.Child - : UriComparisonResult.Parent; - } - - private bool IsThisServer(Uri uri, Uri? publicBaseUrl) - { - if (_contextAccessor is null) - { - // Always assume that the URL points to the same server, because we don't have a context - return true; - } - - var uriInfo = new UriInfo(uri, publicBaseUrl); - if (!uriInfo.IsAbsolute) - { - // URL is not absolute - return true; - } - - if (!IsSameHost(publicBaseUrl, uriInfo.Uri)) - { - return false; - } - - // This makes "http://localhost/_dav/" a base path of "/_dav/" - var basePath = "/" + publicBaseUrl.GetComponents(UriComponents.Path, UriFormat.UriEscaped); - if (!basePath.EndsWith("/")) - { - basePath += "/"; - } - - var uriPath = uriInfo.PathWithSlash; - - return uriPath.StartsWith(basePath, StringComparison.OrdinalIgnoreCase); - } - - private Uri? MakeAbsoluteUri(Uri uri, IWebDavContext? context = null) - { - if (uri.IsAbsoluteUri) - { - return uri; - } - - context ??= _contextAccessor?.WebDavContext; - if (context == null) - { - // It is "absolute" in the sense that it is relative to the server root - if (uri.OriginalString.StartsWith("/")) - { - return new Uri(uri.OriginalString); - } - - // Not possible without a context - return null; - } - - return new Uri(context.PublicBaseUrl, uri); - } - } - - private class UriInfo - { - public UriInfo(Uri originalUri, Uri? publicBaseUri) - { - OriginalUri = originalUri; - Scheme = publicBaseUri?.Scheme ?? "http"; - - var uri = originalUri; - if (!uri.IsAbsoluteUri) - { - if (publicBaseUri != null) - { - var basePath = publicBaseUri.OriginalString; - if (!basePath.EndsWith("/")) - { - // Always ensure that the path ends in a slash - publicBaseUri = new Uri(basePath + "/"); - } - - if (uri.OriginalString.StartsWith("///")) - { - uri = new Uri(publicBaseUri, uri.OriginalString.TrimStart('/')); - } - else if (uri.OriginalString.StartsWith("//")) - { - uri = new Uri(Scheme + "://" + uri.OriginalString.TrimStart('/')); - } - else - { - uri = new Uri(publicBaseUri, uri); - } - } - else - { - if (uri.OriginalString.StartsWith("///")) - { - uri = new Uri("/" + uri.OriginalString.TrimStart('/')); - } - else if (uri.OriginalString.StartsWith("//")) - { - uri = new Uri(Scheme + "://" + uri.OriginalString.TrimStart('/')); - } - else if (uri.OriginalString.StartsWith("/")) - { - uri = new Uri(uri.OriginalString); - } - } - } - - Uri = uri; - IsAbsolute = uri.IsAbsoluteUri; - - Path = uri.IsAbsoluteUri - ? "/" + uri.GetComponents(UriComponents.Path, UriFormat.UriEscaped) - : new Uri("/" + uri.OriginalString).GetComponents(UriComponents.Path, UriFormat.UriEscaped); - PathWithSlash = !Path.EndsWith("/") ? Path + "/" : Path; - } - - public string Scheme { get; } - - public Uri OriginalUri { get; } - - public Uri Uri { get; } - - public bool IsAbsolute { get; } - - public string Path { get; } - - public string PathWithSlash { get; } - } } }