diff --git a/Runtime.sln b/Runtime.sln
index 5a9da54f..dc7b795c 100644
--- a/Runtime.sln
+++ b/Runtime.sln
@@ -98,6 +98,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Web.WebPages.OAut
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Web.WebPages.OAuth.Test", "test\Microsoft.Web.WebPages.OAuth.Test\Microsoft.Web.WebPages.OAuth.Test.csproj", "{694C6EDF-EA52-438F-B745-82B025ECC0E7}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Web.Http.SelfHost.Test", "test\System.Web.Http.SelfHost.Test\System.Web.Http.SelfHost.Test.csproj", "{7F29EE87-6A63-43C6-B7FF-74DD06815830}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
CodeCov|Any CPU = CodeCov|Any CPU
@@ -1014,6 +1016,26 @@ Global
{694C6EDF-EA52-438F-B745-82B025ECC0E7}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{694C6EDF-EA52-438F-B745-82B025ECC0E7}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{694C6EDF-EA52-438F-B745-82B025ECC0E7}.Release|x86.ActiveCfg = Release|Any CPU
+ {7F29EE87-6A63-43C6-B7FF-74DD06815830}.CodeCov|Any CPU.ActiveCfg = CodeCoverage|Any CPU
+ {7F29EE87-6A63-43C6-B7FF-74DD06815830}.CodeCov|Any CPU.Build.0 = CodeCoverage|Any CPU
+ {7F29EE87-6A63-43C6-B7FF-74DD06815830}.CodeCov|Mixed Platforms.ActiveCfg = CodeCoverage|Any CPU
+ {7F29EE87-6A63-43C6-B7FF-74DD06815830}.CodeCov|Mixed Platforms.Build.0 = CodeCoverage|Any CPU
+ {7F29EE87-6A63-43C6-B7FF-74DD06815830}.CodeCov|x86.ActiveCfg = CodeCoverage|Any CPU
+ {7F29EE87-6A63-43C6-B7FF-74DD06815830}.CodeCoverage|Any CPU.ActiveCfg = CodeCoverage|Any CPU
+ {7F29EE87-6A63-43C6-B7FF-74DD06815830}.CodeCoverage|Any CPU.Build.0 = CodeCoverage|Any CPU
+ {7F29EE87-6A63-43C6-B7FF-74DD06815830}.CodeCoverage|Mixed Platforms.ActiveCfg = CodeCoverage|Any CPU
+ {7F29EE87-6A63-43C6-B7FF-74DD06815830}.CodeCoverage|Mixed Platforms.Build.0 = CodeCoverage|Any CPU
+ {7F29EE87-6A63-43C6-B7FF-74DD06815830}.CodeCoverage|x86.ActiveCfg = CodeCoverage|Any CPU
+ {7F29EE87-6A63-43C6-B7FF-74DD06815830}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7F29EE87-6A63-43C6-B7FF-74DD06815830}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7F29EE87-6A63-43C6-B7FF-74DD06815830}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {7F29EE87-6A63-43C6-B7FF-74DD06815830}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {7F29EE87-6A63-43C6-B7FF-74DD06815830}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {7F29EE87-6A63-43C6-B7FF-74DD06815830}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7F29EE87-6A63-43C6-B7FF-74DD06815830}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7F29EE87-6A63-43C6-B7FF-74DD06815830}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {7F29EE87-6A63-43C6-B7FF-74DD06815830}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {7F29EE87-6A63-43C6-B7FF-74DD06815830}.Release|x86.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1064,5 +1086,6 @@ Global
{EA62944F-BD25-4730-9405-9BE8FF5BEACD} = {C40883CD-366D-4534-8B58-3EA0D13136DF}
{7B8601F8-8D1F-4B9C-8C20-772B673A2FA6} = {C40883CD-366D-4534-8B58-3EA0D13136DF}
{694C6EDF-EA52-438F-B745-82B025ECC0E7} = {C40883CD-366D-4534-8B58-3EA0D13136DF}
+ {7F29EE87-6A63-43C6-B7FF-74DD06815830} = {C40883CD-366D-4534-8B58-3EA0D13136DF}
EndGlobalSection
EndGlobal
diff --git a/src/System.Web.Http.Common/Error.cs b/src/System.Web.Http.Common/Error.cs
index 97c71257..d632f87a 100644
--- a/src/System.Web.Http.Common/Error.cs
+++ b/src/System.Web.Http.Common/Error.cs
@@ -25,7 +25,7 @@ namespace System.Web.Http.Common
}
///
- /// Creates an with the provided properties and logs it with .
+ /// Creates an with the provided properties.
///
/// A composite format string explaining the reason for the exception.
/// An object array that contains zero or more objects to format.
@@ -36,7 +36,7 @@ namespace System.Web.Http.Common
}
///
- /// Creates an with the provided properties and logs it with .
+ /// Creates an with the provided properties.
///
/// The name of the parameter that caused the current exception.
/// A composite format string explaining the reason for the exception.
@@ -48,7 +48,7 @@ namespace System.Web.Http.Common
}
///
- /// Creates an with a message saying that the argument must be an "http" or "https" URI and logs it with .
+ /// Creates an with a message saying that the argument must be an "http" or "https" URI.
///
/// The name of the parameter that caused the current exception.
/// The value of the argument that causes this exception.
@@ -59,7 +59,7 @@ namespace System.Web.Http.Common
}
///
- /// Creates an with a message saying that the argument must be an absolute URI and logs it with .
+ /// Creates an with a message saying that the argument must be an absolute URI.
///
/// The name of the parameter that caused the current exception.
/// The value of the argument that causes this exception.
@@ -82,7 +82,7 @@ namespace System.Web.Http.Common
}
///
- /// Creates an with the provided properties and logs it with .
+ /// Creates an with the provided properties.
///
/// The logged .
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly", Justification = "The purpose of this API is to return an error for properties")]
@@ -92,7 +92,7 @@ namespace System.Web.Http.Common
}
///
- /// Creates an with the provided properties and logs it with .
+ /// Creates an with the provided properties.
///
/// The name of the parameter that caused the current exception.
/// The logged .
@@ -102,7 +102,7 @@ namespace System.Web.Http.Common
}
///
- /// Creates an with the provided properties and logs it with .
+ /// Creates an with the provided properties.
///
/// The name of the parameter that caused the current exception.
/// A composite format string explaining the reason for the exception.
@@ -114,7 +114,7 @@ namespace System.Web.Http.Common
}
///
- /// Creates an with a default message and logs it with .
+ /// Creates an with a default message.
///
/// The name of the parameter that caused the current exception.
/// The logged .
@@ -124,7 +124,7 @@ namespace System.Web.Http.Common
}
///
- /// Creates an with the provided properties and logs it with .
+ /// Creates an with the provided properties.
///
/// The name of the parameter that caused the current exception.
/// The value of the argument that causes this exception.
@@ -137,7 +137,7 @@ namespace System.Web.Http.Common
}
///
- /// Creates an with a message saying that the argument must be greater than or equal to and logs it with .
+ /// Creates an with a message saying that the argument must be greater than or equal to .
///
/// The name of the parameter that caused the current exception.
/// The value of the argument that causes this exception.
@@ -149,7 +149,7 @@ namespace System.Web.Http.Common
}
///
- /// Creates an with a message saying that the argument must be less than or equal to and logs it with .
+ /// Creates an with a message saying that the argument must be less than or equal to .
///
/// The name of the parameter that caused the current exception.
/// The value of the argument that causes this exception.
@@ -161,7 +161,7 @@ namespace System.Web.Http.Common
}
///
- /// Creates an with a message saying that the key was not found and logs it with .
+ /// Creates an with a message saying that the key was not found.
///
/// The logged .
public static KeyNotFoundException KeyNotFound()
@@ -170,7 +170,7 @@ namespace System.Web.Http.Common
}
///
- /// Creates an with a message saying that the key was not found and logs it with .
+ /// Creates an with a message saying that the key was not found.
///
/// A composite format string explaining the reason for the exception.
/// An object array that contains zero or more objects to format.
@@ -181,7 +181,7 @@ namespace System.Web.Http.Common
}
///
- /// Creates an initialized according to guidelines and logs it with .
+ /// Creates an initialized according to guidelines.
///
/// A composite format string explaining the reason for the exception.
/// An object array that contains zero or more objects to format.
@@ -193,7 +193,7 @@ namespace System.Web.Http.Common
}
///
- /// Creates an initialized with the provided parameters and logs it with .
+ /// Creates an initialized with the provided parameters.
///
/// The logged .
public static OperationCanceledException OperationCanceled()
@@ -202,7 +202,7 @@ namespace System.Web.Http.Common
}
///
- /// Creates an initialized with the provided parameters and logs it with .
+ /// Creates an initialized with the provided parameters.
///
/// A composite format string explaining the reason for the exception.
/// An object array that contains zero or more objects to format.
@@ -213,7 +213,7 @@ namespace System.Web.Http.Common
}
///
- /// Creates an and logs it with .
+ /// Creates an .
///
/// The name of the parameter that caused the current exception.
/// The value of the argument that failed.
@@ -225,7 +225,7 @@ namespace System.Web.Http.Common
}
///
- /// Creates an and logs it with .
+ /// Creates an .
///
/// A composite format string explaining the reason for the exception.
/// An object array that contains zero or more objects to format.
@@ -236,7 +236,7 @@ namespace System.Web.Http.Common
}
///
- /// Creates an and logs it with .
+ /// Creates an .
///
/// Inner exception
/// A composite format string explaining the reason for the exception.
@@ -248,7 +248,7 @@ namespace System.Web.Http.Common
}
///
- /// Creates an and logs it with .
+ /// Creates an .
///
/// A composite format string explaining the reason for the exception.
/// An object array that contains zero or more objects to format.
diff --git a/src/System.Web.Http.Common/Properties/SRResources.Designer.cs b/src/System.Web.Http.Common/Properties/SRResources.Designer.cs
index 82dfb987..e7962545 100644
--- a/src/System.Web.Http.Common/Properties/SRResources.Designer.cs
+++ b/src/System.Web.Http.Common/Properties/SRResources.Designer.cs
@@ -79,7 +79,7 @@ namespace System.Web.Http.Common.Properties {
}
///
- /// Looks up a localized string similar to The argument '{0}' must be greater than or equal to {1}..
+ /// Looks up a localized string similar to Value must be greater than or equal to {1}..
///
internal static string ArgumentMustBeGreaterThanOrEqualTo {
get {
@@ -88,7 +88,7 @@ namespace System.Web.Http.Common.Properties {
}
///
- /// Looks up a localized string similar to The argument '{0}' must be less than or equal to {1}..
+ /// Looks up a localized string similar to Value must be less than or equal to {1}..
///
internal static string ArgumentMustBeLessThanOrEqualTo {
get {
diff --git a/src/System.Web.Http.Common/Properties/SRResources.resx b/src/System.Web.Http.Common/Properties/SRResources.resx
index 14322733..92481d47 100644
--- a/src/System.Web.Http.Common/Properties/SRResources.resx
+++ b/src/System.Web.Http.Common/Properties/SRResources.resx
@@ -124,10 +124,10 @@
Unsupported URI scheme: '{0}'. The URI scheme must be either '{1}' or '{2}'.
- The argument '{0}' must be greater than or equal to {1}.
+ Value must be greater than or equal to {1}.
- The argument '{0}' must be less than or equal to {1}.
+ Value must be less than or equal to {1}.
The argument '{0}' is null or empty.
diff --git a/src/System.Web.Http.SelfHost/HttpSelfHostConfiguration.cs b/src/System.Web.Http.SelfHost/HttpSelfHostConfiguration.cs
index 85603ce2..28d9ebcf 100644
--- a/src/System.Web.Http.SelfHost/HttpSelfHostConfiguration.cs
+++ b/src/System.Web.Http.SelfHost/HttpSelfHostConfiguration.cs
@@ -18,6 +18,9 @@ namespace System.Web.Http.SelfHost
public class HttpSelfHostConfiguration : HttpConfiguration
{
private const int DefaultMaxConcurrentRequests = 100;
+ private const int DefaultMaxBufferSize = 64 * 1024;
+ private const int DefaultReceivedMessageSize = 64 * 1024;
+
private const int PendingContextFactor = 100;
private const int MinConcurrentRequests = 1;
private const int MinBufferSize = 0;
@@ -28,15 +31,16 @@ namespace System.Web.Http.SelfHost
private ServiceCredentials _credentials = new ServiceCredentials();
private bool _useWindowsAuth;
private TransferMode _transferMode;
- private int _maxBufferSize;
- private long _maxReceivedMessageSize;
+ private int _maxBufferSize = DefaultMaxBufferSize;
+ private long _maxReceivedMessageSize = DefaultReceivedMessageSize;
+ private HostNameComparisonMode _hostNameComparisonMode;
///
/// Initializes a new instance of the class.
///
/// The base address.
public HttpSelfHostConfiguration(string baseAddress)
- : this(new Uri(baseAddress, UriKind.RelativeOrAbsolute))
+ : this(CreateBaseAddress(baseAddress))
{
}
@@ -82,6 +86,7 @@ namespace System.Web.Http.SelfHost
{
throw Error.ArgumentTooSmall("value", value, MinConcurrentRequests);
}
+ _maxConcurrentRequests = value;
}
}
@@ -102,6 +107,20 @@ namespace System.Web.Http.SelfHost
}
}
+ ///
+ /// Specifies how the host name should be used in URI comparisons when dispatching an incoming message.
+ ///
+ public HostNameComparisonMode HostNameComparisonMode
+ {
+ get { return _hostNameComparisonMode; }
+
+ set
+ {
+ HostNameComparisonModeHelper.Validate(value);
+ _hostNameComparisonMode = value;
+ }
+ }
+
///
/// Gets or sets the size of the max buffer.
///
@@ -118,7 +137,6 @@ namespace System.Web.Http.SelfHost
{
throw Error.ArgumentTooSmall("value", value, MinBufferSize);
}
-
_maxBufferSize = value;
}
}
@@ -139,7 +157,6 @@ namespace System.Web.Http.SelfHost
{
throw Error.ArgumentTooSmall("value", value, MinReceivedMessageSize);
}
-
_maxReceivedMessageSize = value;
}
}
@@ -203,6 +220,8 @@ namespace System.Web.Http.SelfHost
httpBinding.MaxBufferSize = MaxBufferSize;
httpBinding.MaxReceivedMessageSize = MaxReceivedMessageSize;
httpBinding.TransferMode = TransferMode;
+ httpBinding.HostNameComparisonMode = HostNameComparisonMode;
+
if (_baseAddress.Scheme == Uri.UriSchemeHttps)
{
// we need to use SSL
@@ -232,7 +251,7 @@ namespace System.Web.Http.SelfHost
}
else if (_useWindowsAuth)
{
- if (httpBinding.Security == null)
+ if (httpBinding.Security == null || httpBinding.Security.Mode == HttpBindingSecurityMode.None)
{
// Basic over HTTP case, should we even allow this?
httpBinding.Security = new HttpBindingSecurity()
@@ -257,6 +276,16 @@ namespace System.Web.Http.SelfHost
return bindingParameters;
}
+ private static Uri CreateBaseAddress(string baseAddress)
+ {
+ if (baseAddress == null)
+ {
+ throw Error.ArgumentNull("baseAddress");
+ }
+
+ return new Uri(baseAddress, UriKind.RelativeOrAbsolute);
+ }
+
private static Uri ValidateBaseAddress(Uri baseAddress)
{
if (baseAddress == null)
diff --git a/test/Microsoft.TestCommon/ExceptionAssertions.cs b/test/Microsoft.TestCommon/ExceptionAssertions.cs
index b16e84d6..76a79b23 100644
--- a/test/Microsoft.TestCommon/ExceptionAssertions.cs
+++ b/test/Microsoft.TestCommon/ExceptionAssertions.cs
@@ -342,12 +342,14 @@ namespace Microsoft.TestCommon
/// The name of the parameter that should throw the exception
/// The exception message to verify
/// Pass true to allow exceptions which derive from TException; pass false, otherwise
+ /// The actual value provided
/// The exception that was thrown, when successful
/// Thrown when an exception was not thrown, or when an exception of the incorrect type is thrown
- public static ArgumentOutOfRangeException ThrowsArgumentOutOfRange(Action testCode, string paramName, string exceptionMessage, bool allowDerivedExceptions = false)
+ public static ArgumentOutOfRangeException ThrowsArgumentOutOfRange(Action testCode, string paramName, string exceptionMessage, bool allowDerivedExceptions = false, object actualValue = null)
{
exceptionMessage = exceptionMessage != null
- ? exceptionMessage + "\r\nParameter name: " + paramName
+ ? exceptionMessage + "\r\nParameter name: " + paramName +
+ (actualValue != null ? "\r\nActual value was " + actualValue.ToString() + "." : "")
: exceptionMessage;
var ex = Throws(testCode, exceptionMessage, allowDerivedExceptions);
@@ -361,16 +363,17 @@ namespace Microsoft.TestCommon
///
/// Verifies that the code throws an with the expected message that indicates that
- /// the value must be greater than the given value.
+ /// the value must be greater than the given .
///
/// A delegate to the code to be tested
/// The name of the parameter that should throw the exception
- /// The expected limit value.
+ /// The actual value provided.
+ /// The expected limit value.
/// The exception that was thrown, when successful
/// Thrown when an exception was not thrown, or when an exception of the incorrect type is thrown
- public static ArgumentOutOfRangeException ThrowsArgumentGreaterThan(Action testCode, string paramName, string value)
+ public static ArgumentOutOfRangeException ThrowsArgumentGreaterThan(Action testCode, string paramName, string minValue, object actualValue = null)
{
- return ThrowsArgumentOutOfRange(testCode, paramName, String.Format("Value must be greater than {0}.", value));
+ return ThrowsArgumentOutOfRange(testCode, paramName, String.Format("Value must be greater than {0}.", minValue), false, actualValue);
}
///
@@ -379,40 +382,42 @@ namespace Microsoft.TestCommon
///
/// A delegate to the code to be tested
/// The name of the parameter that should throw the exception
- /// The expected limit value.
+ /// The expected limit value.
/// The exception that was thrown, when successful
/// Thrown when an exception was not thrown, or when an exception of the incorrect type is thrown
- public static ArgumentOutOfRangeException ThrowsArgumentGreaterThanOrEqualTo(Action testCode, string paramName, string value)
+ public static ArgumentOutOfRangeException ThrowsArgumentGreaterThanOrEqualTo(Action testCode, string paramName, string minValue, object actualValue = null)
{
- return ThrowsArgumentOutOfRange(testCode, paramName, String.Format("Value must be greater than or equal to {0}.", value));
+ return ThrowsArgumentOutOfRange(testCode, paramName, String.Format("Value must be greater than or equal to {0}.", minValue), false, actualValue);
}
///
/// Verifies that the code throws an with the expected message that indicates that
- /// the value must be less than the given value.
+ /// the value must be less than the given .
///
/// A delegate to the code to be tested
/// The name of the parameter that should throw the exception
- /// The expected limit value.
+ /// The actual value provided.
+ /// The expected limit value.
/// The exception that was thrown, when successful
/// Thrown when an exception was not thrown, or when an exception of the incorrect type is thrown
- public static ArgumentOutOfRangeException ThrowsArgumentLessThan(Action testCode, string paramName, string value)
+ public static ArgumentOutOfRangeException ThrowsArgumentLessThan(Action testCode, string paramName, string maxValue, object actualValue = null)
{
- return ThrowsArgumentOutOfRange(testCode, paramName, String.Format("Value must be less than {0}.", value));
+ return ThrowsArgumentOutOfRange(testCode, paramName, String.Format("Value must be less than {0}.", maxValue), false, actualValue);
}
///
/// Verifies that the code throws an with the expected message that indicates that
- /// the value must be less than or equal to the given value.
+ /// the value must be less than or equal to the given .
///
/// A delegate to the code to be tested
/// The name of the parameter that should throw the exception
- /// The expected limit value.
+ /// The actual value provided.
+ /// The expected limit value.
/// The exception that was thrown, when successful
/// Thrown when an exception was not thrown, or when an exception of the incorrect type is thrown
- public static ArgumentOutOfRangeException ThrowsArgumentLessThanOrEqualTo(Action testCode, string paramName, string value)
+ public static ArgumentOutOfRangeException ThrowsArgumentLessThanOrEqualTo(Action testCode, string paramName, string maxValue, object actualValue = null)
{
- return ThrowsArgumentOutOfRange(testCode, paramName, String.Format("Value must be less than or equal to {0}.", value));
+ return ThrowsArgumentOutOfRange(testCode, paramName, String.Format("Value must be less than or equal to {0}.", maxValue), false, actualValue);
}
///
diff --git a/test/Microsoft.TestCommon/ReflectionAssert.cs b/test/Microsoft.TestCommon/ReflectionAssert.cs
index a2b3eb59..0f92d99e 100644
--- a/test/Microsoft.TestCommon/ReflectionAssert.cs
+++ b/test/Microsoft.TestCommon/ReflectionAssert.cs
@@ -61,6 +61,64 @@ namespace Microsoft.TestCommon
}
}
+ public void IntegerProperty(T instance, Expression> propertyGetter, TResult expectedDefaultValue,
+ TResult? minLegalValue, TResult? illegalLowerValue,
+ TResult? maxLegalValue, TResult? illegalUpperValue,
+ TResult roundTripTestValue) where TResult : struct
+ {
+ PropertyInfo property = GetPropertyInfo(propertyGetter);
+ Func getFunc = (obj) => (TResult)property.GetValue(obj, index: null);
+ Action setFunc = (obj, value) => property.SetValue(obj, value, index: null);
+
+ Assert.Equal(expectedDefaultValue, getFunc(instance));
+
+ if (minLegalValue.HasValue)
+ {
+ TestPropertyValue(instance, getFunc, setFunc, minLegalValue.Value);
+ }
+
+ if (maxLegalValue.HasValue)
+ {
+ TestPropertyValue(instance, getFunc, setFunc, maxLegalValue.Value);
+ }
+
+ if (illegalLowerValue.HasValue)
+ {
+ Assert.ThrowsArgumentGreaterThanOrEqualTo(() => { setFunc(instance, illegalLowerValue.Value); }, "value", minLegalValue.Value.ToString(), illegalLowerValue.Value);
+ }
+
+ if (illegalUpperValue.HasValue)
+ {
+ Assert.ThrowsArgumentLessThanOrEqualTo(() => { setFunc(instance, illegalLowerValue.Value); }, "value", maxLegalValue.Value.ToString(), illegalUpperValue.Value);
+ }
+
+ TestPropertyValue(instance, getFunc, setFunc, roundTripTestValue);
+ }
+
+ public void BooleanProperty(T instance, Expression> propertyGetter, bool expectedDefaultValue)
+ {
+ PropertyInfo property = GetPropertyInfo(propertyGetter);
+ Func getFunc = (obj) => (bool)property.GetValue(obj, index: null);
+ Action setFunc = (obj, value) => property.SetValue(obj, value, index: null);
+
+ Assert.Equal(expectedDefaultValue, getFunc(instance));
+
+ TestPropertyValue(instance, getFunc, setFunc, !expectedDefaultValue);
+ }
+
+ public void EnumProperty(T instance, Expression> propertyGetter, TResult expectedDefaultValue, TResult illegalValue, TResult roundTripTestValue) where TResult : struct
+ {
+ PropertyInfo property = GetPropertyInfo(propertyGetter);
+ Func getFunc = (obj) => (TResult)property.GetValue(obj, index: null);
+ Action setFunc = (obj, value) => property.SetValue(obj, value, index: null);
+
+ Assert.Equal(expectedDefaultValue, getFunc(instance));
+
+ Assert.ThrowsInvalidEnumArgument(() => { setFunc(instance, illegalValue); }, "value", Convert.ToInt32(illegalValue), typeof(TResult));
+
+ TestPropertyValue(instance, getFunc, setFunc, roundTripTestValue);
+ }
+
public void StringProperty(T instance, Expression> propertyGetter, string expectedDefaultValue,
bool allowNullAndEmpty = true, string nullAndEmptyReturnValue = "")
{
diff --git a/test/System.Web.Http.SelfHost.Test/HttpSelfHostConfigurationTest.cs b/test/System.Web.Http.SelfHost.Test/HttpSelfHostConfigurationTest.cs
new file mode 100644
index 00000000..fcbfea8c
--- /dev/null
+++ b/test/System.Web.Http.SelfHost.Test/HttpSelfHostConfigurationTest.cs
@@ -0,0 +1,258 @@
+using System.IdentityModel.Selectors;
+using System.ServiceModel;
+using System.ServiceModel.Channels;
+using System.ServiceModel.Description;
+using System.Web.Http.SelfHost;
+using System.Web.Http.SelfHost.Channels;
+using Moq;
+using Xunit;
+using Xunit.Extensions;
+using Assert = Microsoft.TestCommon.AssertEx;
+
+namespace System.Web.Http.WebHost
+{
+ public class HttpSelfHostConfigurationTest
+ {
+ [Fact]
+ public void HttpSelfHostConfiguration_NullBaseAddressString_Throws()
+ {
+ Assert.ThrowsArgumentNull(() => new HttpSelfHostConfiguration((string)null), "baseAddress");
+ }
+
+ [Fact]
+ public void HttpSelfHostConfiguration_RelativeBaseAddressString_Throws()
+ {
+ Assert.ThrowsArgument(() => new HttpSelfHostConfiguration("relative"), "baseAddress");
+ }
+
+ [Fact]
+ public void HttpSelfHostConfiguration_QueryBaseAddressString_Throws()
+ {
+ Assert.ThrowsArgument(() => new HttpSelfHostConfiguration("http://localhost?somequery"), "baseAddress");
+ }
+
+ [Fact]
+ public void HttpSelfHostConfiguration_FragmentBaseAddressString_Throws()
+ {
+ Assert.ThrowsArgument(() => new HttpSelfHostConfiguration("http://localhost#somefragment"), "baseAddress");
+ }
+
+ [Fact]
+ public void HttpSelfHostConfiguration_InvalidSchemeBaseAddressString_Throws()
+ {
+ Assert.ThrowsArgument(() => new HttpSelfHostConfiguration("ftp://localhost"), "baseAddress");
+ }
+
+ [Fact]
+ public void HttpSelfHostConfiguration_NullBaseAddress_Throws()
+ {
+ Assert.ThrowsArgumentNull(() => new HttpSelfHostConfiguration((Uri)null), "baseAddress");
+ }
+
+ [Fact]
+ public void HttpSelfHostConfiguration_RelativeBaseAddress_Throws()
+ {
+ Assert.ThrowsArgument(() => new HttpSelfHostConfiguration(new Uri("relative", UriKind.Relative)), "baseAddress");
+ }
+
+ [Fact]
+ public void HttpSelfHostConfiguration_QueryBaseAddress_Throws()
+ {
+ Assert.ThrowsArgument(() => new HttpSelfHostConfiguration(new Uri("http://localhost?somequery")), "baseAddress");
+ }
+
+ [Fact]
+ public void HttpSelfHostConfiguration_FragmentBaseAddress_Throws()
+ {
+ Assert.ThrowsArgument(() => new HttpSelfHostConfiguration(new Uri("http://localhost#somefragment")), "baseAddress");
+ }
+
+ [Fact]
+ public void HttpSelfHostConfiguration_InvalidSchemeBaseAddress_Throws()
+ {
+ Assert.ThrowsArgument(() => new HttpSelfHostConfiguration(new Uri("ftp://localhost")), "baseAddress");
+ }
+
+ [Fact]
+ public void HttpSelfHostConfiguration_BaseAddress_IsSet()
+ {
+ // Arrange
+ Uri baseAddress = new Uri("http://localhost");
+
+ // Act
+ HttpSelfHostConfiguration config = new HttpSelfHostConfiguration(baseAddress);
+
+ // Assert
+ Assert.Same(baseAddress, config.BaseAddress);
+ }
+
+ [Fact]
+ public void HttpSelfHostConfiguration_MaxConcurrentRequests_RoundTrips()
+ {
+ Assert.Reflection.IntegerProperty(
+ new HttpSelfHostConfiguration("http://localhost"),
+ c => c.MaxConcurrentRequests,
+ expectedDefaultValue: GetDefaultMaxConcurrentRequests(),
+ minLegalValue: 1,
+ illegalLowerValue: 0,
+ maxLegalValue: null,
+ illegalUpperValue: null,
+ roundTripTestValue: 10);
+ }
+
+ [Fact]
+ public void HttpSelfHostConfiguration_MaxBufferSize_RoundTrips()
+ {
+ Assert.Reflection.IntegerProperty(
+ new HttpSelfHostConfiguration("http://localhost"),
+ c => c.MaxBufferSize,
+ expectedDefaultValue: 64 * 1024,
+ minLegalValue: 0,
+ illegalLowerValue: -1,
+ maxLegalValue: null,
+ illegalUpperValue: null,
+ roundTripTestValue: 10);
+ }
+
+ [Fact]
+ public void HttpSelfHostConfiguration_MaxReceivedMessageSize_RoundTrips()
+ {
+ Assert.Reflection.IntegerProperty(
+ new HttpSelfHostConfiguration("http://localhost"),
+ c => c.MaxReceivedMessageSize,
+ expectedDefaultValue: 64 * 1024,
+ minLegalValue: 0,
+ illegalLowerValue: -1,
+ maxLegalValue: null,
+ illegalUpperValue: null,
+ roundTripTestValue: 10);
+ }
+
+ [Fact]
+ public void HttpSelfHostConfiguration_UseWindowsAuthentication_RoundTrips()
+ {
+ Assert.Reflection.BooleanProperty(
+ new HttpSelfHostConfiguration("http://localhost"),
+ c => c.UseWindowsAuthentication,
+ expectedDefaultValue: false);
+ }
+
+ [Fact]
+ public void HttpSelfHostConfiguration_UserNamePasswordValidator_RoundTrips()
+ {
+ // Arrange
+ UserNamePasswordValidator userNamePasswordValidator = new Mock().Object;
+
+ Assert.Reflection.Property(
+ new HttpSelfHostConfiguration("http://localhost"),
+ c => c.UserNamePasswordValidator,
+ expectedDefaultValue: null,
+ allowNull: true,
+ roundTripTestValue: userNamePasswordValidator);
+ }
+
+ [Fact]
+ public void HttpSelfHostConfiguration_TransferMode_RoundTrips()
+ {
+ Assert.Reflection.EnumProperty(
+ new HttpSelfHostConfiguration("http://localhost"),
+ c => c.TransferMode,
+ expectedDefaultValue: TransferMode.Buffered,
+ illegalValue: (TransferMode)999,
+ roundTripTestValue: TransferMode.Streamed);
+ }
+
+ [Fact]
+ public void HttpSelfHostConfiguration_HostNameComparisonMode_RoundTrips()
+ {
+ Assert.Reflection.EnumProperty(
+ new HttpSelfHostConfiguration("http://localhost"),
+ c => c.HostNameComparisonMode,
+ expectedDefaultValue: HostNameComparisonMode.StrongWildcard,
+ illegalValue: (HostNameComparisonMode)999,
+ roundTripTestValue: HostNameComparisonMode.Exact);
+ }
+
+ [Fact]
+ public void HttpSelfHostConfiguration_Settings_PropagateToBinding()
+ {
+ // Arrange
+ HttpBinding binding = new HttpBinding();
+ HttpSelfHostConfiguration config = new HttpSelfHostConfiguration("http://localhost")
+ {
+ MaxBufferSize = 10,
+ MaxReceivedMessageSize = 11,
+ TransferMode = TransferMode.StreamedResponse,
+ HostNameComparisonMode = HostNameComparisonMode.WeakWildcard
+ };
+
+ // Act
+ config.ConfigureBinding(binding);
+
+ // Assert
+ Assert.Equal(10, binding.MaxBufferSize);
+ Assert.Equal(11, binding.MaxReceivedMessageSize);
+ Assert.Equal(TransferMode.StreamedResponse, binding.TransferMode);
+ Assert.Equal(HostNameComparisonMode.WeakWildcard, binding.HostNameComparisonMode);
+ }
+
+ [Theory]
+ [InlineData("http://localhost", HttpBindingSecurityMode.TransportCredentialOnly)]
+ [InlineData("https://localhost", HttpBindingSecurityMode.Transport)]
+ public void HttpSelfHostConfiguration_UseWindowsAuth_PropagatesToHttpBinding(string address, HttpBindingSecurityMode mode)
+ {
+ // Arrange
+ HttpBinding binding = new HttpBinding();
+ HttpSelfHostConfiguration config = new HttpSelfHostConfiguration(address)
+ {
+ UseWindowsAuthentication = true
+ };
+
+ // Act
+ BindingParameterCollection parameters = config.ConfigureBinding(binding);
+
+ // Assert
+ Assert.NotNull(parameters);
+ ServiceCredentials serviceCredentials = parameters.Find();
+ Assert.NotNull(serviceCredentials);
+ Assert.Equal(HttpClientCredentialType.Windows, binding.Security.Transport.ClientCredentialType);
+ Assert.Equal(mode, binding.Security.Mode);
+ }
+
+ [Theory]
+ [InlineData("http://localhost", HttpBindingSecurityMode.TransportCredentialOnly)]
+ [InlineData("https://localhost", HttpBindingSecurityMode.Transport)]
+ public void HttpSelfHostConfiguration_UserNamePasswordValidator_PropagatesToBinding(string address, HttpBindingSecurityMode mode)
+ {
+ // Arrange
+ HttpBinding binding = new HttpBinding();
+ UserNamePasswordValidator validator = new Mock().Object;
+ HttpSelfHostConfiguration config = new HttpSelfHostConfiguration(address)
+ {
+ UserNamePasswordValidator = validator
+ };
+
+ // Act
+ BindingParameterCollection parameters = config.ConfigureBinding(binding);
+
+ // Assert
+ Assert.NotNull(parameters);
+ ServiceCredentials serviceCredentials = parameters.Find();
+ Assert.NotNull(serviceCredentials);
+ Assert.Equal(HttpClientCredentialType.Basic, binding.Security.Transport.ClientCredentialType);
+ Assert.Equal(mode, binding.Security.Mode);
+ }
+
+ private static int GetDefaultMaxConcurrentRequests()
+ {
+ try
+ {
+ return Math.Max(Environment.ProcessorCount * 100, 100);
+ }
+ catch
+ {
+ return 100;
+ }
+ }
+ }
+}
diff --git a/test/System.Web.Http.SelfHost.Test/Properties/AssemblyInfo.cs b/test/System.Web.Http.SelfHost.Test/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000..9155b469
--- /dev/null
+++ b/test/System.Web.Http.SelfHost.Test/Properties/AssemblyInfo.cs
@@ -0,0 +1,3 @@
+using System;
+
+[assembly: CLSCompliant(false)]
diff --git a/test/System.Web.Http.SelfHost.Test/System.Web.Http.SelfHost.Test.csproj b/test/System.Web.Http.SelfHost.Test/System.Web.Http.SelfHost.Test.csproj
new file mode 100644
index 00000000..caf1c23f
--- /dev/null
+++ b/test/System.Web.Http.SelfHost.Test/System.Web.Http.SelfHost.Test.csproj
@@ -0,0 +1,92 @@
+
+
+
+
+ Debug
+ AnyCPU
+ 9.0.30729
+ 2.0
+ {7F29EE87-6A63-43C6-B7FF-74DD06815830}
+ Library
+ Properties
+ System.Web.Http.SelfHost
+ System.Web.Http.SelfHost.Test
+ 512
+ {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ prompt
+ 4
+ true
+
+
+ true
+ full
+ false
+ $(WebStackRootPath)\bin\Debug\Test\
+ TRACE;DEBUG
+ MinimumRecommendedRules.ruleset
+
+
+ pdbonly
+ true
+ $(WebStackRootPath)\bin\Release\Test\
+ TRACE
+ MinimumRecommendedRules.ruleset
+
+
+ true
+ full
+ false
+ $(WebStackRootPath)\bin\CodeCoverage\Test\
+ TRACE;DEBUG
+ MinimumRecommendedRules.ruleset
+
+
+
+ ..\..\packages\Moq.4.0.10827\lib\NET40\Moq.dll
+
+
+
+
+
+
+ ..\..\packages\Microsoft.Net.Http.2.0.20302.1\lib\net40\System.Net.Http.dll
+
+
+ ..\..\packages\Microsoft.Net.Http.2.0.20302.1\lib\net40\System.Net.Http.WebRequest.dll
+
+
+
+
+ ..\..\packages\xunit.1.9.0.1566\lib\xunit.dll
+
+
+ ..\..\packages\xunit.extensions.1.9.0.1566\lib\xunit.extensions.dll
+
+
+
+
+
+
+
+
+
+
+
+ {66492E69-CE4C-4FB1-9B1F-88DEE09D06F1}
+ System.Web.Http.SelfHost
+
+
+ {DDC1CE0C-486E-4E35-BB3B-EAB61F8F9440}
+ System.Web.Http
+
+
+ {3D3FFD8A-624D-4E9B-954B-E1C105507975}
+ System.Web.Mvc
+
+
+ {FCCC4CB7-BAF7-4A57-9F89-E5766FE536C0}
+ Microsoft.TestCommon
+
+
+
+
\ No newline at end of file
diff --git a/test/System.Web.Http.SelfHost.Test/packages.config b/test/System.Web.Http.SelfHost.Test/packages.config
new file mode 100644
index 00000000..b9070f9e
--- /dev/null
+++ b/test/System.Web.Http.SelfHost.Test/packages.config
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file