#52 - Enable parallel tests by using dynamic ports.

This commit is contained in:
Chris Ross 2014-07-24 16:13:03 -07:00
parent 53e38e2a23
commit 6fab49b6e0
30 changed files with 636 additions and 451 deletions

View File

@ -47,6 +47,24 @@ namespace Microsoft.Net.Server
/// <param name="port">If empty, the default port for the given scheme will be used (80 or 443).</param> /// <param name="port">If empty, the default port for the given scheme will be used (80 or 443).</param>
/// <param name="path">Should start and end with a '/', though a missing trailing slash will be added. This value must be un-escaped.</param> /// <param name="path">Should start and end with a '/', though a missing trailing slash will be added. This value must be un-escaped.</param>
public static UrlPrefix Create(string scheme, string host, string port, string path) public static UrlPrefix Create(string scheme, string host, string port, string path)
{
int? portValue = null;
if (!string.IsNullOrWhiteSpace(port))
{
portValue = int.Parse(port, NumberStyles.None, CultureInfo.InvariantCulture);
}
return UrlPrefix.Create(scheme, host, portValue, path);
}
/// <summary>
/// http://msdn.microsoft.com/en-us/library/windows/desktop/aa364698(v=vs.85).aspx
/// </summary>
/// <param name="scheme">http or https. Will be normalized to lower case.</param>
/// <param name="host">+, *, IPv4, [IPv6], or a dns name. Http.Sys does not permit punycode (xn--), use Unicode instead.</param>
/// <param name="port">If empty, the default port for the given scheme will be used (80 or 443).</param>
/// <param name="path">Should start and end with a '/', though a missing trailing slash will be added. This value must be un-escaped.</param>
public static UrlPrefix Create(string scheme, string host, int? portValue, string path)
{ {
bool isHttps; bool isHttps;
if (string.Equals(Constants.HttpScheme, scheme, StringComparison.OrdinalIgnoreCase)) if (string.Equals(Constants.HttpScheme, scheme, StringComparison.OrdinalIgnoreCase))
@ -69,15 +87,15 @@ namespace Microsoft.Net.Server
throw new ArgumentNullException("host"); throw new ArgumentNullException("host");
} }
int portValue; string port;
if (string.IsNullOrWhiteSpace(port)) if (!portValue.HasValue)
{ {
port = isHttps ? "443" : "80"; port = isHttps ? "443" : "80";
portValue = isHttps ? 443 : 80; portValue = isHttps ? 443 : 80;
} }
else else
{ {
portValue = int.Parse(port, NumberStyles.None, CultureInfo.InvariantCulture); port = portValue.Value.ToString(CultureInfo.InvariantCulture);
} }
// Http.Sys requires the path end with a slash. // Http.Sys requires the path end with a slash.
@ -90,14 +108,14 @@ namespace Microsoft.Net.Server
path += "/"; path += "/";
} }
return new UrlPrefix(isHttps, scheme, host, port, portValue, path); return new UrlPrefix(isHttps, scheme, host, port, portValue.Value, path);
} }
public static UrlPrefix Create(string prefix) public static UrlPrefix Create(string prefix)
{ {
string scheme = null; string scheme = null;
string host = null; string host = null;
string port = null; int? port = null;
string path = null; string path = null;
string whole = prefix ?? string.Empty; string whole = prefix ?? string.Empty;
@ -123,11 +141,11 @@ namespace Microsoft.Net.Server
scheme = whole.Substring(0, delimiterStart1); scheme = whole.Substring(0, delimiterStart1);
string portString = whole.Substring(delimiterEnd2, delimiterStart3 - delimiterEnd2); string portString = whole.Substring(delimiterEnd2, delimiterStart3 - delimiterEnd2);
int ignored; int portValue;
if (int.TryParse(portString, NumberStyles.Integer, CultureInfo.InvariantCulture, out ignored)) if (int.TryParse(portString, NumberStyles.Integer, CultureInfo.InvariantCulture, out portValue))
{ {
host = whole.Substring(delimiterEnd1, delimiterStart2 - delimiterEnd1); host = whole.Substring(delimiterEnd1, delimiterStart2 - delimiterEnd1);
port = portString; port = portValue;
} }
else else
{ {

View File

@ -29,8 +29,6 @@ namespace Microsoft.AspNet.Server.WebListener
{ {
public class AuthenticationTests public class AuthenticationTests
{ {
private const string Address = "http://localhost:8080/";
[Theory] [Theory]
[InlineData(AuthenticationTypes.AllowAnonymous)] [InlineData(AuthenticationTypes.AllowAnonymous)]
[InlineData(AuthenticationTypes.Kerberos)] [InlineData(AuthenticationTypes.Kerberos)]
@ -41,7 +39,8 @@ namespace Microsoft.AspNet.Server.WebListener
[InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /*AuthenticationTypes.Digest |*/ AuthenticationTypes.Basic)] [InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /*AuthenticationTypes.Digest |*/ AuthenticationTypes.Basic)]
public async Task AuthTypes_AllowAnonymous_NoChallenge(AuthenticationTypes authType) public async Task AuthTypes_AllowAnonymous_NoChallenge(AuthenticationTypes authType)
{ {
using (Utilities.CreateAuthServer(authType | AuthenticationTypes.AllowAnonymous, env => string address;
using (Utilities.CreateHttpAuthServer(authType | AuthenticationTypes.AllowAnonymous, out address, env =>
{ {
var context = new DefaultHttpContext((IFeatureCollection)env); var context = new DefaultHttpContext((IFeatureCollection)env);
Assert.NotNull(context.User); Assert.NotNull(context.User);
@ -49,7 +48,7 @@ namespace Microsoft.AspNet.Server.WebListener
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
var response = await SendRequestAsync(Address); var response = await SendRequestAsync(address);
Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal(0, response.Headers.WwwAuthenticate.Count); Assert.Equal(0, response.Headers.WwwAuthenticate.Count);
} }
@ -63,12 +62,13 @@ namespace Microsoft.AspNet.Server.WebListener
[InlineData(AuthenticationTypes.Basic)] [InlineData(AuthenticationTypes.Basic)]
public async Task AuthType_RequireAuth_ChallengesAdded(AuthenticationTypes authType) public async Task AuthType_RequireAuth_ChallengesAdded(AuthenticationTypes authType)
{ {
using (Utilities.CreateAuthServer(authType, env => string address;
using (Utilities.CreateHttpAuthServer(authType, out address, env =>
{ {
throw new NotImplementedException(); throw new NotImplementedException();
})) }))
{ {
var response = await SendRequestAsync(Address); var response = await SendRequestAsync(address);
Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
Assert.Equal(authType.ToString(), response.Headers.WwwAuthenticate.ToString(), StringComparer.OrdinalIgnoreCase); Assert.Equal(authType.ToString(), response.Headers.WwwAuthenticate.ToString(), StringComparer.OrdinalIgnoreCase);
} }
@ -82,7 +82,8 @@ namespace Microsoft.AspNet.Server.WebListener
[InlineData(AuthenticationTypes.Basic)] [InlineData(AuthenticationTypes.Basic)]
public async Task AuthType_AllowAnonymousButSpecify401_ChallengesAdded(AuthenticationTypes authType) public async Task AuthType_AllowAnonymousButSpecify401_ChallengesAdded(AuthenticationTypes authType)
{ {
using (Utilities.CreateAuthServer(authType | AuthenticationTypes.AllowAnonymous, env => string address;
using (Utilities.CreateHttpAuthServer(authType | AuthenticationTypes.AllowAnonymous, out address, env =>
{ {
var context = new DefaultHttpContext((IFeatureCollection)env); var context = new DefaultHttpContext((IFeatureCollection)env);
Assert.NotNull(context.User); Assert.NotNull(context.User);
@ -91,7 +92,7 @@ namespace Microsoft.AspNet.Server.WebListener
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
var response = await SendRequestAsync(Address); var response = await SendRequestAsync(address);
Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
Assert.Equal(authType.ToString(), response.Headers.WwwAuthenticate.ToString(), StringComparer.OrdinalIgnoreCase); Assert.Equal(authType.ToString(), response.Headers.WwwAuthenticate.ToString(), StringComparer.OrdinalIgnoreCase);
} }
@ -100,13 +101,15 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task MultipleAuthTypes_AllowAnonymousButSpecify401_ChallengesAdded() public async Task MultipleAuthTypes_AllowAnonymousButSpecify401_ChallengesAdded()
{ {
using (Utilities.CreateAuthServer( string address;
using (Utilities.CreateHttpAuthServer(
AuthenticationTypes.Kerberos AuthenticationTypes.Kerberos
| AuthenticationTypes.Negotiate | AuthenticationTypes.Negotiate
| AuthenticationTypes.NTLM | AuthenticationTypes.NTLM
/* | AuthenticationTypes.Digest TODO: Not implemented */ /* | AuthenticationTypes.Digest TODO: Not implemented */
| AuthenticationTypes.Basic | AuthenticationTypes.Basic
| AuthenticationTypes.AllowAnonymous, | AuthenticationTypes.AllowAnonymous,
out address,
env => env =>
{ {
var context = new DefaultHttpContext((IFeatureCollection)env); var context = new DefaultHttpContext((IFeatureCollection)env);
@ -116,7 +119,7 @@ namespace Microsoft.AspNet.Server.WebListener
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
var response = await SendRequestAsync(Address); var response = await SendRequestAsync(address);
Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
Assert.Equal("Kerberos, Negotiate, NTLM, basic", response.Headers.WwwAuthenticate.ToString(), StringComparer.OrdinalIgnoreCase); Assert.Equal("Kerberos, Negotiate, NTLM, basic", response.Headers.WwwAuthenticate.ToString(), StringComparer.OrdinalIgnoreCase);
} }
@ -131,8 +134,9 @@ namespace Microsoft.AspNet.Server.WebListener
[InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /* AuthenticationTypes.Digest |*/ AuthenticationTypes.Basic)] [InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /* AuthenticationTypes.Digest |*/ AuthenticationTypes.Basic)]
public async Task AuthTypes_AllowAnonymousButSpecify401_Success(AuthenticationTypes authType) public async Task AuthTypes_AllowAnonymousButSpecify401_Success(AuthenticationTypes authType)
{ {
string address;
int requestId = 0; int requestId = 0;
using (Utilities.CreateAuthServer(authType | AuthenticationTypes.AllowAnonymous, env => using (Utilities.CreateHttpAuthServer(authType | AuthenticationTypes.AllowAnonymous, out address, env =>
{ {
var context = new DefaultHttpContext((IFeatureCollection)env); var context = new DefaultHttpContext((IFeatureCollection)env);
Assert.NotNull(context.User); Assert.NotNull(context.User);
@ -153,7 +157,7 @@ namespace Microsoft.AspNet.Server.WebListener
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
var response = await SendRequestAsync(Address, useDefaultCredentials: true); var response = await SendRequestAsync(address, useDefaultCredentials: true);
Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.StatusCode);
} }
} }
@ -167,7 +171,8 @@ namespace Microsoft.AspNet.Server.WebListener
[InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /* AuthenticationTypes.Digest |*/ AuthenticationTypes.Basic)] [InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /* AuthenticationTypes.Digest |*/ AuthenticationTypes.Basic)]
public async Task AuthTypes_RequireAuth_Success(AuthenticationTypes authType) public async Task AuthTypes_RequireAuth_Success(AuthenticationTypes authType)
{ {
using (Utilities.CreateAuthServer(authType, env => string address;
using (Utilities.CreateHttpAuthServer(authType, out address, env =>
{ {
var context = new DefaultHttpContext((IFeatureCollection)env); var context = new DefaultHttpContext((IFeatureCollection)env);
Assert.NotNull(context.User); Assert.NotNull(context.User);
@ -175,7 +180,7 @@ namespace Microsoft.AspNet.Server.WebListener
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
var response = await SendRequestAsync(Address, useDefaultCredentials: true); var response = await SendRequestAsync(address, useDefaultCredentials: true);
Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.StatusCode);
} }
} }
@ -190,7 +195,8 @@ namespace Microsoft.AspNet.Server.WebListener
// [InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /*AuthenticationTypes.Digest |*/ AuthenticationTypes.Basic)] // [InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /*AuthenticationTypes.Digest |*/ AuthenticationTypes.Basic)]
public async Task AuthTypes_GetSingleDescriptions(AuthenticationTypes authType) public async Task AuthTypes_GetSingleDescriptions(AuthenticationTypes authType)
{ {
using (Utilities.CreateAuthServer(authType | AuthenticationTypes.AllowAnonymous, env => string address;
using (Utilities.CreateHttpAuthServer(authType | AuthenticationTypes.AllowAnonymous, out address, env =>
{ {
var context = new DefaultHttpContext((IFeatureCollection)env); var context = new DefaultHttpContext((IFeatureCollection)env);
var resultList = context.GetAuthenticationTypes(); var resultList = context.GetAuthenticationTypes();
@ -209,7 +215,7 @@ namespace Microsoft.AspNet.Server.WebListener
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
var response = await SendRequestAsync(Address); var response = await SendRequestAsync(address);
Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal(0, response.Headers.WwwAuthenticate.Count); Assert.Equal(0, response.Headers.WwwAuthenticate.Count);
} }
@ -218,13 +224,14 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task AuthTypes_GetMultipleDescriptions() public async Task AuthTypes_GetMultipleDescriptions()
{ {
string address;
AuthenticationTypes authType = AuthenticationTypes authType =
AuthenticationTypes.Kerberos AuthenticationTypes.Kerberos
| AuthenticationTypes.Negotiate | AuthenticationTypes.Negotiate
| AuthenticationTypes.NTLM | AuthenticationTypes.NTLM
| /*AuthenticationTypes.Digest | /*AuthenticationTypes.Digest
|*/ AuthenticationTypes.Basic; |*/ AuthenticationTypes.Basic;
using (Utilities.CreateAuthServer(authType | AuthenticationTypes.AllowAnonymous, env => using (Utilities.CreateHttpAuthServer(authType | AuthenticationTypes.AllowAnonymous, out address, env =>
{ {
var context = new DefaultHttpContext((IFeatureCollection)env); var context = new DefaultHttpContext((IFeatureCollection)env);
var resultList = context.GetAuthenticationTypes(); var resultList = context.GetAuthenticationTypes();
@ -232,7 +239,7 @@ namespace Microsoft.AspNet.Server.WebListener
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
var response = await SendRequestAsync(Address); var response = await SendRequestAsync(address);
Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal(0, response.Headers.WwwAuthenticate.Count); Assert.Equal(0, response.Headers.WwwAuthenticate.Count);
} }
@ -247,8 +254,9 @@ namespace Microsoft.AspNet.Server.WebListener
[InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /*AuthenticationTypes.Digest |*/ AuthenticationTypes.Basic)] [InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /*AuthenticationTypes.Digest |*/ AuthenticationTypes.Basic)]
public async Task AuthTypes_AuthenticateWithNoUser_NoResults(AuthenticationTypes authType) public async Task AuthTypes_AuthenticateWithNoUser_NoResults(AuthenticationTypes authType)
{ {
string address;
var authTypeList = authType.ToString().Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries); var authTypeList = authType.ToString().Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
using (Utilities.CreateAuthServer(authType | AuthenticationTypes.AllowAnonymous, env => using (Utilities.CreateHttpAuthServer(authType | AuthenticationTypes.AllowAnonymous, out address, env =>
{ {
var context = new DefaultHttpContext((IFeatureCollection)env); var context = new DefaultHttpContext((IFeatureCollection)env);
Assert.NotNull(context.User); Assert.NotNull(context.User);
@ -258,7 +266,7 @@ namespace Microsoft.AspNet.Server.WebListener
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
var response = await SendRequestAsync(Address); var response = await SendRequestAsync(address);
Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal(0, response.Headers.WwwAuthenticate.Count); Assert.Equal(0, response.Headers.WwwAuthenticate.Count);
} }
@ -273,8 +281,9 @@ namespace Microsoft.AspNet.Server.WebListener
[InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /*AuthenticationTypes.Digest |*/ AuthenticationTypes.Basic)] [InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /*AuthenticationTypes.Digest |*/ AuthenticationTypes.Basic)]
public async Task AuthTypes_AuthenticateWithUser_OneResult(AuthenticationTypes authType) public async Task AuthTypes_AuthenticateWithUser_OneResult(AuthenticationTypes authType)
{ {
string address;
var authTypeList = authType.ToString().Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries); var authTypeList = authType.ToString().Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
using (Utilities.CreateAuthServer(authType, env => using (Utilities.CreateHttpAuthServer(authType, out address, env =>
{ {
var context = new DefaultHttpContext((IFeatureCollection)env); var context = new DefaultHttpContext((IFeatureCollection)env);
Assert.NotNull(context.User); Assert.NotNull(context.User);
@ -284,7 +293,7 @@ namespace Microsoft.AspNet.Server.WebListener
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
var response = await SendRequestAsync(Address, useDefaultCredentials: true); var response = await SendRequestAsync(address, useDefaultCredentials: true);
Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.StatusCode);
} }
} }
@ -298,8 +307,9 @@ namespace Microsoft.AspNet.Server.WebListener
[InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /*AuthenticationTypes.Digest |*/ AuthenticationTypes.Basic)] [InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /*AuthenticationTypes.Digest |*/ AuthenticationTypes.Basic)]
public async Task AuthTypes_ChallengeWithoutAuthTypes_AllChallengesSent(AuthenticationTypes authType) public async Task AuthTypes_ChallengeWithoutAuthTypes_AllChallengesSent(AuthenticationTypes authType)
{ {
string address;
var authTypeList = authType.ToString().Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries); var authTypeList = authType.ToString().Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
using (Utilities.CreateAuthServer(authType | AuthenticationTypes.AllowAnonymous, env => using (Utilities.CreateHttpAuthServer(authType | AuthenticationTypes.AllowAnonymous, out address, env =>
{ {
var context = new DefaultHttpContext((IFeatureCollection)env); var context = new DefaultHttpContext((IFeatureCollection)env);
Assert.NotNull(context.User); Assert.NotNull(context.User);
@ -308,7 +318,7 @@ namespace Microsoft.AspNet.Server.WebListener
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
var response = await SendRequestAsync(Address); var response = await SendRequestAsync(address);
Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
Assert.Equal(authTypeList.Count(), response.Headers.WwwAuthenticate.Count); Assert.Equal(authTypeList.Count(), response.Headers.WwwAuthenticate.Count);
} }
@ -323,8 +333,9 @@ namespace Microsoft.AspNet.Server.WebListener
[InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /*AuthenticationTypes.Digest |*/ AuthenticationTypes.Basic)] [InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /*AuthenticationTypes.Digest |*/ AuthenticationTypes.Basic)]
public async Task AuthTypes_ChallengeWithAllAuthTypes_AllChallengesSent(AuthenticationTypes authType) public async Task AuthTypes_ChallengeWithAllAuthTypes_AllChallengesSent(AuthenticationTypes authType)
{ {
string address;
var authTypeList = authType.ToString().Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries); var authTypeList = authType.ToString().Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
using (Utilities.CreateAuthServer(authType | AuthenticationTypes.AllowAnonymous, env => using (Utilities.CreateHttpAuthServer(authType | AuthenticationTypes.AllowAnonymous, out address, env =>
{ {
var context = new DefaultHttpContext((IFeatureCollection)env); var context = new DefaultHttpContext((IFeatureCollection)env);
Assert.NotNull(context.User); Assert.NotNull(context.User);
@ -333,7 +344,7 @@ namespace Microsoft.AspNet.Server.WebListener
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
var response = await SendRequestAsync(Address); var response = await SendRequestAsync(address);
Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
Assert.Equal(authTypeList.Count(), response.Headers.WwwAuthenticate.Count); Assert.Equal(authTypeList.Count(), response.Headers.WwwAuthenticate.Count);
} }
@ -347,8 +358,9 @@ namespace Microsoft.AspNet.Server.WebListener
[InlineData(AuthenticationTypes.Basic)] [InlineData(AuthenticationTypes.Basic)]
public async Task AuthTypes_ChallengeOneAuthType_OneChallengeSent(AuthenticationTypes authType) public async Task AuthTypes_ChallengeOneAuthType_OneChallengeSent(AuthenticationTypes authType)
{ {
string address;
var authTypes = AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /*AuthenticationTypes.Digest |*/ AuthenticationTypes.Basic; var authTypes = AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /*AuthenticationTypes.Digest |*/ AuthenticationTypes.Basic;
using (Utilities.CreateAuthServer(authTypes | AuthenticationTypes.AllowAnonymous, env => using (Utilities.CreateHttpAuthServer(authTypes | AuthenticationTypes.AllowAnonymous, out address, env =>
{ {
var context = new DefaultHttpContext((IFeatureCollection)env); var context = new DefaultHttpContext((IFeatureCollection)env);
Assert.NotNull(context.User); Assert.NotNull(context.User);
@ -357,7 +369,7 @@ namespace Microsoft.AspNet.Server.WebListener
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
var response = await SendRequestAsync(Address); var response = await SendRequestAsync(address);
Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
Assert.Equal(1, response.Headers.WwwAuthenticate.Count); Assert.Equal(1, response.Headers.WwwAuthenticate.Count);
Assert.Equal(authType.ToString(), response.Headers.WwwAuthenticate.First().Scheme); Assert.Equal(authType.ToString(), response.Headers.WwwAuthenticate.First().Scheme);
@ -372,10 +384,11 @@ namespace Microsoft.AspNet.Server.WebListener
[InlineData(AuthenticationTypes.Basic)] [InlineData(AuthenticationTypes.Basic)]
public async Task AuthTypes_ChallengeDisabledAuthType_Error(AuthenticationTypes authType) public async Task AuthTypes_ChallengeDisabledAuthType_Error(AuthenticationTypes authType)
{ {
string address;
var authTypes = AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /*AuthenticationTypes.Digest |*/ AuthenticationTypes.Basic; var authTypes = AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /*AuthenticationTypes.Digest |*/ AuthenticationTypes.Basic;
authTypes = authTypes & ~authType; authTypes = authTypes & ~authType;
var authTypeList = authType.ToString().Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries); var authTypeList = authType.ToString().Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
using (Utilities.CreateAuthServer(authTypes | AuthenticationTypes.AllowAnonymous, env => using (Utilities.CreateHttpAuthServer(authTypes | AuthenticationTypes.AllowAnonymous, out address, env =>
{ {
var context = new DefaultHttpContext((IFeatureCollection)env); var context = new DefaultHttpContext((IFeatureCollection)env);
Assert.NotNull(context.User); Assert.NotNull(context.User);
@ -384,7 +397,7 @@ namespace Microsoft.AspNet.Server.WebListener
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
var response = await SendRequestAsync(Address); var response = await SendRequestAsync(address);
Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
Assert.Equal(0, response.Headers.WwwAuthenticate.Count); Assert.Equal(0, response.Headers.WwwAuthenticate.Count);
} }

View File

@ -22,7 +22,6 @@
<Compile Include="HttpsTests.cs" /> <Compile Include="HttpsTests.cs" />
<Compile Include="WebSocketTests.cs" /> <Compile Include="WebSocketTests.cs" />
<Compile Include="OpaqueUpgradeTests.cs" /> <Compile Include="OpaqueUpgradeTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RequestBodyTests.cs" /> <Compile Include="RequestBodyTests.cs" />
<Compile Include="RequestHeaderTests.cs" /> <Compile Include="RequestHeaderTests.cs" />
<Compile Include="RequestTests.cs" /> <Compile Include="RequestTests.cs" />

View File

@ -16,7 +16,6 @@
// permissions and limitations under the License. // permissions and limitations under the License.
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Net.Http; using System.Net.Http;
using System.Net.Sockets; using System.Net.Sockets;
@ -24,8 +23,8 @@ using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNet.FeatureModel; using Microsoft.AspNet.FeatureModel;
using Microsoft.AspNet.HttpFeature;
using Microsoft.AspNet.Http; using Microsoft.AspNet.Http;
using Microsoft.AspNet.HttpFeature;
using Microsoft.AspNet.PipelineCore; using Microsoft.AspNet.PipelineCore;
using Xunit; using Xunit;
@ -33,12 +32,11 @@ namespace Microsoft.AspNet.Server.WebListener
{ {
public class OpaqueUpgradeTests public class OpaqueUpgradeTests
{ {
private const string Address = "http://localhost:8080/";
[Fact] [Fact]
public async Task OpaqueUpgrade_SupportKeys_Present() public async Task OpaqueUpgrade_SupportKeys_Present()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
try try
@ -53,7 +51,7 @@ namespace Microsoft.AspNet.Server.WebListener
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
HttpResponseMessage response = await SendRequestAsync(Address); HttpResponseMessage response = await SendRequestAsync(address);
Assert.Equal(200, (int)response.StatusCode); Assert.Equal(200, (int)response.StatusCode);
Assert.False(response.Headers.TransferEncodingChunked.HasValue, "Chunked"); Assert.False(response.Headers.TransferEncodingChunked.HasValue, "Chunked");
Assert.Equal(0, response.Content.Headers.ContentLength); Assert.Equal(0, response.Content.Headers.ContentLength);
@ -65,7 +63,8 @@ namespace Microsoft.AspNet.Server.WebListener
public async Task OpaqueUpgrade_AfterHeadersSent_Throws() public async Task OpaqueUpgrade_AfterHeadersSent_Throws()
{ {
bool? upgradeThrew = null; bool? upgradeThrew = null;
using (Utilities.CreateHttpServer(async env => string address;
using (Utilities.CreateHttpServer(out address, async env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
await httpContext.Response.WriteAsync("Hello World"); await httpContext.Response.WriteAsync("Hello World");
@ -82,7 +81,7 @@ namespace Microsoft.AspNet.Server.WebListener
} }
})) }))
{ {
HttpResponseMessage response = await SendRequestAsync(Address); HttpResponseMessage response = await SendRequestAsync(address);
Assert.Equal(200, (int)response.StatusCode); Assert.Equal(200, (int)response.StatusCode);
Assert.True(response.Headers.TransferEncodingChunked.Value, "Chunked"); Assert.True(response.Headers.TransferEncodingChunked.Value, "Chunked");
Assert.True(upgradeThrew.Value); Assert.True(upgradeThrew.Value);
@ -94,7 +93,8 @@ namespace Microsoft.AspNet.Server.WebListener
{ {
ManualResetEvent waitHandle = new ManualResetEvent(false); ManualResetEvent waitHandle = new ManualResetEvent(false);
bool? upgraded = null; bool? upgraded = null;
using (Utilities.CreateHttpServer(async env => string address;
using (Utilities.CreateHttpServer(out address, async env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
httpContext.Response.Headers["Upgrade"] = "websocket"; // Win8.1 blocks anything but WebSockets httpContext.Response.Headers["Upgrade"] = "websocket"; // Win8.1 blocks anything but WebSockets
@ -106,7 +106,7 @@ namespace Microsoft.AspNet.Server.WebListener
waitHandle.Set(); waitHandle.Set();
})) }))
{ {
using (Stream stream = await SendOpaqueRequestAsync("GET", Address)) using (Stream stream = await SendOpaqueRequestAsync("GET", address))
{ {
Assert.True(waitHandle.WaitOne(TimeSpan.FromSeconds(1)), "Timed out"); Assert.True(waitHandle.WaitOne(TimeSpan.FromSeconds(1)), "Timed out");
Assert.True(upgraded.HasValue, "Upgraded not set"); Assert.True(upgraded.HasValue, "Upgraded not set");
@ -140,7 +140,8 @@ namespace Microsoft.AspNet.Server.WebListener
[InlineData("PUT", "Content-Length: 0")] [InlineData("PUT", "Content-Length: 0")]
public async Task OpaqueUpgrade_VariousMethodsUpgradeSendAndReceive_Success(string method, string extraHeader) public async Task OpaqueUpgrade_VariousMethodsUpgradeSendAndReceive_Success(string method, string extraHeader)
{ {
using (Utilities.CreateHttpServer(async env => string address;
using (Utilities.CreateHttpServer(out address, async env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
try try
@ -162,7 +163,7 @@ namespace Microsoft.AspNet.Server.WebListener
} }
})) }))
{ {
using (Stream stream = await SendOpaqueRequestAsync(method, Address, extraHeader)) using (Stream stream = await SendOpaqueRequestAsync(method, address, extraHeader))
{ {
byte[] data = new byte[100]; byte[] data = new byte[100];
stream.WriteAsync(data, 0, 49).Wait(); stream.WriteAsync(data, 0, 49).Wait();
@ -182,7 +183,8 @@ namespace Microsoft.AspNet.Server.WebListener
[InlineData("CUSTOMVERB", "Transfer-Encoding: chunked")] [InlineData("CUSTOMVERB", "Transfer-Encoding: chunked")]
public async Task OpaqueUpgrade_InvalidMethodUpgrade_Disconnected(string method, string extraHeader) public async Task OpaqueUpgrade_InvalidMethodUpgrade_Disconnected(string method, string extraHeader)
{ {
using (Utilities.CreateHttpServer(async env => string address;
using (Utilities.CreateHttpServer(out address, async env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
try try
@ -197,7 +199,7 @@ namespace Microsoft.AspNet.Server.WebListener
} }
})) }))
{ {
await Assert.ThrowsAsync<InvalidOperationException>(async () => await SendOpaqueRequestAsync(method, Address, extraHeader)); await Assert.ThrowsAsync<InvalidOperationException>(async () => await SendOpaqueRequestAsync(method, address, extraHeader));
} }
} }

View File

@ -1,19 +0,0 @@
// Copyright (c) Microsoft Open Technologies, Inc.
// All Rights Reserved
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
// See the Apache 2 License for the specific language governing
// permissions and limitations under the License.
// These tests can't run in parallel because they all use the same port.
[assembly: Xunit.CollectionBehaviorAttribute(Xunit.CollectionBehavior.CollectionPerAssembly, DisableTestParallelization = true)]

View File

@ -31,12 +31,11 @@ namespace Microsoft.AspNet.Server.WebListener
{ {
public class RequestBodyTests public class RequestBodyTests
{ {
private const string Address = "http://localhost:8080/";
[Fact] [Fact]
public async Task RequestBody_ReadSync_Success() public async Task RequestBody_ReadSync_Success()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
byte[] input = new byte[100]; byte[] input = new byte[100];
@ -46,7 +45,7 @@ namespace Microsoft.AspNet.Server.WebListener
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
string response = await SendRequestAsync(Address, "Hello World"); string response = await SendRequestAsync(address, "Hello World");
Assert.Equal("Hello World", response); Assert.Equal("Hello World", response);
} }
} }
@ -54,7 +53,8 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task RequestBody_ReadAync_Success() public async Task RequestBody_ReadAync_Success()
{ {
using (Utilities.CreateHttpServer(async env => string address;
using (Utilities.CreateHttpServer(out address, async env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
byte[] input = new byte[100]; byte[] input = new byte[100];
@ -63,7 +63,7 @@ namespace Microsoft.AspNet.Server.WebListener
await httpContext.Response.Body.WriteAsync(input, 0, read); await httpContext.Response.Body.WriteAsync(input, 0, read);
})) }))
{ {
string response = await SendRequestAsync(Address, "Hello World"); string response = await SendRequestAsync(address, "Hello World");
Assert.Equal("Hello World", response); Assert.Equal("Hello World", response);
} }
} }
@ -71,7 +71,8 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task RequestBody_ReadBeginEnd_Success() public async Task RequestBody_ReadBeginEnd_Success()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
byte[] input = new byte[100]; byte[] input = new byte[100];
@ -81,7 +82,7 @@ namespace Microsoft.AspNet.Server.WebListener
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
string response = await SendRequestAsync(Address, "Hello World"); string response = await SendRequestAsync(address, "Hello World");
Assert.Equal("Hello World", response); Assert.Equal("Hello World", response);
} }
} }
@ -90,7 +91,8 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task RequestBody_InvalidBuffer_ArgumentException() public async Task RequestBody_InvalidBuffer_ArgumentException()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
byte[] input = new byte[100]; byte[] input = new byte[100];
@ -104,7 +106,7 @@ namespace Microsoft.AspNet.Server.WebListener
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
string response = await SendRequestAsync(Address, "Hello World"); string response = await SendRequestAsync(address, "Hello World");
Assert.Equal(string.Empty, response); Assert.Equal(string.Empty, response);
} }
} }
@ -113,7 +115,8 @@ namespace Microsoft.AspNet.Server.WebListener
public async Task RequestBody_ReadSyncPartialBody_Success() public async Task RequestBody_ReadSyncPartialBody_Success()
{ {
StaggardContent content = new StaggardContent(); StaggardContent content = new StaggardContent();
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
byte[] input = new byte[10]; byte[] input = new byte[10];
@ -125,7 +128,7 @@ namespace Microsoft.AspNet.Server.WebListener
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
string response = await SendRequestAsync(Address, content); string response = await SendRequestAsync(address, content);
Assert.Equal(string.Empty, response); Assert.Equal(string.Empty, response);
} }
} }
@ -134,7 +137,8 @@ namespace Microsoft.AspNet.Server.WebListener
public async Task RequestBody_ReadAsyncPartialBody_Success() public async Task RequestBody_ReadAsyncPartialBody_Success()
{ {
StaggardContent content = new StaggardContent(); StaggardContent content = new StaggardContent();
using (Utilities.CreateHttpServer(async env => string address;
using (Utilities.CreateHttpServer(out address, async env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
byte[] input = new byte[10]; byte[] input = new byte[10];
@ -145,7 +149,7 @@ namespace Microsoft.AspNet.Server.WebListener
Assert.Equal(5, read); Assert.Equal(5, read);
})) }))
{ {
string response = await SendRequestAsync(Address, content); string response = await SendRequestAsync(address, content);
Assert.Equal(string.Empty, response); Assert.Equal(string.Empty, response);
} }
} }
@ -153,7 +157,8 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task RequestBody_PostWithImidateBody_Success() public async Task RequestBody_PostWithImidateBody_Success()
{ {
using (Utilities.CreateHttpServer(async env => string address;
using (Utilities.CreateHttpServer(out address, async env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
byte[] input = new byte[11]; byte[] input = new byte[11];
@ -165,7 +170,7 @@ namespace Microsoft.AspNet.Server.WebListener
await httpContext.Response.Body.WriteAsync(input, 0, 10); await httpContext.Response.Body.WriteAsync(input, 0, 10);
})) }))
{ {
string response = await SendSocketRequestAsync(Address); string response = await SendSocketRequestAsync(address);
string[] lines = response.Split('\r', '\n'); string[] lines = response.Split('\r', '\n');
Assert.Equal(13, lines.Length); Assert.Equal(13, lines.Length);
Assert.Equal("HTTP/1.1 200 OK", lines[0]); Assert.Equal("HTTP/1.1 200 OK", lines[0]);

View File

@ -28,23 +28,22 @@ namespace Microsoft.AspNet.Server.WebListener
{ {
public class RequestHeaderTests public class RequestHeaderTests
{ {
private const string Address = "http://localhost:8080/";
[Fact] [Fact]
public async Task RequestHeaders_ClientSendsDefaultHeaders_Success() public async Task RequestHeaders_ClientSendsDefaultHeaders_Success()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var requestHeaders = new DefaultHttpContext((IFeatureCollection)env).Request.Headers; var requestHeaders = new DefaultHttpContext((IFeatureCollection)env).Request.Headers;
// NOTE: The System.Net client only sends the Connection: keep-alive header on the first connection per service-point. // NOTE: The System.Net client only sends the Connection: keep-alive header on the first connection per service-point.
// Assert.Equal(2, requestHeaders.Count); // Assert.Equal(2, requestHeaders.Count);
// Assert.Equal("Keep-Alive", requestHeaders.Get("Connection")); // Assert.Equal("Keep-Alive", requestHeaders.Get("Connection"));
Assert.Equal("localhost:8080", requestHeaders.Get("Host")); Assert.NotNull(requestHeaders.Get("Host"));
Assert.Equal(null, requestHeaders.Get("Accept")); Assert.Equal(null, requestHeaders.Get("Accept"));
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
string response = await SendRequestAsync(Address); string response = await SendRequestAsync(address);
Assert.Equal(string.Empty, response); Assert.Equal(string.Empty, response);
} }
} }
@ -52,23 +51,24 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task RequestHeaders_ClientSendsCustomHeaders_Success() public async Task RequestHeaders_ClientSendsCustomHeaders_Success()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var requestHeaders = new DefaultHttpContext((IFeatureCollection)env).Request.Headers; var requestHeaders = new DefaultHttpContext((IFeatureCollection)env).Request.Headers;
Assert.Equal(4, requestHeaders.Count); Assert.Equal(4, requestHeaders.Count);
Assert.Equal("localhost:8080", requestHeaders.Get("Host")); Assert.NotNull(requestHeaders.Get("Host"));
Assert.Equal("close", requestHeaders.Get("Connection")); Assert.Equal("close", requestHeaders.Get("Connection"));
Assert.Equal(1, requestHeaders["Custom-Header"].Length);
// Apparently Http.Sys squashes request headers together. // Apparently Http.Sys squashes request headers together.
Assert.Equal(1, requestHeaders.GetValues("Custom-Header").Count);
Assert.Equal("custom1, and custom2, custom3", requestHeaders.Get("Custom-Header")); Assert.Equal("custom1, and custom2, custom3", requestHeaders.Get("Custom-Header"));
Assert.Equal(1, requestHeaders["Spacer-Header"].Length); Assert.Equal(1, requestHeaders.GetValues("Spacer-Header").Count);
Assert.Equal("spacervalue, spacervalue", requestHeaders.Get("Spacer-Header")); Assert.Equal("spacervalue, spacervalue", requestHeaders.Get("Spacer-Header"));
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
string[] customValues = new string[] { "custom1, and custom2", "custom3" }; string[] customValues = new string[] { "custom1, and custom2", "custom3" };
await SendRequestAsync("localhost", 8080, "Custom-Header", customValues); await SendRequestAsync(address, "Custom-Header", customValues);
} }
} }
@ -80,15 +80,14 @@ namespace Microsoft.AspNet.Server.WebListener
} }
} }
private async Task SendRequestAsync(string host, int port, string customHeader, string[] customValues) private async Task SendRequestAsync(string address, string customHeader, string[] customValues)
{ {
var uri = new Uri(address);
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
builder.AppendLine("GET / HTTP/1.1"); builder.AppendLine("GET / HTTP/1.1");
builder.AppendLine("Connection: close"); builder.AppendLine("Connection: close");
builder.Append("HOST: "); builder.Append("HOST: ");
builder.Append(host); builder.AppendLine(uri.Authority);
builder.Append(':');
builder.AppendLine(port.ToString());
foreach (string value in customValues) foreach (string value in customValues)
{ {
builder.Append(customHeader); builder.Append(customHeader);
@ -101,7 +100,7 @@ namespace Microsoft.AspNet.Server.WebListener
byte[] request = Encoding.ASCII.GetBytes(builder.ToString()); byte[] request = Encoding.ASCII.GetBytes(builder.ToString());
Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp); Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
socket.Connect(host, port); socket.Connect(uri.Host, uri.Port);
socket.Send(request); socket.Send(request);

View File

@ -32,12 +32,11 @@ namespace Microsoft.AspNet.Server.WebListener
public class RequestTests public class RequestTests
{ {
private const string Address = "http://localhost:8080";
[Fact] [Fact]
public async Task Request_SimpleGet_Success() public async Task Request_SimpleGet_Success()
{ {
using (Utilities.CreateServer("http", "localhost", "8080", "/basepath", env => string root;
using (Utilities.CreateHttpServerReturnRoot("/basepath", out root, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
try try
@ -77,21 +76,22 @@ namespace Microsoft.AspNet.Server.WebListener
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
string response = await SendRequestAsync(Address + "/basepath/SomePath?SomeQuery"); string response = await SendRequestAsync(root + "/basepath/SomePath?SomeQuery");
Assert.Equal(string.Empty, response); Assert.Equal(string.Empty, response);
} }
} }
[Theory] [Theory]
[InlineData("/", "http://localhost:8080/", "", "/")] [InlineData("/", "/", "", "/")]
[InlineData("/basepath/", "http://localhost:8080/basepath", "/basepath", "")] [InlineData("/basepath/", "/basepath", "/basepath", "")]
[InlineData("/basepath/", "http://localhost:8080/basepath/", "/basepath", "/")] [InlineData("/basepath/", "/basepath/", "/basepath", "/")]
[InlineData("/basepath/", "http://localhost:8080/basepath/subpath", "/basepath", "/subpath")] [InlineData("/basepath/", "/basepath/subpath", "/basepath", "/subpath")]
[InlineData("/base path/", "http://localhost:8080/base%20path/sub path", "/base path", "/sub path")] [InlineData("/base path/", "/base%20path/sub path", "/base path", "/sub path")]
[InlineData("/base葉path/", "http://localhost:8080/base%E8%91%89path/sub%E8%91%89path", "/base葉path", "/sub葉path")] [InlineData("/base葉path/", "/base%E8%91%89path/sub%E8%91%89path", "/base葉path", "/sub葉path")]
public async Task Request_PathSplitting(string pathBase, string requestUri, string expectedPathBase, string expectedPath) public async Task Request_PathSplitting(string pathBase, string requestPath, string expectedPathBase, string expectedPath)
{ {
using (Utilities.CreateServer("http", "localhost", "8080", pathBase, env => string root;
using (Utilities.CreateHttpServerReturnRoot(pathBase, out root, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
try try
@ -104,7 +104,6 @@ namespace Microsoft.AspNet.Server.WebListener
Assert.Equal(expectedPath, requestInfo.Path); Assert.Equal(expectedPath, requestInfo.Path);
Assert.Equal(expectedPathBase, requestInfo.PathBase); Assert.Equal(expectedPathBase, requestInfo.PathBase);
Assert.Equal(string.Empty, requestInfo.QueryString); Assert.Equal(string.Empty, requestInfo.QueryString);
Assert.Equal(8080, connectionInfo.LocalPort);
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -114,7 +113,7 @@ namespace Microsoft.AspNet.Server.WebListener
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
string response = await SendRequestAsync(requestUri); string response = await SendRequestAsync(root + requestPath);
Assert.Equal(string.Empty, response); Assert.Equal(string.Empty, response);
} }
} }
@ -132,9 +131,10 @@ namespace Microsoft.AspNet.Server.WebListener
[InlineData("/2/3", "/2/3", "")] [InlineData("/2/3", "/2/3", "")]
[InlineData("/2/3/", "/2/3", "/")] [InlineData("/2/3/", "/2/3", "/")]
[InlineData("/2/3/random", "/2/3", "/random")] [InlineData("/2/3/random", "/2/3", "/random")]
public async Task Request_MultiplePrefixes(string requestUri, string expectedPathBase, string expectedPath) public async Task Request_MultiplePrefixes(string requestPath, string expectedPathBase, string expectedPath)
{ {
using (CreateServer(env => string root;
using (CreateServer(out root, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
var requestInfo = httpContext.GetFeature<IHttpRequestFeature>(); var requestInfo = httpContext.GetFeature<IHttpRequestFeature>();
@ -151,19 +151,23 @@ namespace Microsoft.AspNet.Server.WebListener
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
string response = await SendRequestAsync(Address + requestUri); string response = await SendRequestAsync(root + requestPath);
Assert.Equal(string.Empty, response); Assert.Equal(string.Empty, response);
} }
} }
private IDisposable CreateServer(AppFunc app) private IDisposable CreateServer(out string root, AppFunc app)
{ {
// TODO: We're just doing this to get a dynamic port. This can be removed later when we add support for hot-adding prefixes.
var server = Utilities.CreateHttpServerReturnRoot("/", out root, app);
server.Dispose();
var rootUri = new Uri(root);
var factory = new ServerFactory(loggerFactory: null); var factory = new ServerFactory(loggerFactory: null);
var serverInfo = (ServerInformation)factory.Initialize(configuration: null); var serverInfo = (ServerInformation)factory.Initialize(configuration: null);
foreach (string path in new[] { "/", "/11", "/2/3", "/2", "/11/2" }) foreach (string path in new[] { "/", "/11", "/2/3", "/2", "/11/2" })
{ {
serverInfo.Listener.UrlPrefixes.Add(UrlPrefix.Create("http", "localhost", "8080", path)); serverInfo.Listener.UrlPrefixes.Add(UrlPrefix.Create(rootUri.Scheme, rootUri.Host, rootUri.Port, path));
} }
return factory.Start(serverInfo, app); return factory.Start(serverInfo, app);

View File

@ -30,19 +30,18 @@ namespace Microsoft.AspNet.Server.WebListener
{ {
public class ResponseBodyTests public class ResponseBodyTests
{ {
private const string Address = "http://localhost:8080/";
[Fact] [Fact]
public async Task ResponseBody_WriteNoHeaders_DefaultsToChunked() public async Task ResponseBody_WriteNoHeaders_DefaultsToChunked()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
httpContext.Response.Body.Write(new byte[10], 0, 10); httpContext.Response.Body.Write(new byte[10], 0, 10);
return httpContext.Response.Body.WriteAsync(new byte[10], 0, 10); return httpContext.Response.Body.WriteAsync(new byte[10], 0, 10);
})) }))
{ {
HttpResponseMessage response = await SendRequestAsync(Address); HttpResponseMessage response = await SendRequestAsync(address);
Assert.Equal(200, (int)response.StatusCode); Assert.Equal(200, (int)response.StatusCode);
Assert.Equal(new Version(1, 1), response.Version); Assert.Equal(new Version(1, 1), response.Version);
IEnumerable<string> ignored; IEnumerable<string> ignored;
@ -55,7 +54,8 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task ResponseBody_WriteChunked_Chunked() public async Task ResponseBody_WriteChunked_Chunked()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
httpContext.Request.Headers["transfeR-Encoding"] = " CHunked "; httpContext.Request.Headers["transfeR-Encoding"] = " CHunked ";
@ -65,7 +65,7 @@ namespace Microsoft.AspNet.Server.WebListener
return stream.WriteAsync(new byte[10], 0, 10); return stream.WriteAsync(new byte[10], 0, 10);
})) }))
{ {
HttpResponseMessage response = await SendRequestAsync(Address); HttpResponseMessage response = await SendRequestAsync(address);
Assert.Equal(200, (int)response.StatusCode); Assert.Equal(200, (int)response.StatusCode);
Assert.Equal(new Version(1, 1), response.Version); Assert.Equal(new Version(1, 1), response.Version);
IEnumerable<string> ignored; IEnumerable<string> ignored;
@ -78,7 +78,8 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task ResponseBody_WriteContentLength_PassedThrough() public async Task ResponseBody_WriteContentLength_PassedThrough()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
httpContext.Response.Headers["Content-lenGth"] = " 30 "; httpContext.Response.Headers["Content-lenGth"] = " 30 ";
@ -88,7 +89,7 @@ namespace Microsoft.AspNet.Server.WebListener
return stream.WriteAsync(new byte[10], 0, 10); return stream.WriteAsync(new byte[10], 0, 10);
})) }))
{ {
HttpResponseMessage response = await SendRequestAsync(Address); HttpResponseMessage response = await SendRequestAsync(address);
Assert.Equal(200, (int)response.StatusCode); Assert.Equal(200, (int)response.StatusCode);
Assert.Equal(new Version(1, 1), response.Version); Assert.Equal(new Version(1, 1), response.Version);
IEnumerable<string> contentLength; IEnumerable<string> contentLength;
@ -102,14 +103,15 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task ResponseBody_Http10WriteNoHeaders_DefaultsConnectionClose() public async Task ResponseBody_Http10WriteNoHeaders_DefaultsConnectionClose()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
env["owin.ResponseProtocol"] = "HTTP/1.0"; env["owin.ResponseProtocol"] = "HTTP/1.0";
env.Get<Stream>("owin.ResponseBody").Write(new byte[10], 0, 10); env.Get<Stream>("owin.ResponseBody").Write(new byte[10], 0, 10);
return env.Get<Stream>("owin.ResponseBody").WriteAsync(new byte[10], 0, 10); return env.Get<Stream>("owin.ResponseBody").WriteAsync(new byte[10], 0, 10);
})) }))
{ {
HttpResponseMessage response = await SendRequestAsync(Address); HttpResponseMessage response = await SendRequestAsync(address);
Assert.Equal(200, (int)response.StatusCode); Assert.Equal(200, (int)response.StatusCode);
Assert.Equal(new Version(1, 1), response.Version); // Http.Sys won't transmit 1.0 Assert.Equal(new Version(1, 1), response.Version); // Http.Sys won't transmit 1.0
IEnumerable<string> ignored; IEnumerable<string> ignored;
@ -122,21 +124,23 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task ResponseBody_WriteContentLengthNoneWritten_Throws() public async Task ResponseBody_WriteContentLengthNoneWritten_Throws()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
httpContext.Response.Headers["Content-lenGth"] = " 20 "; httpContext.Response.Headers["Content-lenGth"] = " 20 ";
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
await Assert.ThrowsAsync<HttpRequestException>(() => SendRequestAsync(Address)); await Assert.ThrowsAsync<HttpRequestException>(() => SendRequestAsync(address));
} }
} }
[Fact] [Fact]
public void ResponseBody_WriteContentLengthNotEnoughWritten_Throws() public void ResponseBody_WriteContentLengthNotEnoughWritten_Throws()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
httpContext.Response.Headers["Content-lenGth"] = " 20 "; httpContext.Response.Headers["Content-lenGth"] = " 20 ";
@ -144,14 +148,15 @@ namespace Microsoft.AspNet.Server.WebListener
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
Assert.Throws<AggregateException>(() => SendRequestAsync(Address).Result); Assert.Throws<AggregateException>(() => SendRequestAsync(address).Result);
} }
} }
[Fact] [Fact]
public void ResponseBody_WriteContentLengthTooMuchWritten_Throws() public void ResponseBody_WriteContentLengthTooMuchWritten_Throws()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
httpContext.Response.Headers["Content-lenGth"] = " 10 "; httpContext.Response.Headers["Content-lenGth"] = " 10 ";
@ -160,7 +165,7 @@ namespace Microsoft.AspNet.Server.WebListener
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
Assert.Throws<AggregateException>(() => SendRequestAsync(Address).Result); Assert.Throws<AggregateException>(() => SendRequestAsync(address).Result);
} }
} }
@ -169,7 +174,8 @@ namespace Microsoft.AspNet.Server.WebListener
{ {
ManualResetEvent waitHandle = new ManualResetEvent(false); ManualResetEvent waitHandle = new ManualResetEvent(false);
bool? appThrew = null; bool? appThrew = null;
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
try try
{ {
@ -188,7 +194,7 @@ namespace Microsoft.AspNet.Server.WebListener
})) }))
{ {
// The full response is received. // The full response is received.
HttpResponseMessage response = await SendRequestAsync(Address); HttpResponseMessage response = await SendRequestAsync(address);
Assert.Equal(200, (int)response.StatusCode); Assert.Equal(200, (int)response.StatusCode);
Assert.Equal(new Version(1, 1), response.Version); Assert.Equal(new Version(1, 1), response.Version);
IEnumerable<string> contentLength; IEnumerable<string> contentLength;

View File

@ -29,17 +29,16 @@ namespace Microsoft.AspNet.Server.WebListener
{ {
public class ResponseHeaderTests public class ResponseHeaderTests
{ {
private const string Address = "http://localhost:8080/";
[Fact] [Fact]
public async Task ResponseHeaders_ServerSendsDefaultHeaders_Success() public async Task ResponseHeaders_ServerSendsDefaultHeaders_Success()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
HttpResponseMessage response = await SendRequestAsync(Address); HttpResponseMessage response = await SendRequestAsync(address);
response.EnsureSuccessStatusCode(); response.EnsureSuccessStatusCode();
Assert.Equal(2, response.Headers.Count()); Assert.Equal(2, response.Headers.Count());
Assert.False(response.Headers.TransferEncodingChunked.HasValue); Assert.False(response.Headers.TransferEncodingChunked.HasValue);
@ -53,7 +52,8 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task ResponseHeaders_ServerSendsSingleValueKnownHeaders_Success() public async Task ResponseHeaders_ServerSendsSingleValueKnownHeaders_Success()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
var responseInfo = httpContext.GetFeature<IHttpResponseFeature>(); var responseInfo = httpContext.GetFeature<IHttpResponseFeature>();
@ -63,7 +63,7 @@ namespace Microsoft.AspNet.Server.WebListener
})) }))
{ {
// HttpClient would merge the headers no matter what // HttpClient would merge the headers no matter what
WebRequest request = WebRequest.Create(Address); WebRequest request = WebRequest.Create(address);
HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync(); HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync();
Assert.Equal(4, response.Headers.Count); Assert.Equal(4, response.Headers.Count);
Assert.Null(response.Headers["Transfer-Encoding"]); Assert.Null(response.Headers["Transfer-Encoding"]);
@ -77,7 +77,8 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task ResponseHeaders_ServerSendsMultiValueKnownHeaders_Success() public async Task ResponseHeaders_ServerSendsMultiValueKnownHeaders_Success()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
var responseInfo = httpContext.GetFeature<IHttpResponseFeature>(); var responseInfo = httpContext.GetFeature<IHttpResponseFeature>();
@ -87,7 +88,7 @@ namespace Microsoft.AspNet.Server.WebListener
})) }))
{ {
// HttpClient would merge the headers no matter what // HttpClient would merge the headers no matter what
WebRequest request = WebRequest.Create(Address); WebRequest request = WebRequest.Create(address);
HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync(); HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync();
Assert.Equal(4, response.Headers.Count); Assert.Equal(4, response.Headers.Count);
Assert.Null(response.Headers["Transfer-Encoding"]); Assert.Null(response.Headers["Transfer-Encoding"]);
@ -101,7 +102,8 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task ResponseHeaders_ServerSendsCustomHeaders_Success() public async Task ResponseHeaders_ServerSendsCustomHeaders_Success()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
var responseInfo = httpContext.GetFeature<IHttpResponseFeature>(); var responseInfo = httpContext.GetFeature<IHttpResponseFeature>();
@ -111,7 +113,7 @@ namespace Microsoft.AspNet.Server.WebListener
})) }))
{ {
// HttpClient would merge the headers no matter what // HttpClient would merge the headers no matter what
WebRequest request = WebRequest.Create(Address); WebRequest request = WebRequest.Create(address);
HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync(); HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync();
Assert.Equal(4, response.Headers.Count); Assert.Equal(4, response.Headers.Count);
Assert.Null(response.Headers["Transfer-Encoding"]); Assert.Null(response.Headers["Transfer-Encoding"]);
@ -125,7 +127,8 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task ResponseHeaders_ServerSendsConnectionClose_Closed() public async Task ResponseHeaders_ServerSendsConnectionClose_Closed()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
var responseInfo = httpContext.GetFeature<IHttpResponseFeature>(); var responseInfo = httpContext.GetFeature<IHttpResponseFeature>();
@ -134,7 +137,7 @@ namespace Microsoft.AspNet.Server.WebListener
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
HttpResponseMessage response = await SendRequestAsync(Address); HttpResponseMessage response = await SendRequestAsync(address);
response.EnsureSuccessStatusCode(); response.EnsureSuccessStatusCode();
Assert.True(response.Headers.ConnectionClose.Value); Assert.True(response.Headers.ConnectionClose.Value);
Assert.Equal(new string[] { "close" }, response.Headers.GetValues("Connection")); Assert.Equal(new string[] { "close" }, response.Headers.GetValues("Connection"));
@ -144,13 +147,14 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task ResponseHeaders_SendsHttp10_Gets11Close() public async Task ResponseHeaders_SendsHttp10_Gets11Close()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
env["owin.ResponseProtocol"] = "HTTP/1.0"; env["owin.ResponseProtocol"] = "HTTP/1.0";
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
HttpResponseMessage response = await SendRequestAsync(Address); HttpResponseMessage response = await SendRequestAsync(address);
response.EnsureSuccessStatusCode(); response.EnsureSuccessStatusCode();
Assert.Equal(new Version(1, 1), response.Version); Assert.Equal(new Version(1, 1), response.Version);
Assert.True(response.Headers.ConnectionClose.Value); Assert.True(response.Headers.ConnectionClose.Value);
@ -161,13 +165,14 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task ResponseHeaders_SendsHttp10WithBody_Gets11Close() public async Task ResponseHeaders_SendsHttp10WithBody_Gets11Close()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
env["owin.ResponseProtocol"] = "HTTP/1.0"; env["owin.ResponseProtocol"] = "HTTP/1.0";
return env.Get<Stream>("owin.ResponseBody").WriteAsync(new byte[10], 0, 10); return env.Get<Stream>("owin.ResponseBody").WriteAsync(new byte[10], 0, 10);
})) }))
{ {
HttpResponseMessage response = await SendRequestAsync(Address); HttpResponseMessage response = await SendRequestAsync(address);
response.EnsureSuccessStatusCode(); response.EnsureSuccessStatusCode();
Assert.Equal(new Version(1, 1), response.Version); Assert.Equal(new Version(1, 1), response.Version);
Assert.False(response.Headers.TransferEncodingChunked.HasValue); Assert.False(response.Headers.TransferEncodingChunked.HasValue);
@ -181,14 +186,15 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task ResponseHeaders_HTTP10Request_Gets11Close() public async Task ResponseHeaders_HTTP10Request_Gets11Close()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
using (HttpClient client = new HttpClient()) using (HttpClient client = new HttpClient())
{ {
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, Address); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, address);
request.Version = new Version(1, 0); request.Version = new Version(1, 0);
HttpResponseMessage response = await client.SendAsync(request); HttpResponseMessage response = await client.SendAsync(request);
response.EnsureSuccessStatusCode(); response.EnsureSuccessStatusCode();
@ -202,7 +208,8 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task ResponseHeaders_HTTP10Request_RemovesChunkedHeader() public async Task ResponseHeaders_HTTP10Request_RemovesChunkedHeader()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
var responseInfo = httpContext.GetFeature<IHttpResponseFeature>(); var responseInfo = httpContext.GetFeature<IHttpResponseFeature>();
@ -213,7 +220,7 @@ namespace Microsoft.AspNet.Server.WebListener
{ {
using (HttpClient client = new HttpClient()) using (HttpClient client = new HttpClient())
{ {
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, Address); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, address);
request.Version = new Version(1, 0); request.Version = new Version(1, 0);
HttpResponseMessage response = await client.SendAsync(request); HttpResponseMessage response = await client.SendAsync(request);
response.EnsureSuccessStatusCode(); response.EnsureSuccessStatusCode();
@ -229,8 +236,8 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task Headers_FlushSendsHeaders_Success() public async Task Headers_FlushSendsHeaders_Success()
{ {
using (Utilities.CreateHttpServer( string address;
env => using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
var responseInfo = httpContext.GetFeature<IHttpResponseFeature>(); var responseInfo = httpContext.GetFeature<IHttpResponseFeature>();
@ -244,7 +251,7 @@ namespace Microsoft.AspNet.Server.WebListener
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
HttpResponseMessage response = await SendRequestAsync(Address); HttpResponseMessage response = await SendRequestAsync(address);
response.EnsureSuccessStatusCode(); response.EnsureSuccessStatusCode();
Assert.Equal(5, response.Headers.Count()); // Date, Server, Chunked Assert.Equal(5, response.Headers.Count()); // Date, Server, Chunked
@ -259,8 +266,8 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task Headers_FlushAsyncSendsHeaders_Success() public async Task Headers_FlushAsyncSendsHeaders_Success()
{ {
using (Utilities.CreateHttpServer( string address;
async env => using (Utilities.CreateHttpServer(out address, async env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
var responseInfo = httpContext.GetFeature<IHttpResponseFeature>(); var responseInfo = httpContext.GetFeature<IHttpResponseFeature>();
@ -273,7 +280,7 @@ namespace Microsoft.AspNet.Server.WebListener
responseHeaders.Add("Custom3", new string[] { "value3a, value3b", "value3c" }); // Ignored responseHeaders.Add("Custom3", new string[] { "value3a, value3b", "value3c" }); // Ignored
})) }))
{ {
HttpResponseMessage response = await SendRequestAsync(Address); HttpResponseMessage response = await SendRequestAsync(address);
response.EnsureSuccessStatusCode(); response.EnsureSuccessStatusCode();
Assert.Equal(5, response.Headers.Count()); // Date, Server, Chunked Assert.Equal(5, response.Headers.Count()); // Date, Server, Chunked

View File

@ -33,7 +33,6 @@ namespace Microsoft.AspNet.Server.WebListener
{ {
public class ResponseSendFileTests public class ResponseSendFileTests
{ {
private const string Address = "http://localhost:8080/";
private readonly string AbsoluteFilePath; private readonly string AbsoluteFilePath;
private readonly string RelativeFilePath; private readonly string RelativeFilePath;
private readonly long FileLength; private readonly long FileLength;
@ -48,7 +47,8 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task ResponseSendFile_SupportKeys_Present() public async Task ResponseSendFile_SupportKeys_Present()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
try try
@ -76,7 +76,7 @@ namespace Microsoft.AspNet.Server.WebListener
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
HttpResponseMessage response = await SendRequestAsync(Address); HttpResponseMessage response = await SendRequestAsync(address);
Assert.Equal(200, (int)response.StatusCode); Assert.Equal(200, (int)response.StatusCode);
IEnumerable<string> ignored; IEnumerable<string> ignored;
Assert.True(response.Content.Headers.TryGetValues("content-length", out ignored), "Content-Length"); Assert.True(response.Content.Headers.TryGetValues("content-length", out ignored), "Content-Length");
@ -91,7 +91,8 @@ namespace Microsoft.AspNet.Server.WebListener
{ {
ManualResetEvent waitHandle = new ManualResetEvent(false); ManualResetEvent waitHandle = new ManualResetEvent(false);
bool? appThrew = null; bool? appThrew = null;
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
var sendFile = httpContext.GetFeature<IHttpSendFileFeature>(); var sendFile = httpContext.GetFeature<IHttpSendFileFeature>();
@ -112,7 +113,7 @@ namespace Microsoft.AspNet.Server.WebListener
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
HttpResponseMessage response = await SendRequestAsync(Address); HttpResponseMessage response = await SendRequestAsync(address);
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode); Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
Assert.True(waitHandle.WaitOne(100)); Assert.True(waitHandle.WaitOne(100));
Assert.True(appThrew.HasValue, "appThrew.HasValue"); Assert.True(appThrew.HasValue, "appThrew.HasValue");
@ -123,14 +124,15 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task ResponseSendFile_NoHeaders_DefaultsToChunked() public async Task ResponseSendFile_NoHeaders_DefaultsToChunked()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
var sendFile = httpContext.GetFeature<IHttpSendFileFeature>(); var sendFile = httpContext.GetFeature<IHttpSendFileFeature>();
return sendFile.SendFileAsync(AbsoluteFilePath, 0, null, CancellationToken.None); return sendFile.SendFileAsync(AbsoluteFilePath, 0, null, CancellationToken.None);
})) }))
{ {
HttpResponseMessage response = await SendRequestAsync(Address); HttpResponseMessage response = await SendRequestAsync(address);
Assert.Equal(200, (int)response.StatusCode); Assert.Equal(200, (int)response.StatusCode);
IEnumerable<string> ignored; IEnumerable<string> ignored;
Assert.False(response.Content.Headers.TryGetValues("content-length", out ignored), "Content-Length"); Assert.False(response.Content.Headers.TryGetValues("content-length", out ignored), "Content-Length");
@ -142,14 +144,15 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task ResponseSendFile_RelativeFile_Success() public async Task ResponseSendFile_RelativeFile_Success()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
var sendFile = httpContext.GetFeature<IHttpSendFileFeature>(); var sendFile = httpContext.GetFeature<IHttpSendFileFeature>();
return sendFile.SendFileAsync(RelativeFilePath, 0, null, CancellationToken.None); return sendFile.SendFileAsync(RelativeFilePath, 0, null, CancellationToken.None);
})) }))
{ {
HttpResponseMessage response = await SendRequestAsync(Address); HttpResponseMessage response = await SendRequestAsync(address);
Assert.Equal(200, (int)response.StatusCode); Assert.Equal(200, (int)response.StatusCode);
IEnumerable<string> ignored; IEnumerable<string> ignored;
Assert.False(response.Content.Headers.TryGetValues("content-length", out ignored), "Content-Length"); Assert.False(response.Content.Headers.TryGetValues("content-length", out ignored), "Content-Length");
@ -161,7 +164,8 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task ResponseSendFile_Chunked_Chunked() public async Task ResponseSendFile_Chunked_Chunked()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
var sendFile = httpContext.GetFeature<IHttpSendFileFeature>(); var sendFile = httpContext.GetFeature<IHttpSendFileFeature>();
@ -169,7 +173,7 @@ namespace Microsoft.AspNet.Server.WebListener
return sendFile.SendFileAsync(AbsoluteFilePath, 0, null, CancellationToken.None); return sendFile.SendFileAsync(AbsoluteFilePath, 0, null, CancellationToken.None);
})) }))
{ {
HttpResponseMessage response = await SendRequestAsync(Address); HttpResponseMessage response = await SendRequestAsync(address);
Assert.Equal(200, (int)response.StatusCode); Assert.Equal(200, (int)response.StatusCode);
IEnumerable<string> contentLength; IEnumerable<string> contentLength;
Assert.False(response.Content.Headers.TryGetValues("content-length", out contentLength), "Content-Length"); Assert.False(response.Content.Headers.TryGetValues("content-length", out contentLength), "Content-Length");
@ -181,7 +185,8 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task ResponseSendFile_MultipleChunks_Chunked() public async Task ResponseSendFile_MultipleChunks_Chunked()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
var sendFile = httpContext.GetFeature<IHttpSendFileFeature>(); var sendFile = httpContext.GetFeature<IHttpSendFileFeature>();
@ -190,7 +195,7 @@ namespace Microsoft.AspNet.Server.WebListener
return sendFile.SendFileAsync(AbsoluteFilePath, 0, null, CancellationToken.None); return sendFile.SendFileAsync(AbsoluteFilePath, 0, null, CancellationToken.None);
})) }))
{ {
HttpResponseMessage response = await SendRequestAsync(Address); HttpResponseMessage response = await SendRequestAsync(address);
Assert.Equal(200, (int)response.StatusCode); Assert.Equal(200, (int)response.StatusCode);
IEnumerable<string> contentLength; IEnumerable<string> contentLength;
Assert.False(response.Content.Headers.TryGetValues("content-length", out contentLength), "Content-Length"); Assert.False(response.Content.Headers.TryGetValues("content-length", out contentLength), "Content-Length");
@ -202,14 +207,15 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task ResponseSendFile_ChunkedHalfOfFile_Chunked() public async Task ResponseSendFile_ChunkedHalfOfFile_Chunked()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
var sendFile = httpContext.GetFeature<IHttpSendFileFeature>(); var sendFile = httpContext.GetFeature<IHttpSendFileFeature>();
return sendFile.SendFileAsync(AbsoluteFilePath, 0, FileLength / 2, CancellationToken.None); return sendFile.SendFileAsync(AbsoluteFilePath, 0, FileLength / 2, CancellationToken.None);
})) }))
{ {
HttpResponseMessage response = await SendRequestAsync(Address); HttpResponseMessage response = await SendRequestAsync(address);
Assert.Equal(200, (int)response.StatusCode); Assert.Equal(200, (int)response.StatusCode);
IEnumerable<string> contentLength; IEnumerable<string> contentLength;
Assert.False(response.Content.Headers.TryGetValues("content-length", out contentLength), "Content-Length"); Assert.False(response.Content.Headers.TryGetValues("content-length", out contentLength), "Content-Length");
@ -221,14 +227,15 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task ResponseSendFile_ChunkedOffsetOutOfRange_Throws() public async Task ResponseSendFile_ChunkedOffsetOutOfRange_Throws()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
var sendFile = httpContext.GetFeature<IHttpSendFileFeature>(); var sendFile = httpContext.GetFeature<IHttpSendFileFeature>();
return sendFile.SendFileAsync(AbsoluteFilePath, 1234567, null, CancellationToken.None); return sendFile.SendFileAsync(AbsoluteFilePath, 1234567, null, CancellationToken.None);
})) }))
{ {
HttpResponseMessage response = await SendRequestAsync(Address); HttpResponseMessage response = await SendRequestAsync(address);
Assert.Equal(500, (int)response.StatusCode); Assert.Equal(500, (int)response.StatusCode);
} }
} }
@ -236,14 +243,15 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task ResponseSendFile_ChunkedCountOutOfRange_Throws() public async Task ResponseSendFile_ChunkedCountOutOfRange_Throws()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
var sendFile = httpContext.GetFeature<IHttpSendFileFeature>(); var sendFile = httpContext.GetFeature<IHttpSendFileFeature>();
return sendFile.SendFileAsync(AbsoluteFilePath, 0, 1234567, CancellationToken.None); return sendFile.SendFileAsync(AbsoluteFilePath, 0, 1234567, CancellationToken.None);
})) }))
{ {
HttpResponseMessage response = await SendRequestAsync(Address); HttpResponseMessage response = await SendRequestAsync(address);
Assert.Equal(500, (int)response.StatusCode); Assert.Equal(500, (int)response.StatusCode);
} }
} }
@ -251,14 +259,15 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task ResponseSendFile_ChunkedCount0_Chunked() public async Task ResponseSendFile_ChunkedCount0_Chunked()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
var sendFile = httpContext.GetFeature<IHttpSendFileFeature>(); var sendFile = httpContext.GetFeature<IHttpSendFileFeature>();
return sendFile.SendFileAsync(AbsoluteFilePath, 0, 0, CancellationToken.None); return sendFile.SendFileAsync(AbsoluteFilePath, 0, 0, CancellationToken.None);
})) }))
{ {
HttpResponseMessage response = await SendRequestAsync(Address); HttpResponseMessage response = await SendRequestAsync(address);
Assert.Equal(200, (int)response.StatusCode); Assert.Equal(200, (int)response.StatusCode);
IEnumerable<string> contentLength; IEnumerable<string> contentLength;
Assert.False(response.Content.Headers.TryGetValues("content-length", out contentLength), "Content-Length"); Assert.False(response.Content.Headers.TryGetValues("content-length", out contentLength), "Content-Length");
@ -270,7 +279,8 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task ResponseSendFile_ContentLength_PassedThrough() public async Task ResponseSendFile_ContentLength_PassedThrough()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
var sendFile = httpContext.GetFeature<IHttpSendFileFeature>(); var sendFile = httpContext.GetFeature<IHttpSendFileFeature>();
@ -278,7 +288,7 @@ namespace Microsoft.AspNet.Server.WebListener
return sendFile.SendFileAsync(AbsoluteFilePath, 0, null, CancellationToken.None); return sendFile.SendFileAsync(AbsoluteFilePath, 0, null, CancellationToken.None);
})) }))
{ {
HttpResponseMessage response = await SendRequestAsync(Address); HttpResponseMessage response = await SendRequestAsync(address);
Assert.Equal(200, (int)response.StatusCode); Assert.Equal(200, (int)response.StatusCode);
IEnumerable<string> contentLength; IEnumerable<string> contentLength;
Assert.True(response.Content.Headers.TryGetValues("content-length", out contentLength), "Content-Length"); Assert.True(response.Content.Headers.TryGetValues("content-length", out contentLength), "Content-Length");
@ -291,7 +301,8 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task ResponseSendFile_ContentLengthSpecific_PassedThrough() public async Task ResponseSendFile_ContentLengthSpecific_PassedThrough()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
var sendFile = httpContext.GetFeature<IHttpSendFileFeature>(); var sendFile = httpContext.GetFeature<IHttpSendFileFeature>();
@ -299,7 +310,7 @@ namespace Microsoft.AspNet.Server.WebListener
return sendFile.SendFileAsync(AbsoluteFilePath, 0, 10, CancellationToken.None); return sendFile.SendFileAsync(AbsoluteFilePath, 0, 10, CancellationToken.None);
})) }))
{ {
HttpResponseMessage response = await SendRequestAsync(Address); HttpResponseMessage response = await SendRequestAsync(address);
Assert.Equal(200, (int)response.StatusCode); Assert.Equal(200, (int)response.StatusCode);
IEnumerable<string> contentLength; IEnumerable<string> contentLength;
Assert.True(response.Content.Headers.TryGetValues("content-length", out contentLength), "Content-Length"); Assert.True(response.Content.Headers.TryGetValues("content-length", out contentLength), "Content-Length");
@ -312,7 +323,8 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task ResponseSendFile_ContentLength0_PassedThrough() public async Task ResponseSendFile_ContentLength0_PassedThrough()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
var sendFile = httpContext.GetFeature<IHttpSendFileFeature>(); var sendFile = httpContext.GetFeature<IHttpSendFileFeature>();
@ -320,7 +332,7 @@ namespace Microsoft.AspNet.Server.WebListener
return sendFile.SendFileAsync(AbsoluteFilePath, 0, 0, CancellationToken.None); return sendFile.SendFileAsync(AbsoluteFilePath, 0, 0, CancellationToken.None);
})) }))
{ {
HttpResponseMessage response = await SendRequestAsync(Address); HttpResponseMessage response = await SendRequestAsync(address);
Assert.Equal(200, (int)response.StatusCode); Assert.Equal(200, (int)response.StatusCode);
IEnumerable<string> contentLength; IEnumerable<string> contentLength;
Assert.True(response.Content.Headers.TryGetValues("content-length", out contentLength), "Content-Length"); Assert.True(response.Content.Headers.TryGetValues("content-length", out contentLength), "Content-Length");

View File

@ -28,19 +28,18 @@ namespace Microsoft.AspNet.Server.WebListener
{ {
public class ResponseTests public class ResponseTests
{ {
private const string Address = "http://localhost:8080/";
[Fact] [Fact]
public async Task Response_ServerSendsDefaultResponse_ServerProvidesStatusCodeAndReasonPhrase() public async Task Response_ServerSendsDefaultResponse_ServerProvidesStatusCodeAndReasonPhrase()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
Assert.Equal(200, httpContext.Response.StatusCode); Assert.Equal(200, httpContext.Response.StatusCode);
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
HttpResponseMessage response = await SendRequestAsync(Address); HttpResponseMessage response = await SendRequestAsync(address);
Assert.Equal(200, (int)response.StatusCode); Assert.Equal(200, (int)response.StatusCode);
Assert.Equal("OK", response.ReasonPhrase); Assert.Equal("OK", response.ReasonPhrase);
Assert.Equal(new Version(1, 1), response.Version); Assert.Equal(new Version(1, 1), response.Version);
@ -51,7 +50,8 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task Response_ServerSendsSpecificStatus_ServerProvidesReasonPhrase() public async Task Response_ServerSendsSpecificStatus_ServerProvidesReasonPhrase()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
httpContext.Response.StatusCode = 201; httpContext.Response.StatusCode = 201;
@ -59,7 +59,7 @@ namespace Microsoft.AspNet.Server.WebListener
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
HttpResponseMessage response = await SendRequestAsync(Address); HttpResponseMessage response = await SendRequestAsync(address);
Assert.Equal(201, (int)response.StatusCode); Assert.Equal(201, (int)response.StatusCode);
Assert.Equal("Created", response.ReasonPhrase); Assert.Equal("Created", response.ReasonPhrase);
Assert.Equal(new Version(1, 1), response.Version); Assert.Equal(new Version(1, 1), response.Version);
@ -70,7 +70,8 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task Response_ServerSendsSpecificStatusAndReasonPhrase_PassedThrough() public async Task Response_ServerSendsSpecificStatusAndReasonPhrase_PassedThrough()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
httpContext.Response.StatusCode = 201; httpContext.Response.StatusCode = 201;
@ -79,7 +80,7 @@ namespace Microsoft.AspNet.Server.WebListener
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
HttpResponseMessage response = await SendRequestAsync(Address); HttpResponseMessage response = await SendRequestAsync(address);
Assert.Equal(201, (int)response.StatusCode); Assert.Equal(201, (int)response.StatusCode);
Assert.Equal("CustomReasonPhrase", response.ReasonPhrase); Assert.Equal("CustomReasonPhrase", response.ReasonPhrase);
Assert.Equal(new Version(1, 1), response.Version); Assert.Equal(new Version(1, 1), response.Version);
@ -90,14 +91,15 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task Response_ServerSendsCustomStatus_NoReasonPhrase() public async Task Response_ServerSendsCustomStatus_NoReasonPhrase()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
httpContext.Response.StatusCode = 901; httpContext.Response.StatusCode = 901;
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
HttpResponseMessage response = await SendRequestAsync(Address); HttpResponseMessage response = await SendRequestAsync(address);
Assert.Equal(901, (int)response.StatusCode); Assert.Equal(901, (int)response.StatusCode);
Assert.Equal(string.Empty, response.ReasonPhrase); Assert.Equal(string.Empty, response.ReasonPhrase);
Assert.Equal(string.Empty, await response.Content.ReadAsStringAsync()); Assert.Equal(string.Empty, await response.Content.ReadAsStringAsync());
@ -107,14 +109,15 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task Response_100_Throws() public async Task Response_100_Throws()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
httpContext.Response.StatusCode = 100; httpContext.Response.StatusCode = 100;
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
HttpResponseMessage response = await SendRequestAsync(Address); HttpResponseMessage response = await SendRequestAsync(address);
Assert.Equal(500, (int)response.StatusCode); Assert.Equal(500, (int)response.StatusCode);
} }
} }
@ -122,14 +125,15 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task Response_0_Throws() public async Task Response_0_Throws()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
httpContext.Response.StatusCode = 0; httpContext.Response.StatusCode = 0;
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
HttpResponseMessage response = await SendRequestAsync(Address); HttpResponseMessage response = await SendRequestAsync(address);
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode); Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
} }
} }

View File

@ -34,17 +34,16 @@ namespace Microsoft.AspNet.Server.WebListener
{ {
public class ServerTests public class ServerTests
{ {
private const string Address = "http://localhost:8080/";
[Fact] [Fact]
public async Task Server_200OK_Success() public async Task Server_200OK_Success()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
string response = await SendRequestAsync(Address); string response = await SendRequestAsync(address);
Assert.Equal(string.Empty, response); Assert.Equal(string.Empty, response);
} }
} }
@ -52,14 +51,15 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task Server_SendHelloWorld_Success() public async Task Server_SendHelloWorld_Success()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
httpContext.Response.ContentLength = 11; httpContext.Response.ContentLength = 11;
return httpContext.Response.WriteAsync("Hello World"); return httpContext.Response.WriteAsync("Hello World");
})) }))
{ {
string response = await SendRequestAsync(Address); string response = await SendRequestAsync(address);
Assert.Equal("Hello World", response); Assert.Equal("Hello World", response);
} }
} }
@ -67,7 +67,8 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task Server_EchoHelloWorld_Success() public async Task Server_EchoHelloWorld_Success()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
string input = new StreamReader(httpContext.Request.Body).ReadToEnd(); string input = new StreamReader(httpContext.Request.Body).ReadToEnd();
@ -76,7 +77,7 @@ namespace Microsoft.AspNet.Server.WebListener
return httpContext.Response.WriteAsync("Hello World"); return httpContext.Response.WriteAsync("Hello World");
})) }))
{ {
string response = await SendRequestAsync(Address, "Hello World"); string response = await SendRequestAsync(address, "Hello World");
Assert.Equal("Hello World", response); Assert.Equal("Hello World", response);
} }
} }
@ -86,7 +87,8 @@ namespace Microsoft.AspNet.Server.WebListener
{ {
Task<string> responseTask; Task<string> responseTask;
ManualResetEvent received = new ManualResetEvent(false); ManualResetEvent received = new ManualResetEvent(false);
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
received.Set(); received.Set();
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
@ -94,7 +96,7 @@ namespace Microsoft.AspNet.Server.WebListener
return httpContext.Response.WriteAsync("Hello World"); return httpContext.Response.WriteAsync("Hello World");
})) }))
{ {
responseTask = SendRequestAsync(Address); responseTask = SendRequestAsync(address);
Assert.True(received.WaitOne(10000)); Assert.True(received.WaitOne(10000));
} }
string response = await responseTask; string response = await responseTask;
@ -104,16 +106,17 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public void Server_AppException_ClientReset() public void Server_AppException_ClientReset()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
throw new InvalidOperationException(); throw new InvalidOperationException();
})) }))
{ {
Task<string> requestTask = SendRequestAsync(Address); Task<string> requestTask = SendRequestAsync(address);
Assert.Throws<AggregateException>(() => requestTask.Result); Assert.Throws<AggregateException>(() => requestTask.Result);
// Do it again to make sure the server didn't crash // Do it again to make sure the server didn't crash
requestTask = SendRequestAsync(Address); requestTask = SendRequestAsync(address);
Assert.Throws<AggregateException>(() => requestTask.Result); Assert.Throws<AggregateException>(() => requestTask.Result);
} }
} }
@ -125,7 +128,8 @@ namespace Microsoft.AspNet.Server.WebListener
int requestCount = 0; int requestCount = 0;
TaskCompletionSource<object> tcs = new TaskCompletionSource<object>(); TaskCompletionSource<object> tcs = new TaskCompletionSource<object>();
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
if (Interlocked.Increment(ref requestCount) == requestLimit) if (Interlocked.Increment(ref requestCount) == requestLimit)
{ {
@ -142,7 +146,7 @@ namespace Microsoft.AspNet.Server.WebListener
List<Task> requestTasks = new List<Task>(); List<Task> requestTasks = new List<Task>();
for (int i = 0; i < requestLimit; i++) for (int i = 0; i < requestLimit; i++)
{ {
Task<string> requestTask = SendRequestAsync(Address); Task<string> requestTask = SendRequestAsync(address);
requestTasks.Add(requestTask); requestTasks.Add(requestTask);
} }
@ -162,7 +166,8 @@ namespace Microsoft.AspNet.Server.WebListener
int requestCount = 0; int requestCount = 0;
TaskCompletionSource<object> tcs = new TaskCompletionSource<object>(); TaskCompletionSource<object> tcs = new TaskCompletionSource<object>();
using (Utilities.CreateHttpServer(async env => string address;
using (Utilities.CreateHttpServer(out address, async env =>
{ {
if (Interlocked.Increment(ref requestCount) == requestLimit) if (Interlocked.Increment(ref requestCount) == requestLimit)
{ {
@ -177,7 +182,7 @@ namespace Microsoft.AspNet.Server.WebListener
List<Task> requestTasks = new List<Task>(); List<Task> requestTasks = new List<Task>();
for (int i = 0; i < requestLimit; i++) for (int i = 0; i < requestLimit; i++)
{ {
Task<string> requestTask = SendRequestAsync(Address); Task<string> requestTask = SendRequestAsync(address);
requestTasks.Add(requestTask); requestTasks.Add(requestTask);
} }
Assert.True(Task.WaitAll(requestTasks.ToArray(), TimeSpan.FromSeconds(2)), "Timed out"); Assert.True(Task.WaitAll(requestTasks.ToArray(), TimeSpan.FromSeconds(2)), "Timed out");
@ -192,7 +197,8 @@ namespace Microsoft.AspNet.Server.WebListener
ManualResetEvent aborted = new ManualResetEvent(false); ManualResetEvent aborted = new ManualResetEvent(false);
ManualResetEvent canceled = new ManualResetEvent(false); ManualResetEvent canceled = new ManualResetEvent(false);
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
CancellationToken ct = httpContext.RequestAborted; CancellationToken ct = httpContext.RequestAborted;
@ -208,7 +214,7 @@ namespace Microsoft.AspNet.Server.WebListener
{ {
// Note: System.Net.Sockets does not RST the connection by default, it just FINs. // Note: System.Net.Sockets does not RST the connection by default, it just FINs.
// Http.Sys's disconnect notice requires a RST. // Http.Sys's disconnect notice requires a RST.
using (Socket socket = await SendHungRequestAsync("GET", Address)) using (Socket socket = await SendHungRequestAsync("GET", address))
{ {
Assert.True(received.WaitOne(interval), "Receive Timeout"); Assert.True(received.WaitOne(interval), "Receive Timeout");
socket.Close(0); // Force a RST socket.Close(0); // Force a RST
@ -226,7 +232,8 @@ namespace Microsoft.AspNet.Server.WebListener
ManualResetEvent aborted = new ManualResetEvent(false); ManualResetEvent aborted = new ManualResetEvent(false);
ManualResetEvent canceled = new ManualResetEvent(false); ManualResetEvent canceled = new ManualResetEvent(false);
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
CancellationToken ct = httpContext.RequestAborted; CancellationToken ct = httpContext.RequestAborted;
@ -240,7 +247,7 @@ namespace Microsoft.AspNet.Server.WebListener
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
using (Socket socket = await SendHungRequestAsync("GET", Address)) using (Socket socket = await SendHungRequestAsync("GET", address))
{ {
Assert.True(received.WaitOne(interval), "Receive Timeout"); Assert.True(received.WaitOne(interval), "Receive Timeout");
Assert.Throws<SocketException>(() => socket.Receive(new byte[10])); Assert.Throws<SocketException>(() => socket.Receive(new byte[10]));
@ -251,15 +258,19 @@ namespace Microsoft.AspNet.Server.WebListener
[Fact] [Fact]
public async Task Server_SetQueueLimit_Success() public async Task Server_SetQueueLimit_Success()
{ {
var factory = new ServerFactory(loggerFactory: null); // TODO: This is just to get a dynamic port
string address;
using (Utilities.CreateHttpServer(out address, env => Task.FromResult(0))) { }
var factory = new ServerFactory(loggerFactory: null);
var serverInfo = (ServerInformation)factory.Initialize(configuration: null); var serverInfo = (ServerInformation)factory.Initialize(configuration: null);
serverInfo.Listener.UrlPrefixes.Add(UrlPrefix.Create("http://localhost:8080")); serverInfo.Listener.UrlPrefixes.Add(UrlPrefix.Create(address));
serverInfo.Listener.SetRequestQueueLimit(1001); serverInfo.Listener.SetRequestQueueLimit(1001);
using (factory.Start(serverInfo, env => Task.FromResult(0))) using (factory.Start(serverInfo, env => Task.FromResult(0)))
{ {
string response = await SendRequestAsync(Address); string response = await SendRequestAsync(address);
Assert.Equal(string.Empty, response); Assert.Equal(string.Empty, response);
} }
} }

View File

@ -25,32 +25,68 @@ namespace Microsoft.AspNet.Server.WebListener
internal static class Utilities internal static class Utilities
{ {
internal static IDisposable CreateHttpServer(AppFunc app) private const int BasePort = 5001;
private const int MaxPort = 8000;
private static int NextPort = BasePort;
private static object PortLock = new object();
internal static IDisposable CreateHttpServer(out string baseAddress, AppFunc app)
{ {
return CreateServer("http", "localhost", "8080", string.Empty, app); string root;
return CreateDynamicHttpServer(string.Empty, AuthenticationTypes.AllowAnonymous, out root, out baseAddress, app);
}
internal static IDisposable CreateHttpServerReturnRoot(string path, out string root, AppFunc app)
{
string baseAddress;
return CreateDynamicHttpServer(path, AuthenticationTypes.AllowAnonymous, out root, out baseAddress, app);
}
internal static IDisposable CreateHttpAuthServer(AuthenticationTypes authType, out string baseAddress, AppFunc app)
{
string root;
return CreateDynamicHttpServer(string.Empty, authType, out root, out baseAddress, app);
}
internal static IDisposable CreateDynamicHttpServer(string basePath, AuthenticationTypes authType, out string root, out string baseAddress, AppFunc app)
{
var factory = new ServerFactory(loggerFactory: null);
lock (PortLock)
{
while (NextPort < MaxPort)
{
var port = NextPort++;
var prefix = UrlPrefix.Create("http", "localhost", port, basePath);
root = prefix.Scheme + "://" + prefix.Host + ":" + prefix.Port;
baseAddress = prefix.ToString();
var serverInfo = (ServerInformation)factory.Initialize(configuration: null);
serverInfo.Listener.UrlPrefixes.Add(prefix);
serverInfo.Listener.AuthenticationManager.AuthenticationTypes = authType;
try
{
return factory.Start(serverInfo, app);
}
catch (WebListenerException)
{
}
}
NextPort = BasePort;
}
throw new Exception("Failed to locate a free port.");
} }
internal static IDisposable CreateHttpsServer(AppFunc app) internal static IDisposable CreateHttpsServer(AppFunc app)
{ {
return CreateServer("https", "localhost", "9090", string.Empty, app); return CreateServer("https", "localhost", 9090, string.Empty, app);
} }
internal static IDisposable CreateAuthServer(AuthenticationTypes authType, AppFunc app) internal static IDisposable CreateServer(string scheme, string host, int port, string path, AppFunc app)
{
return CreateServer("http", "localhost", "8080", string.Empty, authType, app);
}
internal static IDisposable CreateServer(string scheme, string host, string port, string path, AppFunc app)
{
return CreateServer(scheme, host, port, path, AuthenticationTypes.AllowAnonymous, app);
}
internal static IDisposable CreateServer(string scheme, string host, string port, string path, AuthenticationTypes authType, AppFunc app)
{ {
var factory = new ServerFactory(loggerFactory: null); var factory = new ServerFactory(loggerFactory: null);
var serverInfo = (ServerInformation)factory.Initialize(configuration: null); var serverInfo = (ServerInformation)factory.Initialize(configuration: null);
serverInfo.Listener.UrlPrefixes.Add(UrlPrefix.Create(scheme, host, port, path)); serverInfo.Listener.UrlPrefixes.Add(UrlPrefix.Create(scheme, host, port, path));
serverInfo.Listener.AuthenticationManager.AuthenticationTypes = authType;
return factory.Start(serverInfo, app); return factory.Start(serverInfo, app);
} }

View File

@ -30,13 +30,11 @@ namespace Microsoft.AspNet.Server.WebListener
{ {
public class WebSocketTests public class WebSocketTests
{ {
private const string Address = "http://localhost:8080/";
private const string WsAddress = "ws://localhost:8080/";
[Fact] [Fact]
public async Task WebSocketTests_SupportKeys_Present() public async Task WebSocketTests_SupportKeys_Present()
{ {
using (Utilities.CreateHttpServer(env => string address;
using (Utilities.CreateHttpServer(out address, env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
try try
@ -51,7 +49,7 @@ namespace Microsoft.AspNet.Server.WebListener
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {
HttpResponseMessage response = await SendRequestAsync(Address); HttpResponseMessage response = await SendRequestAsync(address);
Assert.Equal(200, (int)response.StatusCode); Assert.Equal(200, (int)response.StatusCode);
Assert.False(response.Headers.TransferEncodingChunked.HasValue, "Chunked"); Assert.False(response.Headers.TransferEncodingChunked.HasValue, "Chunked");
Assert.Equal(0, response.Content.Headers.ContentLength); Assert.Equal(0, response.Content.Headers.ContentLength);
@ -63,7 +61,8 @@ namespace Microsoft.AspNet.Server.WebListener
public async Task WebSocketTests_AfterHeadersSent_Throws() public async Task WebSocketTests_AfterHeadersSent_Throws()
{ {
bool? upgradeThrew = null; bool? upgradeThrew = null;
using (Utilities.CreateHttpServer(async env => string address;
using (Utilities.CreateHttpServer(out address, async env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
await httpContext.Response.WriteAsync("Hello World"); await httpContext.Response.WriteAsync("Hello World");
@ -80,7 +79,7 @@ namespace Microsoft.AspNet.Server.WebListener
} }
})) }))
{ {
HttpResponseMessage response = await SendRequestAsync(Address); HttpResponseMessage response = await SendRequestAsync(address);
Assert.Equal(200, (int)response.StatusCode); Assert.Equal(200, (int)response.StatusCode);
Assert.True(response.Headers.TransferEncodingChunked.Value, "Chunked"); Assert.True(response.Headers.TransferEncodingChunked.Value, "Chunked");
Assert.True(upgradeThrew.Value); Assert.True(upgradeThrew.Value);
@ -92,7 +91,8 @@ namespace Microsoft.AspNet.Server.WebListener
{ {
ManualResetEvent waitHandle = new ManualResetEvent(false); ManualResetEvent waitHandle = new ManualResetEvent(false);
bool? upgraded = null; bool? upgraded = null;
using (Utilities.CreateHttpServer(async env => string address;
using (Utilities.CreateHttpServer(out address, async env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
var webSocketFeature = httpContext.GetFeature<IHttpWebSocketFeature>(); var webSocketFeature = httpContext.GetFeature<IHttpWebSocketFeature>();
@ -103,7 +103,7 @@ namespace Microsoft.AspNet.Server.WebListener
waitHandle.Set(); waitHandle.Set();
})) }))
{ {
using (WebSocket clientWebSocket = await SendWebSocketRequestAsync(WsAddress)) using (WebSocket clientWebSocket = await SendWebSocketRequestAsync(ConvertToWebSocketAddress(address)))
{ {
Assert.True(waitHandle.WaitOne(TimeSpan.FromSeconds(1)), "Timed out"); Assert.True(waitHandle.WaitOne(TimeSpan.FromSeconds(1)), "Timed out");
Assert.True(upgraded.HasValue, "Upgraded not set"); Assert.True(upgraded.HasValue, "Upgraded not set");
@ -116,7 +116,8 @@ namespace Microsoft.AspNet.Server.WebListener
public async Task WebSocketAccept_SendAndReceive_Success() public async Task WebSocketAccept_SendAndReceive_Success()
{ {
byte[] clientBuffer = new byte[] { 0x00, 0x01, 0xFF, 0x00, 0x00 }; byte[] clientBuffer = new byte[] { 0x00, 0x01, 0xFF, 0x00, 0x00 };
using (Utilities.CreateHttpServer(async env => string address;
using (Utilities.CreateHttpServer(out address, async env =>
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
var webSocketFeature = httpContext.GetFeature<IHttpWebSocketFeature>(); var webSocketFeature = httpContext.GetFeature<IHttpWebSocketFeature>();
@ -132,7 +133,7 @@ namespace Microsoft.AspNet.Server.WebListener
})) }))
{ {
using (WebSocket clientWebSocket = await SendWebSocketRequestAsync(WsAddress)) using (WebSocket clientWebSocket = await SendWebSocketRequestAsync(ConvertToWebSocketAddress(address)))
{ {
await clientWebSocket.SendAsync(new ArraySegment<byte>(clientBuffer, 0, 3), WebSocketMessageType.Binary, true, CancellationToken.None); await clientWebSocket.SendAsync(new ArraySegment<byte>(clientBuffer, 0, 3), WebSocketMessageType.Binary, true, CancellationToken.None);
@ -143,6 +144,13 @@ namespace Microsoft.AspNet.Server.WebListener
} }
} }
private string ConvertToWebSocketAddress(string address)
{
var builder = new UriBuilder(address);
builder.Scheme = "ws";
return builder.ToString();
}
private async Task<HttpResponseMessage> SendRequestAsync(string uri) private async Task<HttpResponseMessage> SendRequestAsync(string uri)
{ {
using (HttpClient client = new HttpClient()) using (HttpClient client = new HttpClient())

View File

@ -10,8 +10,6 @@ namespace Microsoft.Net.Server
{ {
public class AuthenticationTests public class AuthenticationTests
{ {
private const string Address = "http://localhost:8080/";
[Theory] [Theory]
[InlineData(AuthenticationTypes.AllowAnonymous)] [InlineData(AuthenticationTypes.AllowAnonymous)]
[InlineData(AuthenticationTypes.Kerberos)] [InlineData(AuthenticationTypes.Kerberos)]
@ -22,9 +20,10 @@ namespace Microsoft.Net.Server
[InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /*AuthenticationTypes.Digest |*/ AuthenticationTypes.Basic)] [InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /*AuthenticationTypes.Digest |*/ AuthenticationTypes.Basic)]
public async Task AuthTypes_AllowAnonymous_NoChallenge(AuthenticationTypes authType) public async Task AuthTypes_AllowAnonymous_NoChallenge(AuthenticationTypes authType)
{ {
using (var server = Utilities.CreateAuthServer(authType | AuthenticationTypes.AllowAnonymous)) string address;
using (var server = Utilities.CreateHttpAuthServer(authType | AuthenticationTypes.AllowAnonymous, out address))
{ {
Task<HttpResponseMessage> responseTask = SendRequestAsync(Address); Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
Assert.NotNull(context.User); Assert.NotNull(context.User);
@ -53,9 +52,10 @@ namespace Microsoft.Net.Server
[InlineData(AuthenticationTypes.Basic)] [InlineData(AuthenticationTypes.Basic)]
public async Task AuthType_RequireAuth_ChallengesAdded(AuthenticationTypes authType) public async Task AuthType_RequireAuth_ChallengesAdded(AuthenticationTypes authType)
{ {
using (var server = Utilities.CreateAuthServer(authType)) string address;
using (var server = Utilities.CreateHttpAuthServer(authType, out address))
{ {
Task<HttpResponseMessage> responseTask = SendRequestAsync(Address); Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
var contextTask = server.GetContextAsync(); // Fails when the server shuts down, the challenge happens internally. var contextTask = server.GetContextAsync(); // Fails when the server shuts down, the challenge happens internally.
@ -73,9 +73,10 @@ namespace Microsoft.Net.Server
[InlineData(AuthenticationTypes.Basic)] [InlineData(AuthenticationTypes.Basic)]
public async Task AuthType_AllowAnonymousButSpecify401_ChallengesAdded(AuthenticationTypes authType) public async Task AuthType_AllowAnonymousButSpecify401_ChallengesAdded(AuthenticationTypes authType)
{ {
using (var server = Utilities.CreateAuthServer(authType | AuthenticationTypes.AllowAnonymous)) string address;
using (var server = Utilities.CreateHttpAuthServer(authType | AuthenticationTypes.AllowAnonymous, out address))
{ {
Task<HttpResponseMessage> responseTask = SendRequestAsync(Address); Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
Assert.NotNull(context.User); Assert.NotNull(context.User);
@ -93,15 +94,16 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task MultipleAuthTypes_AllowAnonymousButSpecify401_ChallengesAdded() public async Task MultipleAuthTypes_AllowAnonymousButSpecify401_ChallengesAdded()
{ {
string address;
AuthenticationTypes authType = AuthenticationTypes authType =
AuthenticationTypes.Kerberos AuthenticationTypes.Kerberos
| AuthenticationTypes.Negotiate | AuthenticationTypes.Negotiate
| AuthenticationTypes.NTLM | AuthenticationTypes.NTLM
/* | AuthenticationTypes.Digest TODO: Not implemented */ /* | AuthenticationTypes.Digest TODO: Not implemented */
| AuthenticationTypes.Basic; | AuthenticationTypes.Basic;
using (var server = Utilities.CreateAuthServer(authType | AuthenticationTypes.AllowAnonymous)) using (var server = Utilities.CreateHttpAuthServer(authType | AuthenticationTypes.AllowAnonymous, out address))
{ {
Task<HttpResponseMessage> responseTask = SendRequestAsync(Address); Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
Assert.NotNull(context.User); Assert.NotNull(context.User);
@ -125,9 +127,10 @@ namespace Microsoft.Net.Server
[InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /*AuthenticationType.Digest |*/ AuthenticationTypes.Basic)] [InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /*AuthenticationType.Digest |*/ AuthenticationTypes.Basic)]
public async Task AuthTypes_AllowAnonymousButSpecify401_Success(AuthenticationTypes authType) public async Task AuthTypes_AllowAnonymousButSpecify401_Success(AuthenticationTypes authType)
{ {
using (var server = Utilities.CreateAuthServer(authType | AuthenticationTypes.AllowAnonymous)) string address;
using (var server = Utilities.CreateHttpAuthServer(authType | AuthenticationTypes.AllowAnonymous, out address))
{ {
Task<HttpResponseMessage> responseTask = SendRequestAsync(Address, useDefaultCredentials: true); Task<HttpResponseMessage> responseTask = SendRequestAsync(address, useDefaultCredentials: true);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
Assert.NotNull(context.User); Assert.NotNull(context.User);
@ -156,9 +159,10 @@ namespace Microsoft.Net.Server
[InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /*AuthenticationType.Digest |*/ AuthenticationTypes.Basic)] [InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /*AuthenticationType.Digest |*/ AuthenticationTypes.Basic)]
public async Task AuthTypes_RequireAuth_Success(AuthenticationTypes authType) public async Task AuthTypes_RequireAuth_Success(AuthenticationTypes authType)
{ {
using (var server = Utilities.CreateAuthServer(authType)) string address;
using (var server = Utilities.CreateHttpAuthServer(authType, out address))
{ {
Task<HttpResponseMessage> responseTask = SendRequestAsync(Address, useDefaultCredentials: true); Task<HttpResponseMessage> responseTask = SendRequestAsync(address, useDefaultCredentials: true);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
Assert.NotNull(context.User); Assert.NotNull(context.User);

View File

@ -11,6 +11,7 @@ namespace Microsoft.Net.Server
{ {
public class HttpsTests public class HttpsTests
{ {
// Note these tests can't use dynamic ports or run concurrently because the ssl cert must be pre-registered with a specific port.
private const string Address = "https://localhost:9090/"; private const string Address = "https://localhost:9090/";
[Fact(Skip = "TODO: Add trait filtering support so these SSL tests don't get run on teamcity or the command line."), Trait("scheme", "https")] [Fact(Skip = "TODO: Add trait filtering support so these SSL tests don't get run on teamcity or the command line."), Trait("scheme", "https")]

View File

@ -22,7 +22,6 @@
<Compile Include="HttpsTests.cs" /> <Compile Include="HttpsTests.cs" />
<Compile Include="WebSocketTests.cs" /> <Compile Include="WebSocketTests.cs" />
<Compile Include="OpaqueUpgradeTests.cs" /> <Compile Include="OpaqueUpgradeTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RequestBodyTests.cs" /> <Compile Include="RequestBodyTests.cs" />
<Compile Include="RequestHeaderTests.cs" /> <Compile Include="RequestHeaderTests.cs" />
<Compile Include="RequestTests.cs" /> <Compile Include="RequestTests.cs" />

View File

@ -12,21 +12,20 @@ namespace Microsoft.Net.Server
{ {
public class OpaqueUpgradeTests public class OpaqueUpgradeTests
{ {
private const string Address = "http://localhost:8080/";
[Fact] [Fact]
public async Task OpaqueUpgrade_AfterHeadersSent_Throws() public async Task OpaqueUpgrade_AfterHeadersSent_Throws()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<HttpResponseMessage> clientTask = SendRequestAsync(Address); Task<HttpResponseMessage> clientTask = SendRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
byte[] body = Encoding.UTF8.GetBytes("Hello World"); byte[] body = Encoding.UTF8.GetBytes("Hello World");
context.Response.Body.Write(body, 0, body.Length); context.Response.Body.Write(body, 0, body.Length);
context.Response.Headers["Upgrade"] = "WebSocket"; // Win8.1 blocks anything but WebSocket context.Response.Headers["Upgrade"] = "WebSocket"; // Win8.1 blocks anything but WebSocket
Assert.ThrowsAsync<InvalidOperationException>(async () => await context.UpgradeAsync()); await Assert.ThrowsAsync<InvalidOperationException>(async () => await context.UpgradeAsync());
context.Dispose(); context.Dispose();
HttpResponseMessage response = await clientTask; HttpResponseMessage response = await clientTask;
Assert.Equal(200, (int)response.StatusCode); Assert.Equal(200, (int)response.StatusCode);
@ -38,9 +37,10 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task OpaqueUpgrade_GetUpgrade_Success() public async Task OpaqueUpgrade_GetUpgrade_Success()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<Stream> clientTask = SendOpaqueRequestAsync("GET", Address); Task<Stream> clientTask = SendOpaqueRequestAsync("GET", address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
Assert.True(context.IsUpgradableRequest); Assert.True(context.IsUpgradableRequest);
@ -80,9 +80,10 @@ namespace Microsoft.Net.Server
[InlineData("PUT", "Content-Length: 0")] [InlineData("PUT", "Content-Length: 0")]
public async Task OpaqueUpgrade_VariousMethodsUpgradeSendAndReceive_Success(string method, string extraHeader) public async Task OpaqueUpgrade_VariousMethodsUpgradeSendAndReceive_Success(string method, string extraHeader)
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<Stream> clientTask = SendOpaqueRequestAsync(method, Address, extraHeader); Task<Stream> clientTask = SendOpaqueRequestAsync(method, address, extraHeader);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
Assert.True(context.IsUpgradableRequest); Assert.True(context.IsUpgradableRequest);
@ -119,9 +120,10 @@ namespace Microsoft.Net.Server
[InlineData("CUSTOMVERB", "Transfer-Encoding: chunked")] [InlineData("CUSTOMVERB", "Transfer-Encoding: chunked")]
public async Task OpaqueUpgrade_InvalidMethodUpgrade_Disconnected(string method, string extraHeader) public async Task OpaqueUpgrade_InvalidMethodUpgrade_Disconnected(string method, string extraHeader)
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
var clientTask = SendOpaqueRequestAsync(method, Address, extraHeader); var clientTask = SendOpaqueRequestAsync(method, address, extraHeader);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
Assert.False(context.IsUpgradableRequest); Assert.False(context.IsUpgradableRequest);
context.Dispose(); context.Dispose();

View File

@ -1,8 +0,0 @@
// -----------------------------------------------------------------------
// <copyright file="AssemblyInfo.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// -----------------------------------------------------------------------
// These tests can't run in parallel because they all use the same port.
[assembly: Xunit.CollectionBehaviorAttribute(Xunit.CollectionBehavior.CollectionPerAssembly, DisableTestParallelization = true)]

View File

@ -14,14 +14,13 @@ namespace Microsoft.Net.Server
{ {
public class RequestBodyTests public class RequestBodyTests
{ {
private const string Address = "http://localhost:8080/";
[Fact] [Fact]
public async Task RequestBody_ReadSync_Success() public async Task RequestBody_ReadSync_Success()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<string> responseTask = SendRequestAsync(Address, "Hello World"); Task<string> responseTask = SendRequestAsync(address, "Hello World");
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
byte[] input = new byte[100]; byte[] input = new byte[100];
@ -37,9 +36,10 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task RequestBody_ReadAync_Success() public async Task RequestBody_ReadAync_Success()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<string> responseTask = SendRequestAsync(Address, "Hello World"); Task<string> responseTask = SendRequestAsync(address, "Hello World");
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
byte[] input = new byte[100]; byte[] input = new byte[100];
@ -55,9 +55,10 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task RequestBody_ReadBeginEnd_Success() public async Task RequestBody_ReadBeginEnd_Success()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<string> responseTask = SendRequestAsync(Address, "Hello World"); Task<string> responseTask = SendRequestAsync(address, "Hello World");
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
byte[] input = new byte[100]; byte[] input = new byte[100];
@ -74,9 +75,10 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task RequestBody_InvalidBuffer_ArgumentException() public async Task RequestBody_InvalidBuffer_ArgumentException()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<string> responseTask = SendRequestAsync(Address, "Hello World"); Task<string> responseTask = SendRequestAsync(address, "Hello World");
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
byte[] input = new byte[100]; byte[] input = new byte[100];
@ -98,9 +100,10 @@ namespace Microsoft.Net.Server
public async Task RequestBody_ReadSyncPartialBody_Success() public async Task RequestBody_ReadSyncPartialBody_Success()
{ {
StaggardContent content = new StaggardContent(); StaggardContent content = new StaggardContent();
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<string> responseTask = SendRequestAsync(Address, content); Task<string> responseTask = SendRequestAsync(address, content);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
byte[] input = new byte[10]; byte[] input = new byte[10];
@ -120,9 +123,10 @@ namespace Microsoft.Net.Server
public async Task RequestBody_ReadAsyncPartialBody_Success() public async Task RequestBody_ReadAsyncPartialBody_Success()
{ {
StaggardContent content = new StaggardContent(); StaggardContent content = new StaggardContent();
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<string> responseTask = SendRequestAsync(Address, content); Task<string> responseTask = SendRequestAsync(address, content);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
byte[] input = new byte[10]; byte[] input = new byte[10];
@ -141,9 +145,10 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task RequestBody_PostWithImidateBody_Success() public async Task RequestBody_PostWithImidateBody_Success()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<string> responseTask = SendSocketRequestAsync(Address); Task<string> responseTask = SendSocketRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
byte[] input = new byte[11]; byte[] input = new byte[11];

View File

@ -1,5 +1,6 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using System;
using System.Linq; using System.Linq;
using System.Net.Http; using System.Net.Http;
using System.Net.Sockets; using System.Net.Sockets;
@ -11,21 +12,20 @@ namespace Microsoft.Net.Server
{ {
public class RequestHeaderTests public class RequestHeaderTests
{ {
private const string Address = "http://localhost:8080/";
[Fact] [Fact]
public async Task RequestHeaders_ClientSendsDefaultHeaders_Success() public async Task RequestHeaders_ClientSendsDefaultHeaders_Success()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<string> responseTask = SendRequestAsync(Address); Task<string> responseTask = SendRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
var requestHeaders = context.Request.Headers; var requestHeaders = context.Request.Headers;
// NOTE: The System.Net client only sends the Connection: keep-alive header on the first connection per service-point. // NOTE: The System.Net client only sends the Connection: keep-alive header on the first connection per service-point.
// Assert.Equal(2, requestHeaders.Count); // Assert.Equal(2, requestHeaders.Count);
// Assert.Equal("Keep-Alive", requestHeaders.Get("Connection")); // Assert.Equal("Keep-Alive", requestHeaders.Get("Connection"));
Assert.Equal("localhost:8080", requestHeaders["Host"]); Assert.Equal(new Uri(address).Authority, requestHeaders["Host"]);
string[] values; string[] values;
Assert.False(requestHeaders.TryGetValue("Accept", out values)); Assert.False(requestHeaders.TryGetValue("Accept", out values));
Assert.False(requestHeaders.ContainsKey("Accept")); Assert.False(requestHeaders.ContainsKey("Accept"));
@ -40,16 +40,17 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task RequestHeaders_ClientSendsCustomHeaders_Success() public async Task RequestHeaders_ClientSendsCustomHeaders_Success()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
string[] customValues = new string[] { "custom1, and custom2", "custom3" }; string[] customValues = new string[] { "custom1, and custom2", "custom3" };
Task responseTask = SendRequestAsync("localhost", 8080, "Custom-Header", customValues); Task responseTask = SendRequestAsync(address, "Custom-Header", customValues);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
var requestHeaders = context.Request.Headers; var requestHeaders = context.Request.Headers;
Assert.Equal(4, requestHeaders.Count); Assert.Equal(4, requestHeaders.Count);
Assert.Equal("localhost:8080", requestHeaders["Host"]); Assert.Equal(new Uri(address).Authority, requestHeaders["Host"]);
Assert.Equal(new[] { "localhost:8080" }, requestHeaders.GetValues("Host")); Assert.Equal(new[] { new Uri(address).Authority }, requestHeaders.GetValues("Host"));
Assert.Equal("close", requestHeaders["Connection"]); Assert.Equal("close", requestHeaders["Connection"]);
Assert.Equal(new[] { "close" }, requestHeaders.GetValues("Connection")); Assert.Equal(new[] { "close" }, requestHeaders.GetValues("Connection"));
// Apparently Http.Sys squashes request headers together. // Apparently Http.Sys squashes request headers together.
@ -71,15 +72,14 @@ namespace Microsoft.Net.Server
} }
} }
private async Task SendRequestAsync(string host, int port, string customHeader, string[] customValues) private async Task SendRequestAsync(string address, string customHeader, string[] customValues)
{ {
var uri = new Uri(address);
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
builder.AppendLine("GET / HTTP/1.1"); builder.AppendLine("GET / HTTP/1.1");
builder.AppendLine("Connection: close"); builder.AppendLine("Connection: close");
builder.Append("HOST: "); builder.Append("HOST: ");
builder.Append(host); builder.AppendLine(uri.Authority);
builder.Append(':');
builder.AppendLine(port.ToString());
foreach (string value in customValues) foreach (string value in customValues)
{ {
builder.Append(customHeader); builder.Append(customHeader);
@ -92,7 +92,7 @@ namespace Microsoft.Net.Server
byte[] request = Encoding.ASCII.GetBytes(builder.ToString()); byte[] request = Encoding.ASCII.GetBytes(builder.ToString());
Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp); Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
socket.Connect(host, port); socket.Connect(uri.Host, uri.Port);
socket.Send(request); socket.Send(request);

View File

@ -11,14 +11,13 @@ namespace Microsoft.Net.Server
{ {
public class RequestTests public class RequestTests
{ {
private const string Address = "http://localhost:8080";
[Fact] [Fact]
public async Task Request_SimpleGet_Success() public async Task Request_SimpleGet_Success()
{ {
using (var server = Utilities.CreateServer("http", "localhost", "8080", "/basepath")) string root;
using (var server = Utilities.CreateHttpServerReturnRoot("/basepath", out root))
{ {
Task<string> responseTask = SendRequestAsync(Address + "/basepath/SomePath?SomeQuery"); Task<string> responseTask = SendRequestAsync(root + "/basepath/SomePath?SomeQuery");
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
@ -51,17 +50,18 @@ namespace Microsoft.Net.Server
} }
[Theory] [Theory]
[InlineData("/", "http://localhost:8080/", "", "/")] [InlineData("/", "/", "", "/")]
[InlineData("/basepath/", "http://localhost:8080/basepath", "/basepath", "")] [InlineData("/basepath/", "/basepath", "/basepath", "")]
[InlineData("/basepath/", "http://localhost:8080/basepath/", "/basepath", "/")] [InlineData("/basepath/", "/basepath/", "/basepath", "/")]
[InlineData("/basepath/", "http://localhost:8080/basepath/subpath", "/basepath", "/subpath")] [InlineData("/basepath/", "/basepath/subpath", "/basepath", "/subpath")]
[InlineData("/base path/", "http://localhost:8080/base%20path/sub path", "/base path", "/sub path")] [InlineData("/base path/", "/base%20path/sub path", "/base path", "/sub path")]
[InlineData("/base葉path/", "http://localhost:8080/base%E8%91%89path/sub%E8%91%89path", "/base葉path", "/sub葉path")] [InlineData("/base葉path/", "/base%E8%91%89path/sub%E8%91%89path", "/base葉path", "/sub葉path")]
public async Task Request_PathSplitting(string pathBase, string requestUri, string expectedPathBase, string expectedPath) public async Task Request_PathSplitting(string pathBase, string requestPath, string expectedPathBase, string expectedPath)
{ {
using (var server = Utilities.CreateServer("http", "localhost", "8080", pathBase)) string root;
using (var server = Utilities.CreateHttpServerReturnRoot(pathBase, out root))
{ {
Task<string> responseTask = SendRequestAsync(requestUri); Task<string> responseTask = SendRequestAsync(root + requestPath);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
@ -73,7 +73,6 @@ namespace Microsoft.Net.Server
Assert.Equal(expectedPath, request.Path); Assert.Equal(expectedPath, request.Path);
Assert.Equal(expectedPathBase, request.PathBase); Assert.Equal(expectedPathBase, request.PathBase);
Assert.Equal(string.Empty, request.QueryString); Assert.Equal(string.Empty, request.QueryString);
Assert.Equal(8080, request.LocalPort);
context.Dispose(); context.Dispose();
string response = await responseTask; string response = await responseTask;
@ -96,15 +95,21 @@ namespace Microsoft.Net.Server
[InlineData("/2/3/random", "/2/3", "/random")] [InlineData("/2/3/random", "/2/3", "/random")]
public async Task Request_MultiplePrefixes(string requestUri, string expectedPathBase, string expectedPath) public async Task Request_MultiplePrefixes(string requestUri, string expectedPathBase, string expectedPath)
{ {
using (var server = new WebListener()) // TODO: We're just doing this to get a dynamic port. This can be removed later when we add support for hot-adding prefixes.
string root;
var server = Utilities.CreateHttpServerReturnRoot("/", out root);
server.Dispose();
server = new WebListener();
using (server)
{ {
var uriBuilder = new UriBuilder(root);
foreach (string path in new[] { "/", "/11", "/2/3", "/2", "/11/2" }) foreach (string path in new[] { "/", "/11", "/2/3", "/2", "/11/2" })
{ {
server.UrlPrefixes.Add(UrlPrefix.Create("http", "localhost", "8080", path)); server.UrlPrefixes.Add(UrlPrefix.Create(uriBuilder.Scheme, uriBuilder.Host, uriBuilder.Port, path));
} }
server.Start(); server.Start();
Task<string> responseTask = SendRequestAsync(Address + requestUri); Task<string> responseTask = SendRequestAsync(root + requestUri);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
var request = context.Request; var request = context.Request;

View File

@ -13,14 +13,13 @@ namespace Microsoft.Net.Server
{ {
public class ResponseBodyTests public class ResponseBodyTests
{ {
private const string Address = "http://localhost:8080/";
[Fact] [Fact]
public async Task ResponseBody_WriteNoHeaders_DefaultsToChunked() public async Task ResponseBody_WriteNoHeaders_DefaultsToChunked()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<HttpResponseMessage> responseTask = SendRequestAsync(Address); Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
context.Response.Body.Write(new byte[10], 0, 10); context.Response.Body.Write(new byte[10], 0, 10);
@ -40,9 +39,10 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task ResponseBody_WriteChunked_Chunked() public async Task ResponseBody_WriteChunked_Chunked()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<HttpResponseMessage> responseTask = SendRequestAsync(Address); Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
context.Request.Headers["transfeR-Encoding"] = " CHunked "; context.Request.Headers["transfeR-Encoding"] = " CHunked ";
@ -65,9 +65,10 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task ResponseBody_WriteContentLength_PassedThrough() public async Task ResponseBody_WriteContentLength_PassedThrough()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<HttpResponseMessage> responseTask = SendRequestAsync(Address); Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
context.Response.Headers["Content-lenGth"] = " 30 "; context.Response.Headers["Content-lenGth"] = " 30 ";
@ -127,9 +128,10 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task ResponseBody_WriteContentLengthNotEnoughWritten_Throws() public async Task ResponseBody_WriteContentLengthNotEnoughWritten_Throws()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<HttpResponseMessage> responseTask = SendRequestAsync(Address); Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
context.Response.Headers["Content-lenGth"] = " 20 "; context.Response.Headers["Content-lenGth"] = " 20 ";
@ -143,9 +145,10 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task ResponseBody_WriteContentLengthTooMuchWritten_Throws() public async Task ResponseBody_WriteContentLengthTooMuchWritten_Throws()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<HttpResponseMessage> responseTask = SendRequestAsync(Address); Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
context.Response.Headers["Content-lenGth"] = " 10 "; context.Response.Headers["Content-lenGth"] = " 10 ";
@ -160,9 +163,10 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task ResponseBody_WriteContentLengthExtraWritten_Throws() public async Task ResponseBody_WriteContentLengthExtraWritten_Throws()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<HttpResponseMessage> responseTask = SendRequestAsync(Address); Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
context.Response.Headers["Content-lenGth"] = " 10 "; context.Response.Headers["Content-lenGth"] = " 10 ";

View File

@ -11,14 +11,13 @@ namespace Microsoft.Net.Server
{ {
public class ResponseHeaderTests public class ResponseHeaderTests
{ {
private const string Address = "http://localhost:8080/";
[Fact] [Fact]
public async Task ResponseHeaders_ServerSendsDefaultHeaders_Success() public async Task ResponseHeaders_ServerSendsDefaultHeaders_Success()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<HttpResponseMessage> responseTask = SendRequestAsync(Address); Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
context.Dispose(); context.Dispose();
@ -37,9 +36,10 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task ResponseHeaders_ServerSendsSingleValueKnownHeaders_Success() public async Task ResponseHeaders_ServerSendsSingleValueKnownHeaders_Success()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
WebRequest request = WebRequest.Create(Address); WebRequest request = WebRequest.Create(address);
Task<WebResponse> responseTask = request.GetResponseAsync(); Task<WebResponse> responseTask = request.GetResponseAsync();
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
@ -61,9 +61,10 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task ResponseHeaders_ServerSendsMultiValueKnownHeaders_Success() public async Task ResponseHeaders_ServerSendsMultiValueKnownHeaders_Success()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
WebRequest request = WebRequest.Create(Address); WebRequest request = WebRequest.Create(address);
Task<WebResponse> responseTask = request.GetResponseAsync(); Task<WebResponse> responseTask = request.GetResponseAsync();
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
@ -85,9 +86,10 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task ResponseHeaders_ServerSendsCustomHeaders_Success() public async Task ResponseHeaders_ServerSendsCustomHeaders_Success()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
WebRequest request = WebRequest.Create(Address); WebRequest request = WebRequest.Create(address);
Task<WebResponse> responseTask = request.GetResponseAsync(); Task<WebResponse> responseTask = request.GetResponseAsync();
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
@ -109,9 +111,10 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task ResponseHeaders_ServerSendsConnectionClose_Closed() public async Task ResponseHeaders_ServerSendsConnectionClose_Closed()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<HttpResponseMessage> responseTask = SendRequestAsync(Address); Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
var responseHeaders = context.Response.Headers; var responseHeaders = context.Response.Headers;
@ -165,11 +168,12 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task ResponseHeaders_HTTP10Request_Gets11Close() public async Task ResponseHeaders_HTTP10Request_Gets11Close()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
using (HttpClient client = new HttpClient()) using (HttpClient client = new HttpClient())
{ {
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, Address); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, address);
request.Version = new Version(1, 0); request.Version = new Version(1, 0);
Task<HttpResponseMessage> responseTask = client.SendAsync(request); Task<HttpResponseMessage> responseTask = client.SendAsync(request);
@ -188,11 +192,12 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task ResponseHeaders_HTTP10Request_RemovesChunkedHeader() public async Task ResponseHeaders_HTTP10Request_RemovesChunkedHeader()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
using (HttpClient client = new HttpClient()) using (HttpClient client = new HttpClient())
{ {
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, Address); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, address);
request.Version = new Version(1, 0); request.Version = new Version(1, 0);
Task<HttpResponseMessage> responseTask = client.SendAsync(request); Task<HttpResponseMessage> responseTask = client.SendAsync(request);
@ -216,9 +221,10 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task Headers_FlushSendsHeaders_Success() public async Task Headers_FlushSendsHeaders_Success()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<HttpResponseMessage> responseTask = SendRequestAsync(Address); Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
var responseHeaders = context.Response.Headers; var responseHeaders = context.Response.Headers;
@ -247,9 +253,10 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task Headers_FlushAsyncSendsHeaders_Success() public async Task Headers_FlushAsyncSendsHeaders_Success()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<HttpResponseMessage> responseTask = SendRequestAsync(Address); Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
var responseHeaders = context.Response.Headers; var responseHeaders = context.Response.Headers;

View File

@ -13,7 +13,6 @@ namespace Microsoft.Net.Server
{ {
public class ResponseSendFileTests public class ResponseSendFileTests
{ {
private const string Address = "http://localhost:8080/";
private readonly string AbsoluteFilePath; private readonly string AbsoluteFilePath;
private readonly string RelativeFilePath; private readonly string RelativeFilePath;
private readonly long FileLength; private readonly long FileLength;
@ -28,9 +27,10 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task ResponseSendFile_MissingFile_Throws() public async Task ResponseSendFile_MissingFile_Throws()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<HttpResponseMessage> responseTask = SendRequestAsync(Address); Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
await Assert.ThrowsAsync<FileNotFoundException>(() => await Assert.ThrowsAsync<FileNotFoundException>(() =>
@ -44,9 +44,10 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task ResponseSendFile_NoHeaders_DefaultsToChunked() public async Task ResponseSendFile_NoHeaders_DefaultsToChunked()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<HttpResponseMessage> responseTask = SendRequestAsync(Address); Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
await context.Response.SendFileAsync(AbsoluteFilePath, 0, null, CancellationToken.None); await context.Response.SendFileAsync(AbsoluteFilePath, 0, null, CancellationToken.None);
@ -64,9 +65,10 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task ResponseSendFile_RelativeFile_Success() public async Task ResponseSendFile_RelativeFile_Success()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<HttpResponseMessage> responseTask = SendRequestAsync(Address); Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
await context.Response.SendFileAsync(RelativeFilePath, 0, null, CancellationToken.None); await context.Response.SendFileAsync(RelativeFilePath, 0, null, CancellationToken.None);
@ -84,9 +86,10 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task ResponseSendFile_Chunked_Chunked() public async Task ResponseSendFile_Chunked_Chunked()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<HttpResponseMessage> responseTask = SendRequestAsync(Address); Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
context.Response.Headers["Transfer-EncodinG"] = "CHUNKED"; context.Response.Headers["Transfer-EncodinG"] = "CHUNKED";
@ -105,9 +108,10 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task ResponseSendFile_MultipleChunks_Chunked() public async Task ResponseSendFile_MultipleChunks_Chunked()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<HttpResponseMessage> responseTask = SendRequestAsync(Address); Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
context.Response.Headers["Transfer-EncodinG"] = "CHUNKED"; context.Response.Headers["Transfer-EncodinG"] = "CHUNKED";
@ -127,9 +131,10 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task ResponseSendFile_ChunkedHalfOfFile_Chunked() public async Task ResponseSendFile_ChunkedHalfOfFile_Chunked()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<HttpResponseMessage> responseTask = SendRequestAsync(Address); Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
await context.Response.SendFileAsync(AbsoluteFilePath, 0, FileLength / 2, CancellationToken.None); await context.Response.SendFileAsync(AbsoluteFilePath, 0, FileLength / 2, CancellationToken.None);
@ -147,9 +152,10 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task ResponseSendFile_ChunkedOffsetOutOfRange_Throws() public async Task ResponseSendFile_ChunkedOffsetOutOfRange_Throws()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<HttpResponseMessage> responseTask = SendRequestAsync(Address); Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
await Assert.ThrowsAsync<ArgumentOutOfRangeException>( await Assert.ThrowsAsync<ArgumentOutOfRangeException>(
@ -163,9 +169,10 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task ResponseSendFile_ChunkedCountOutOfRange_Throws() public async Task ResponseSendFile_ChunkedCountOutOfRange_Throws()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<HttpResponseMessage> responseTask = SendRequestAsync(Address); Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
await Assert.ThrowsAsync<ArgumentOutOfRangeException>( await Assert.ThrowsAsync<ArgumentOutOfRangeException>(
@ -179,9 +186,10 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task ResponseSendFile_ChunkedCount0_Chunked() public async Task ResponseSendFile_ChunkedCount0_Chunked()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<HttpResponseMessage> responseTask = SendRequestAsync(Address); Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
await context.Response.SendFileAsync(AbsoluteFilePath, 0, 0, CancellationToken.None); await context.Response.SendFileAsync(AbsoluteFilePath, 0, 0, CancellationToken.None);
@ -199,9 +207,10 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task ResponseSendFile_ContentLength_PassedThrough() public async Task ResponseSendFile_ContentLength_PassedThrough()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<HttpResponseMessage> responseTask = SendRequestAsync(Address); Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
context.Response.Headers["Content-lenGth"] = FileLength.ToString(); context.Response.Headers["Content-lenGth"] = FileLength.ToString();
@ -220,9 +229,10 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task ResponseSendFile_ContentLengthSpecific_PassedThrough() public async Task ResponseSendFile_ContentLengthSpecific_PassedThrough()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<HttpResponseMessage> responseTask = SendRequestAsync(Address); Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
context.Response.Headers["Content-lenGth"] = "10"; context.Response.Headers["Content-lenGth"] = "10";
@ -242,9 +252,10 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task ResponseSendFile_ContentLength0_PassedThrough() public async Task ResponseSendFile_ContentLength0_PassedThrough()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<HttpResponseMessage> responseTask = SendRequestAsync(Address); Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
context.Response.Headers["Content-lenGth"] = "0"; context.Response.Headers["Content-lenGth"] = "0";

View File

@ -10,14 +10,13 @@ namespace Microsoft.Net.Server
{ {
public class ResponseTests public class ResponseTests
{ {
private const string Address = "http://localhost:8080/";
[Fact] [Fact]
public async Task Response_ServerSendsDefaultResponse_ServerProvidesStatusCodeAndReasonPhrase() public async Task Response_ServerSendsDefaultResponse_ServerProvidesStatusCodeAndReasonPhrase()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<HttpResponseMessage> responseTask = SendRequestAsync(Address); Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
Assert.Equal(200, context.Response.StatusCode); Assert.Equal(200, context.Response.StatusCode);
@ -34,9 +33,10 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task Response_ServerSendsSpecificStatus_ServerProvidesReasonPhrase() public async Task Response_ServerSendsSpecificStatus_ServerProvidesReasonPhrase()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<HttpResponseMessage> responseTask = SendRequestAsync(Address); Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
context.Response.StatusCode = 201; context.Response.StatusCode = 201;
@ -54,9 +54,10 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task Response_ServerSendsSpecificStatusAndReasonPhrase_PassedThrough() public async Task Response_ServerSendsSpecificStatusAndReasonPhrase_PassedThrough()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<HttpResponseMessage> responseTask = SendRequestAsync(Address); Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
context.Response.StatusCode = 201; context.Response.StatusCode = 201;
@ -75,9 +76,10 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task Response_ServerSendsCustomStatus_NoReasonPhrase() public async Task Response_ServerSendsCustomStatus_NoReasonPhrase()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<HttpResponseMessage> responseTask = SendRequestAsync(Address); Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
context.Response.StatusCode = 901; context.Response.StatusCode = 901;
@ -93,9 +95,10 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task Response_100_Throws() public async Task Response_100_Throws()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<HttpResponseMessage> responseTask = SendRequestAsync(Address); Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
Assert.Throws<ArgumentOutOfRangeException>(() => { context.Response.StatusCode = 100; }); Assert.Throws<ArgumentOutOfRangeException>(() => { context.Response.StatusCode = 100; });
@ -108,9 +111,10 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task Response_0_Throws() public async Task Response_0_Throws()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<HttpResponseMessage> responseTask = SendRequestAsync(Address); Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
Assert.Throws<ArgumentOutOfRangeException>(() => { context.Response.StatusCode = 0; }); Assert.Throws<ArgumentOutOfRangeException>(() => { context.Response.StatusCode = 0; });

View File

@ -1,7 +1,6 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Net; using System.Net;
using System.Net.Http; using System.Net.Http;
@ -15,14 +14,13 @@ namespace Microsoft.Net.Server
{ {
public class ServerTests public class ServerTests
{ {
private const string Address = "http://localhost:8080/";
[Fact] [Fact]
public async Task Server_200OK_Success() public async Task Server_200OK_Success()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<string> responseTask = SendRequestAsync(Address); Task<string> responseTask = SendRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
context.Dispose(); context.Dispose();
@ -35,9 +33,10 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task Server_SendHelloWorld_Success() public async Task Server_SendHelloWorld_Success()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<string> responseTask = SendRequestAsync(Address); Task<string> responseTask = SendRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
context.Response.ContentLength = 11; context.Response.ContentLength = 11;
@ -54,9 +53,10 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task Server_EchoHelloWorld_Success() public async Task Server_EchoHelloWorld_Success()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<string> responseTask = SendRequestAsync(Address, "Hello World"); Task<string> responseTask = SendRequestAsync(address, "Hello World");
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
string input = new StreamReader(context.Request.Body).ReadToEnd(); string input = new StreamReader(context.Request.Body).ReadToEnd();
@ -78,11 +78,12 @@ namespace Microsoft.Net.Server
TimeSpan interval = TimeSpan.FromSeconds(1); TimeSpan interval = TimeSpan.FromSeconds(1);
ManualResetEvent canceled = new ManualResetEvent(false); ManualResetEvent canceled = new ManualResetEvent(false);
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
// Note: System.Net.Sockets does not RST the connection by default, it just FINs. // Note: System.Net.Sockets does not RST the connection by default, it just FINs.
// Http.Sys's disconnect notice requires a RST. // Http.Sys's disconnect notice requires a RST.
Task<Socket> responseTask = SendHungRequestAsync("GET", Address); Task<Socket> responseTask = SendHungRequestAsync("GET", address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
CancellationToken ct = context.DisconnectToken; CancellationToken ct = context.DisconnectToken;
@ -107,11 +108,12 @@ namespace Microsoft.Net.Server
TimeSpan interval = TimeSpan.FromSeconds(1); TimeSpan interval = TimeSpan.FromSeconds(1);
ManualResetEvent canceled = new ManualResetEvent(false); ManualResetEvent canceled = new ManualResetEvent(false);
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
// Note: System.Net.Sockets does not RST the connection by default, it just FINs. // Note: System.Net.Sockets does not RST the connection by default, it just FINs.
// Http.Sys's disconnect notice requires a RST. // Http.Sys's disconnect notice requires a RST.
Task<Socket> responseTask = SendHungRequestAsync("GET", Address); Task<Socket> responseTask = SendHungRequestAsync("GET", address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
CancellationToken ct = context.DisconnectToken; CancellationToken ct = context.DisconnectToken;
@ -132,10 +134,11 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task Server_SetQueueLimit_Success() public async Task Server_SetQueueLimit_Success()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
server.SetRequestQueueLimit(1001); server.SetRequestQueueLimit(1001);
Task<string> responseTask = SendRequestAsync(Address); Task<string> responseTask = SendRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
context.Dispose(); context.Dispose();

View File

@ -6,31 +6,67 @@ namespace Microsoft.Net.Server
{ {
internal static class Utilities internal static class Utilities
{ {
internal static WebListener CreateHttpServer() private const int BasePort = 5001;
private const int MaxPort = 8000;
private static int NextPort = BasePort;
private static object PortLock = new object();
internal static WebListener CreateHttpAuthServer(AuthenticationTypes authType, out string baseAddress)
{ {
return CreateServer("http", "localhost", "8080", string.Empty); var listener = CreateHttpServer(out baseAddress);
listener.AuthenticationManager.AuthenticationTypes = authType;
return listener;
} }
internal static WebListener CreateHttpServer(out string baseAddress)
{
string root;
return CreateDynamicHttpServer(string.Empty, out root, out baseAddress);
}
internal static WebListener CreateHttpServerReturnRoot(string path, out string root)
{
string baseAddress;
return CreateDynamicHttpServer(path, out root, out baseAddress);
}
internal static WebListener CreateDynamicHttpServer(string basePath, out string root, out string baseAddress)
{
lock (PortLock)
{
while (NextPort < MaxPort)
{
var port = NextPort++;
var prefix = UrlPrefix.Create("http", "localhost", port, basePath);
root = prefix.Scheme + "://" + prefix.Host + ":" + prefix.Port;
baseAddress = prefix.ToString();
var listener = new WebListener();
listener.UrlPrefixes.Add(prefix);
try
{
listener.Start();
return listener;
}
catch (WebListenerException)
{
listener.Dispose();
}
}
NextPort = BasePort;
}
throw new Exception("Failed to locate a free port.");
}
internal static WebListener CreateHttpsServer() internal static WebListener CreateHttpsServer()
{ {
return CreateServer("https", "localhost", "9090", string.Empty); return CreateServer("https", "localhost", 9090, string.Empty);
} }
internal static WebListener CreateAuthServer(AuthenticationTypes authType) internal static WebListener CreateServer(string scheme, string host, int port, string path)
{
return CreateServer("http", "localhost", "8080", string.Empty, authType);
}
internal static WebListener CreateServer(string scheme, string host, string port, string path)
{
return CreateServer(scheme, host, port, path, AuthenticationTypes.AllowAnonymous);
}
internal static WebListener CreateServer(string scheme, string host, string port, string path, AuthenticationTypes authType)
{ {
WebListener listener = new WebListener(); WebListener listener = new WebListener();
listener.UrlPrefixes.Add(UrlPrefix.Create(scheme, host, port, path)); listener.UrlPrefixes.Add(UrlPrefix.Create(scheme, host, port, path));
listener.AuthenticationManager.AuthenticationTypes = authType;
listener.Start(); listener.Start();
return listener; return listener;
} }

View File

@ -12,21 +12,19 @@ namespace Microsoft.Net.Server
{ {
public class WebSocketTests public class WebSocketTests
{ {
private const string Address = "http://localhost:8080/";
private const string WsAddress = "ws://localhost:8080/";
[Fact] [Fact]
public async Task WebSocketAccept_AfterHeadersSent_Throws() public async Task WebSocketAccept_AfterHeadersSent_Throws()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<HttpResponseMessage> clientTask = SendRequestAsync(Address); Task<HttpResponseMessage> clientTask = SendRequestAsync(address);
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
byte[] body = Encoding.UTF8.GetBytes("Hello World"); byte[] body = Encoding.UTF8.GetBytes("Hello World");
context.Response.Body.Write(body, 0, body.Length); context.Response.Body.Write(body, 0, body.Length);
Assert.ThrowsAsync<InvalidOperationException>(async () => await context.AcceptWebSocketAsync()); await Assert.ThrowsAsync<InvalidOperationException>(async () => await context.AcceptWebSocketAsync());
context.Dispose(); context.Dispose();
HttpResponseMessage response = await clientTask; HttpResponseMessage response = await clientTask;
Assert.Equal(200, (int)response.StatusCode); Assert.Equal(200, (int)response.StatusCode);
@ -38,9 +36,10 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task WebSocketAccept_Success() public async Task WebSocketAccept_Success()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<WebSocket> clientTask = SendWebSocketRequestAsync(WsAddress); Task<WebSocket> clientTask = SendWebSocketRequestAsync(ConvertToWebSocketAddress(address));
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
Assert.True(context.IsUpgradableRequest); Assert.True(context.IsUpgradableRequest);
@ -54,9 +53,10 @@ namespace Microsoft.Net.Server
[Fact] [Fact]
public async Task WebSocketAccept_SendAndReceive_Success() public async Task WebSocketAccept_SendAndReceive_Success()
{ {
using (var server = Utilities.CreateHttpServer()) string address;
using (var server = Utilities.CreateHttpServer(out address))
{ {
Task<WebSocket> clientTask = SendWebSocketRequestAsync(WsAddress); Task<WebSocket> clientTask = SendWebSocketRequestAsync(ConvertToWebSocketAddress(address));
var context = await server.GetContextAsync(); var context = await server.GetContextAsync();
Assert.True(context.IsWebSocketRequest); Assert.True(context.IsWebSocketRequest);
@ -81,6 +81,13 @@ namespace Microsoft.Net.Server
} }
} }
private string ConvertToWebSocketAddress(string address)
{
var builder = new UriBuilder(address);
builder.Scheme = "ws";
return builder.ToString();
}
private async Task<HttpResponseMessage> SendRequestAsync(string uri) private async Task<HttpResponseMessage> SendRequestAsync(string uri)
{ {
using (HttpClient client = new HttpClient()) using (HttpClient client = new HttpClient())