Merge remote-tracking branch 'HttpSysServer/rybrande/release22ToSrc' into rybrande/Mondo2.2
This commit is contained in:
commit
33a5544c90
|
|
@ -14,7 +14,6 @@
|
|||
<RepositoryRoot>$(MSBuildThisFileDirectory)</RepositoryRoot>
|
||||
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)build\Key.snk</AssemblyOriginatorKeyFile>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<PublicSign Condition="'$(OS)' != 'Windows_NT'">true</PublicSign>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
<Project>
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp2.0' ">$(MicrosoftNETCoreApp20PackageVersion)</RuntimeFrameworkVersion>
|
||||
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp2.1' ">$(MicrosoftNETCoreApp21PackageVersion)</RuntimeFrameworkVersion>
|
||||
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp2.2' ">$(MicrosoftNETCoreApp22PackageVersion)</RuntimeFrameworkVersion>
|
||||
<NETStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netstandard2.0' ">$(NETStandardLibrary20PackageVersion)</NETStandardImplicitPackageVersion>
|
||||
<!-- aspnet/BuildTools#662 Don't police what version of NetCoreApp we use -->
|
||||
<NETCoreAppMaximumVersion>99.9</NETCoreAppMaximumVersion>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -43,6 +43,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{85914BA9
|
|||
ProjectSection(SolutionItems) = preProject
|
||||
build\dependencies.props = build\dependencies.props
|
||||
build\Key.snk = build\Key.snk
|
||||
build\repo.props = build\repo.props
|
||||
build\sources.props = build\sources.props
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "shared", "shared", "{AB6964C9-A7AF-4FAC-BEA1-C8A538EC989E}"
|
||||
|
|
|
|||
|
|
@ -2,30 +2,25 @@
|
|||
<PropertyGroup>
|
||||
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- These package versions may be overridden or updated by automation. -->
|
||||
<PropertyGroup Label="Package Versions: Auto">
|
||||
<InternalAspNetCoreSdkPackageVersion>2.1.3-rtm-15802</InternalAspNetCoreSdkPackageVersion>
|
||||
<MicrosoftNETCoreApp20PackageVersion>2.0.0</MicrosoftNETCoreApp20PackageVersion>
|
||||
<MicrosoftNETCoreApp21PackageVersion>2.1.2</MicrosoftNETCoreApp21PackageVersion>
|
||||
<PropertyGroup Label="Package Versions">
|
||||
<InternalAspNetCoreSdkPackageVersion>2.2.0-preview2-20181011.2</InternalAspNetCoreSdkPackageVersion>
|
||||
<MicrosoftAspNetCoreAuthenticationCorePackageVersion>2.2.0-preview3-35457</MicrosoftAspNetCoreAuthenticationCorePackageVersion>
|
||||
<MicrosoftAspNetCoreHostingPackageVersion>2.2.0-preview3-35457</MicrosoftAspNetCoreHostingPackageVersion>
|
||||
<MicrosoftAspNetCoreTestingPackageVersion>2.2.0-preview3-35457</MicrosoftAspNetCoreTestingPackageVersion>
|
||||
<MicrosoftExtensionsLoggingConsolePackageVersion>2.2.0-preview3-35457</MicrosoftExtensionsLoggingConsolePackageVersion>
|
||||
<MicrosoftNETCoreApp20PackageVersion>2.0.9</MicrosoftNETCoreApp20PackageVersion>
|
||||
<MicrosoftNETCoreApp21PackageVersion>2.1.3</MicrosoftNETCoreApp21PackageVersion>
|
||||
<MicrosoftNETCoreApp22PackageVersion>2.2.0-preview3-27008-03</MicrosoftNETCoreApp22PackageVersion>
|
||||
<MicrosoftNETFrameworkReferenceAssemblies>1.0.0-alpha-004</MicrosoftNETFrameworkReferenceAssemblies>
|
||||
<MicrosoftNetHttpHeadersPackageVersion>2.2.0-preview3-35457</MicrosoftNetHttpHeadersPackageVersion>
|
||||
<MicrosoftNETTestSdkPackageVersion>15.6.1</MicrosoftNETTestSdkPackageVersion>
|
||||
<MicrosoftWin32RegistryPackageVersion>4.5.0</MicrosoftWin32RegistryPackageVersion>
|
||||
<NETStandardLibrary20PackageVersion>2.0.3</NETStandardLibrary20PackageVersion>
|
||||
<SystemNetHttpWinHttpHandlerPackageVersion>4.5.0</SystemNetHttpWinHttpHandlerPackageVersion>
|
||||
<SystemSecurityPrincipalWindowsPackageVersion>4.5.0</SystemSecurityPrincipalWindowsPackageVersion>
|
||||
<XunitPackageVersion>2.3.1</XunitPackageVersion>
|
||||
<XunitRunnerVisualStudioPackageVersion>2.4.0-beta.1.build3945</XunitRunnerVisualStudioPackageVersion>
|
||||
<XunitRunnerVisualStudioPackageVersion>2.4.0</XunitRunnerVisualStudioPackageVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- This may import a generated file which may override the variables above. -->
|
||||
<Import Project="$(DotNetPackageVersionPropsPath)" Condition=" '$(DotNetPackageVersionPropsPath)' != '' " />
|
||||
|
||||
<!-- These are package versions that should not be overridden or updated by automation. -->
|
||||
<PropertyGroup Label="Package Versions: Pinned">
|
||||
<MicrosoftAspNetCoreAuthenticationCorePackageVersion>2.1.1</MicrosoftAspNetCoreAuthenticationCorePackageVersion>
|
||||
<MicrosoftAspNetCoreHostingPackageVersion>2.1.1</MicrosoftAspNetCoreHostingPackageVersion>
|
||||
<MicrosoftAspNetCoreTestingPackageVersion>2.1.0</MicrosoftAspNetCoreTestingPackageVersion>
|
||||
<MicrosoftExtensionsLoggingConsolePackageVersion>2.1.1</MicrosoftExtensionsLoggingConsolePackageVersion>
|
||||
<MicrosoftNetHttpHeadersPackageVersion>2.1.1</MicrosoftNetHttpHeadersPackageVersion>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
<PropertyGroup Label="Package Versions: Pinned" />
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -4,12 +4,13 @@
|
|||
<PropertyGroup>
|
||||
<!-- These properties are use by the automation that updates dependencies.props -->
|
||||
<LineupPackageId>Internal.AspNetCore.Universe.Lineup</LineupPackageId>
|
||||
<LineupPackageVersion>2.1.0-rc1-*</LineupPackageVersion>
|
||||
<LineupPackageVersion>2.2.0-*</LineupPackageVersion>
|
||||
<LineupPackageRestoreSource>https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json</LineupPackageRestoreSource>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<DotNetCoreRuntime Include="$(MicrosoftNETCoreApp20PackageVersion)" />
|
||||
<DotNetCoreRuntime Include="$(MicrosoftNETCoreApp21PackageVersion)" />
|
||||
<DotNetCoreRuntime Include="$(MicrosoftNETCoreApp22PackageVersion)" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
https://dotnet.myget.org/F/dotnet-core/api/v3/index.json;
|
||||
https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json;
|
||||
https://dotnet.myget.org/F/aspnetcore-tools/api/v3/index.json;
|
||||
https://dotnet.myget.org/F/roslyn-tools/api/v3/index.json;
|
||||
</RestoreSources>
|
||||
<RestoreSources Condition="'$(DotNetBuildOffline)' != 'true'">
|
||||
$(RestoreSources);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netcoreapp2.1;net461</TargetFrameworks>
|
||||
<TargetFrameworks>netcoreapp2.2;net461</TargetFrameworks>
|
||||
<OutputType>Exe</OutputType>
|
||||
<ServerGarbageCollection>true</ServerGarbageCollection>
|
||||
</PropertyGroup>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netcoreapp2.1;net461</TargetFrameworks>
|
||||
<TargetFrameworks>netcoreapp2.2;net461</TargetFrameworks>
|
||||
<OutputType>Exe</OutputType>
|
||||
<ServerGarbageCollection>true</ServerGarbageCollection>
|
||||
</PropertyGroup>
|
||||
|
|
|
|||
|
|
@ -17,5 +17,6 @@ namespace Microsoft.AspNetCore.HttpSys.Internal
|
|||
|
||||
internal static Version V1_0 = new Version(1, 0);
|
||||
internal static Version V1_1 = new Version(1, 1);
|
||||
internal static Version V2 = new Version(2, 0);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -434,10 +434,19 @@ namespace Microsoft.AspNetCore.HttpSys.Internal
|
|||
internal HTTP_REQUEST_AUTH_INFO* pInfo;
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum HTTP_REQUEST_FLAGS
|
||||
{
|
||||
None = 0,
|
||||
MoreEntityBodyExists = 1,
|
||||
IPRouted = 2,
|
||||
Http2 = 4,
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct HTTP_REQUEST
|
||||
{
|
||||
internal uint Flags;
|
||||
internal HTTP_REQUEST_FLAGS Flags;
|
||||
internal ulong ConnectionId;
|
||||
internal ulong RequestId;
|
||||
internal ulong UrlContext;
|
||||
|
|
|
|||
|
|
@ -88,6 +88,8 @@ namespace Microsoft.AspNetCore.HttpSys.Internal
|
|||
}
|
||||
}
|
||||
|
||||
internal bool IsHttp2 => NativeRequest->Flags.HasFlag(HttpApiTypes.HTTP_REQUEST_FLAGS.Http2);
|
||||
|
||||
internal uint Size
|
||||
{
|
||||
get { return (uint)_backingBuffer.Length - AlignmentPadding; }
|
||||
|
|
@ -156,6 +158,10 @@ namespace Microsoft.AspNetCore.HttpSys.Internal
|
|||
|
||||
internal Version GetVersion()
|
||||
{
|
||||
if (IsHttp2)
|
||||
{
|
||||
return Constants.V2;
|
||||
}
|
||||
var major = NativeRequest->Version.MajorVersion;
|
||||
var minor = NativeRequest->Version.MinorVersion;
|
||||
if (major == 1 && minor == 1)
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ using System.Threading.Tasks;
|
|||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.Http.Features.Authentication;
|
||||
using Microsoft.AspNetCore.HttpSys.Internal;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.HttpSys
|
||||
|
|
@ -168,11 +169,15 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
if (IsNotInitialized(Fields.Protocol))
|
||||
{
|
||||
var protocol = Request.ProtocolVersion;
|
||||
if (protocol.Major == 1 && protocol.Minor == 1)
|
||||
if (protocol == Constants.V2)
|
||||
{
|
||||
_httpProtocolVersion = "HTTP/2";
|
||||
}
|
||||
else if (protocol == Constants.V1_1)
|
||||
{
|
||||
_httpProtocolVersion = "HTTP/1.1";
|
||||
}
|
||||
else if (protocol.Major == 1 && protocol.Minor == 0)
|
||||
else if (protocol == Constants.V1_0)
|
||||
{
|
||||
_httpProtocolVersion = "HTTP/1.0";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@
|
|||
<Import Project="..\Directory.Build.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<DeveloperBuildTestTfms>netcoreapp2.1</DeveloperBuildTestTfms>
|
||||
<DeveloperBuildTestTfms>netcoreapp2.2</DeveloperBuildTestTfms>
|
||||
<StandardTestTfms>$(DeveloperBuildTestTfms)</StandardTestTfms>
|
||||
<StandardTestTfms Condition=" '$(DeveloperBuild)' != 'true' ">$(StandardTestTfms);netcoreapp2.0</StandardTestTfms>
|
||||
<StandardTestTfms Condition=" '$(DeveloperBuild)' != 'true' AND '$(OS)' == 'Windows_NT' ">$(StandardTestTfms);net461</StandardTestTfms>
|
||||
<StandardTestTfms Condition=" '$(DeveloperBuild)' != 'true' ">$(StandardTestTfms)</StandardTestTfms>
|
||||
<StandardTestTfms Condition=" '$(DeveloperBuild)' != 'true' AND '$(OS)' == 'Windows_NT' ">$(StandardTestTfms);net472</StandardTestTfms>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
@ -15,4 +15,9 @@
|
|||
<PackageReference Include="xunit" Version="$(XunitPackageVersion)" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="$(XunitRunnerVisualStudioPackageVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework' ">
|
||||
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="$(MicrosoftNETFrameworkReferenceAssemblies)" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -40,8 +40,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
Assert.Empty(response.Headers.WwwAuthenticate);
|
||||
}
|
||||
}
|
||||
#if !NETCOREAPP2_0
|
||||
// https://github.com/aspnet/ServerTests/issues/82
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData(AuthenticationSchemes.Negotiate)]
|
||||
[InlineData(AuthenticationSchemes.NTLM)]
|
||||
|
|
@ -107,7 +106,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
Assert.Equal("Negotiate, NTLM, basic", response.Headers.WwwAuthenticate.ToString(), StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData(AuthenticationSchemes.Negotiate)]
|
||||
[InlineData(AuthenticationSchemes.NTLM)]
|
||||
|
|
@ -238,8 +237,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
}
|
||||
}
|
||||
#if !NETCOREAPP2_0
|
||||
// https://github.com/aspnet/ServerTests/issues/82
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData(AuthenticationSchemes.Negotiate)]
|
||||
[InlineData(AuthenticationSchemes.NTLM)]
|
||||
|
|
@ -329,7 +327,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
Assert.Equal(authTypeList.Count(), response.Headers.WwwAuthenticate.Count);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task AuthTypes_Forbid_Forbidden()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,220 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
||||
{
|
||||
public class AuthenticationTests
|
||||
{
|
||||
private static bool AllowAnoymous = true;
|
||||
private static bool DenyAnoymous = false;
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData(AuthenticationSchemes.None)]
|
||||
[InlineData(AuthenticationSchemes.Negotiate)]
|
||||
[InlineData(AuthenticationSchemes.NTLM)]
|
||||
// [InlineData(AuthenticationSchemes.Digest)]
|
||||
[InlineData(AuthenticationSchemes.Basic)]
|
||||
[InlineData(AuthenticationSchemes.Negotiate | AuthenticationSchemes.NTLM | /*AuthenticationSchemes.Digest |*/ AuthenticationSchemes.Basic)]
|
||||
public async Task AuthTypes_AllowAnonymous_NoChallenge(AuthenticationSchemes authType)
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpAuthServer(authType, AllowAnoymous, out address))
|
||||
{
|
||||
Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
Assert.NotNull(context.User);
|
||||
Assert.False(context.User.Identity.IsAuthenticated);
|
||||
Assert.Equal(authType, context.Response.AuthenticationChallenges);
|
||||
context.Dispose();
|
||||
|
||||
var response = await responseTask;
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Empty(response.Headers.WwwAuthenticate);
|
||||
}
|
||||
}
|
||||
#if !NETCOREAPP2_0
|
||||
// https://github.com/aspnet/ServerTests/issues/82
|
||||
[ConditionalTheory]
|
||||
[InlineData(AuthenticationSchemes.Negotiate)]
|
||||
[InlineData(AuthenticationSchemes.NTLM)]
|
||||
// [InlineData(AuthenticationType.Digest)] // TODO: Not implemented
|
||||
[InlineData(AuthenticationSchemes.Basic)]
|
||||
public async Task AuthType_RequireAuth_ChallengesAdded(AuthenticationSchemes authType)
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpAuthServer(authType, DenyAnoymous, out address))
|
||||
{
|
||||
Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
|
||||
|
||||
var contextTask = server.AcceptAsync(Utilities.DefaultTimeout); // Fails when the server shuts down, the challenge happens internally.
|
||||
var response = await responseTask;
|
||||
Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
|
||||
Assert.Equal(authType.ToString(), response.Headers.WwwAuthenticate.ToString(), StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData(AuthenticationSchemes.Negotiate)]
|
||||
[InlineData(AuthenticationSchemes.NTLM)]
|
||||
// [InlineData(AuthenticationSchemes.Digest)] // TODO: Not implemented
|
||||
[InlineData(AuthenticationSchemes.Basic)]
|
||||
public async Task AuthType_AllowAnonymousButSpecify401_ChallengesAdded(AuthenticationSchemes authType)
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpAuthServer(authType, AllowAnoymous, out address))
|
||||
{
|
||||
Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
Assert.NotNull(context.User);
|
||||
Assert.False(context.User.Identity.IsAuthenticated);
|
||||
Assert.Equal(authType, context.Response.AuthenticationChallenges);
|
||||
context.Response.StatusCode = 401;
|
||||
context.Dispose();
|
||||
|
||||
var response = await responseTask;
|
||||
Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
|
||||
Assert.Equal(authType.ToString(), response.Headers.WwwAuthenticate.ToString(), StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task MultipleAuthTypes_AllowAnonymousButSpecify401_ChallengesAdded()
|
||||
{
|
||||
string address;
|
||||
AuthenticationSchemes authType =
|
||||
AuthenticationSchemes.Negotiate
|
||||
| AuthenticationSchemes.NTLM
|
||||
/* | AuthenticationSchemes.Digest TODO: Not implemented */
|
||||
| AuthenticationSchemes.Basic;
|
||||
using (var server = Utilities.CreateHttpAuthServer(authType, AllowAnoymous, out address))
|
||||
{
|
||||
Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
Assert.NotNull(context.User);
|
||||
Assert.False(context.User.Identity.IsAuthenticated);
|
||||
Assert.Equal(authType, context.Response.AuthenticationChallenges);
|
||||
context.Response.StatusCode = 401;
|
||||
context.Dispose();
|
||||
|
||||
var response = await responseTask;
|
||||
Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
|
||||
Assert.Equal("Negotiate, NTLM, basic", response.Headers.WwwAuthenticate.ToString(), StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
[ConditionalTheory]
|
||||
[InlineData(AuthenticationSchemes.Negotiate)]
|
||||
[InlineData(AuthenticationSchemes.NTLM)]
|
||||
// [InlineData(AuthenticationSchemes.Digest)] // TODO: Not implemented
|
||||
// [InlineData(AuthenticationSchemes.Basic)] // Doesn't work with default creds
|
||||
[InlineData(AuthenticationSchemes.Negotiate | AuthenticationSchemes.NTLM | /*AuthenticationType.Digest |*/ AuthenticationSchemes.Basic)]
|
||||
public async Task AuthTypes_AllowAnonymousButSpecify401_Success(AuthenticationSchemes authType)
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpAuthServer(authType, AllowAnoymous, out address))
|
||||
{
|
||||
Task<HttpResponseMessage> responseTask = SendRequestAsync(address, useDefaultCredentials: true);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
Assert.NotNull(context.User);
|
||||
Assert.False(context.User.Identity.IsAuthenticated);
|
||||
Assert.Equal(authType, context.Response.AuthenticationChallenges);
|
||||
context.Response.StatusCode = 401;
|
||||
context.Dispose();
|
||||
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
Assert.NotNull(context.User);
|
||||
Assert.True(context.User.Identity.IsAuthenticated);
|
||||
Assert.Equal(authType, context.Response.AuthenticationChallenges);
|
||||
context.Dispose();
|
||||
|
||||
var response = await responseTask;
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData(AuthenticationSchemes.Negotiate)]
|
||||
[InlineData(AuthenticationSchemes.NTLM)]
|
||||
// [InlineData(AuthenticationSchemes.Digest)] // TODO: Not implemented
|
||||
// [InlineData(AuthenticationSchemes.Basic)] // Doesn't work with default creds
|
||||
[InlineData(AuthenticationSchemes.Negotiate | AuthenticationSchemes.NTLM | /*AuthenticationType.Digest |*/ AuthenticationSchemes.Basic)]
|
||||
public async Task AuthTypes_RequireAuth_Success(AuthenticationSchemes authType)
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpAuthServer(authType, DenyAnoymous, out address))
|
||||
{
|
||||
Task<HttpResponseMessage> responseTask = SendRequestAsync(address, useDefaultCredentials: true);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
Assert.NotNull(context.User);
|
||||
Assert.True(context.User.Identity.IsAuthenticated);
|
||||
Assert.Equal(authType, context.Response.AuthenticationChallenges);
|
||||
context.Dispose();
|
||||
|
||||
var response = await responseTask;
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact(Skip = "Requires a domain joined machine - https://github.com/aspnet/HttpSysServer/issues/357")]
|
||||
public async Task AuthTypes_RequireKerberosAuth_Success()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpAuthServer(AuthenticationSchemes.Kerberos, DenyAnoymous, out address))
|
||||
{
|
||||
Task<HttpResponseMessage> responseTask = SendRequestAsync(address, useDefaultCredentials: true);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
Assert.NotNull(context.User);
|
||||
Assert.True(context.User.Identity.IsAuthenticated);
|
||||
Assert.Equal(AuthenticationSchemes.Kerberos, context.Response.AuthenticationChallenges);
|
||||
context.Dispose();
|
||||
|
||||
var response = await responseTask;
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact(Skip = "Requires a domain joined machine - https://github.com/aspnet/HttpSysServer/issues/357")]
|
||||
public async Task MultipleAuthTypes_KerberosAllowAnonymousButSpecify401_ChallengesAdded()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpAuthServer(AuthenticationSchemes.Kerberos, AllowAnoymous, out address))
|
||||
{
|
||||
Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
Assert.NotNull(context.User);
|
||||
Assert.False(context.User.Identity.IsAuthenticated);
|
||||
Assert.Equal(AuthenticationSchemes.Kerberos, context.Response.AuthenticationChallenges);
|
||||
context.Response.StatusCode = 401;
|
||||
context.Dispose();
|
||||
|
||||
var response = await responseTask;
|
||||
Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
|
||||
Assert.Equal("Kerberos", response.Headers.WwwAuthenticate.ToString(), StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<HttpResponseMessage> SendRequestAsync(string uri, bool useDefaultCredentials = false)
|
||||
{
|
||||
HttpClientHandler handler = new HttpClientHandler();
|
||||
handler.UseDefaultCredentials = useDefaultCredentials;
|
||||
using (HttpClient client = new HttpClient(handler) { Timeout = TimeSpan.FromSeconds(5) })
|
||||
{
|
||||
return await client.GetAsync(uri);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,172 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.IO;
|
||||
using System.Net.Http;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
||||
{
|
||||
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/";
|
||||
|
||||
[ConditionalFact(Skip = "TODO: Add trait filtering support so these SSL tests don't get run on teamcity or the command line."), Trait("scheme", "https")]
|
||||
public async Task Https_200OK_Success()
|
||||
{
|
||||
using (var server = Utilities.CreateHttpsServer())
|
||||
{
|
||||
Task<string> responseTask = SendRequestAsync(Address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context.Dispose();
|
||||
|
||||
string response = await responseTask;
|
||||
Assert.Equal(string.Empty, response);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact(Skip = "TODO: Add trait filtering support so these SSL tests don't get run on teamcity or the command line."), Trait("scheme", "https")]
|
||||
public async Task Https_SendHelloWorld_Success()
|
||||
{
|
||||
using (var server = Utilities.CreateHttpsServer())
|
||||
{
|
||||
Task<string> responseTask = SendRequestAsync(Address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
byte[] body = Encoding.UTF8.GetBytes("Hello World");
|
||||
context.Response.ContentLength = body.Length;
|
||||
await context.Response.Body.WriteAsync(body, 0, body.Length);
|
||||
context.Dispose();
|
||||
|
||||
string response = await responseTask;
|
||||
Assert.Equal("Hello World", response);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact(Skip = "TODO: Add trait filtering support so these SSL tests don't get run on teamcity or the command line."), Trait("scheme", "https")]
|
||||
public async Task Https_EchoHelloWorld_Success()
|
||||
{
|
||||
using (var server = Utilities.CreateHttpsServer())
|
||||
{
|
||||
Task<string> responseTask = SendRequestAsync(Address, "Hello World");
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
string input = new StreamReader(context.Request.Body).ReadToEnd();
|
||||
Assert.Equal("Hello World", input);
|
||||
context.Response.ContentLength = 11;
|
||||
var writer = new StreamWriter(context.Response.Body);
|
||||
await writer.WriteAsync("Hello World");
|
||||
await writer.FlushAsync();
|
||||
|
||||
string response = await responseTask;
|
||||
Assert.Equal("Hello World", response);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact(Skip = "TODO: Add trait filtering support so these SSL tests don't get run on teamcity or the command line."), Trait("scheme", "https")]
|
||||
public async Task Https_ClientCertNotSent_ClientCertNotPresent()
|
||||
{
|
||||
using (var server = Utilities.CreateHttpsServer())
|
||||
{
|
||||
Task<string> responseTask = SendRequestAsync(Address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var cert = await context.Request.GetClientCertificateAsync();
|
||||
Assert.Null(cert);
|
||||
context.Dispose();
|
||||
|
||||
string response = await responseTask;
|
||||
Assert.Equal(string.Empty, response);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact(Skip = "TODO: Add trait filtering support so these SSL tests don't get run on teamcity or the command line."), Trait("scheme", "https")]
|
||||
public async Task Https_ClientCertRequested_ClientCertPresent()
|
||||
{
|
||||
using (var server = Utilities.CreateHttpsServer())
|
||||
{
|
||||
X509Certificate2 clientCert = FindClientCert();
|
||||
Assert.NotNull(clientCert);
|
||||
Task<string> responseTask = SendRequestAsync(Address, clientCert);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var cert = await context.Request.GetClientCertificateAsync();
|
||||
Assert.NotNull(cert);
|
||||
context.Dispose();
|
||||
|
||||
string response = await responseTask;
|
||||
Assert.Equal(string.Empty, response);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<string> SendRequestAsync(string uri,
|
||||
X509Certificate cert = null)
|
||||
{
|
||||
WinHttpHandler handler = new WinHttpHandler();
|
||||
handler.ServerCertificateValidationCallback = (a, b, c, d) => true;
|
||||
if (cert != null)
|
||||
{
|
||||
handler.ClientCertificates.Add(cert);
|
||||
}
|
||||
using (HttpClient client = new HttpClient(handler))
|
||||
{
|
||||
return await client.GetStringAsync(uri);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<string> SendRequestAsync(string uri, string upload)
|
||||
{
|
||||
WinHttpHandler handler = new WinHttpHandler();
|
||||
handler.ServerCertificateValidationCallback = (a, b, c, d) => true;
|
||||
using (HttpClient client = new HttpClient(handler))
|
||||
{
|
||||
HttpResponseMessage response = await client.PostAsync(uri, new StringContent(upload));
|
||||
response.EnsureSuccessStatusCode();
|
||||
return await response.Content.ReadAsStringAsync();
|
||||
}
|
||||
}
|
||||
|
||||
private X509Certificate2 FindClientCert()
|
||||
{
|
||||
var store = new X509Store();
|
||||
store.Open(OpenFlags.ReadOnly);
|
||||
|
||||
foreach (var cert in store.Certificates)
|
||||
{
|
||||
bool isClientAuth = false;
|
||||
bool isSmartCard = false;
|
||||
foreach (var extension in cert.Extensions)
|
||||
{
|
||||
var eku = extension as X509EnhancedKeyUsageExtension;
|
||||
if (eku != null)
|
||||
{
|
||||
foreach (var oid in eku.EnhancedKeyUsages)
|
||||
{
|
||||
if (oid.FriendlyName == "Client Authentication")
|
||||
{
|
||||
isClientAuth = true;
|
||||
}
|
||||
else if (oid.FriendlyName == "Smart Card Logon")
|
||||
{
|
||||
isSmartCard = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isClientAuth && !isSmartCard)
|
||||
{
|
||||
return cert;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,217 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net.Http;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
||||
{
|
||||
public class OpaqueUpgradeTests
|
||||
{
|
||||
[ConditionalFact]
|
||||
[OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, WindowsVersions.Win2008R2)]
|
||||
public async Task OpaqueUpgrade_AfterHeadersSent_Throws()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
Task<HttpResponseMessage> clientTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
byte[] body = Encoding.UTF8.GetBytes("Hello World");
|
||||
await context.Response.Body.WriteAsync(body, 0, body.Length);
|
||||
|
||||
Assert.Throws<InvalidOperationException>(() => context.Response.Headers["Upgrade"] = "WebSocket"); // Win8.1 blocks anything but WebSocket
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(async () => await context.UpgradeAsync());
|
||||
context.Dispose();
|
||||
HttpResponseMessage response = await clientTask;
|
||||
Assert.Equal(200, (int)response.StatusCode);
|
||||
Assert.Equal("Hello World", await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
[OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, WindowsVersions.Win2008R2)]
|
||||
public async Task OpaqueUpgrade_GetUpgrade_Success()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
Task<Stream> clientTask = SendOpaqueRequestAsync("GET", address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
Assert.True(context.IsUpgradableRequest);
|
||||
context.Response.Headers["Upgrade"] = "WebSocket"; // Win8.1 blocks anything but WebSocket
|
||||
Stream serverStream = await context.UpgradeAsync();
|
||||
Assert.True(serverStream.CanRead);
|
||||
Assert.True(serverStream.CanWrite);
|
||||
Stream clientStream = await clientTask;
|
||||
serverStream.Dispose();
|
||||
context.Dispose();
|
||||
clientStream.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, WindowsVersions.Win2008R2)]
|
||||
// See HTTP_VERB for known verbs
|
||||
[InlineData("UNKNOWN", null)]
|
||||
[InlineData("INVALID", null)]
|
||||
[InlineData("OPTIONS", null)]
|
||||
[InlineData("GET", null)]
|
||||
[InlineData("HEAD", null)]
|
||||
[InlineData("DELETE", null)]
|
||||
[InlineData("TRACE", null)]
|
||||
[InlineData("CONNECT", null)]
|
||||
[InlineData("TRACK", null)]
|
||||
[InlineData("MOVE", null)]
|
||||
[InlineData("COPY", null)]
|
||||
[InlineData("PROPFIND", null)]
|
||||
[InlineData("PROPPATCH", null)]
|
||||
[InlineData("MKCOL", null)]
|
||||
[InlineData("LOCK", null)]
|
||||
[InlineData("UNLOCK", null)]
|
||||
[InlineData("SEARCH", null)]
|
||||
[InlineData("CUSTOMVERB", null)]
|
||||
[InlineData("PATCH", null)]
|
||||
[InlineData("POST", "Content-Length: 0")]
|
||||
[InlineData("PUT", "Content-Length: 0")]
|
||||
public async Task OpaqueUpgrade_VariousMethodsUpgradeSendAndReceive_Success(string method, string extraHeader)
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
Task<Stream> clientTask = SendOpaqueRequestAsync(method, address, extraHeader);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
Assert.True(context.IsUpgradableRequest);
|
||||
context.Response.Headers["Upgrade"] = "WebSocket"; // Win8.1 blocks anything but WebSocket
|
||||
Stream serverStream = await context.UpgradeAsync();
|
||||
Stream clientStream = await clientTask;
|
||||
|
||||
byte[] clientBuffer = new byte[] { 0x00, 0x01, 0xFF, 0x00, 0x00 };
|
||||
await clientStream.WriteAsync(clientBuffer, 0, 3);
|
||||
|
||||
byte[] serverBuffer = new byte[clientBuffer.Length];
|
||||
int read = await serverStream.ReadAsync(serverBuffer, 0, serverBuffer.Length);
|
||||
Assert.Equal(clientBuffer, serverBuffer);
|
||||
|
||||
await serverStream.WriteAsync(serverBuffer, 0, read);
|
||||
|
||||
byte[] clientEchoBuffer = new byte[clientBuffer.Length];
|
||||
read = await clientStream.ReadAsync(clientEchoBuffer, 0, clientEchoBuffer.Length);
|
||||
Assert.Equal(clientBuffer, clientEchoBuffer);
|
||||
|
||||
serverStream.Dispose();
|
||||
context.Dispose();
|
||||
clientStream.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, WindowsVersions.Win2008R2)]
|
||||
// Http.Sys returns a 411 Length Required if PUT or POST does not specify content-length or chunked.
|
||||
[InlineData("POST", "Content-Length: 10")]
|
||||
[InlineData("POST", "Transfer-Encoding: chunked")]
|
||||
[InlineData("PUT", "Content-Length: 10")]
|
||||
[InlineData("PUT", "Transfer-Encoding: chunked")]
|
||||
[InlineData("CUSTOMVERB", "Content-Length: 10")]
|
||||
[InlineData("CUSTOMVERB", "Transfer-Encoding: chunked")]
|
||||
public async Task OpaqueUpgrade_InvalidMethodUpgrade_Disconnected(string method, string extraHeader)
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
var clientTask = SendOpaqueRequestAsync(method, address, extraHeader);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
Assert.False(context.IsUpgradableRequest);
|
||||
context.Dispose();
|
||||
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(async () => await clientTask);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<HttpResponseMessage> SendRequestAsync(string uri)
|
||||
{
|
||||
using (HttpClient client = new HttpClient())
|
||||
{
|
||||
return await client.GetAsync(uri);
|
||||
}
|
||||
}
|
||||
|
||||
// Returns a bidirectional opaque stream or throws if the upgrade fails
|
||||
private async Task<Stream> SendOpaqueRequestAsync(string method, string address, string extraHeader = null)
|
||||
{
|
||||
// Connect with a socket
|
||||
Uri uri = new Uri(address);
|
||||
TcpClient client = new TcpClient();
|
||||
try
|
||||
{
|
||||
await client.ConnectAsync(uri.Host, uri.Port);
|
||||
NetworkStream stream = client.GetStream();
|
||||
|
||||
// Send an HTTP GET request
|
||||
byte[] requestBytes = BuildGetRequest(method, uri, extraHeader);
|
||||
await stream.WriteAsync(requestBytes, 0, requestBytes.Length);
|
||||
|
||||
// Read the response headers, fail if it's not a 101
|
||||
await ParseResponseAsync(stream);
|
||||
|
||||
// Return the opaque network stream
|
||||
return stream;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
((IDisposable)client).Dispose();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] BuildGetRequest(string method, Uri uri, string extraHeader)
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.Append(method);
|
||||
builder.Append(" ");
|
||||
builder.Append(uri.PathAndQuery);
|
||||
builder.Append(" HTTP/1.1");
|
||||
builder.AppendLine();
|
||||
|
||||
builder.Append("Host: ");
|
||||
builder.Append(uri.Host);
|
||||
builder.Append(':');
|
||||
builder.Append(uri.Port);
|
||||
builder.AppendLine();
|
||||
|
||||
if (!string.IsNullOrEmpty(extraHeader))
|
||||
{
|
||||
builder.AppendLine(extraHeader);
|
||||
}
|
||||
|
||||
builder.AppendLine();
|
||||
return Encoding.ASCII.GetBytes(builder.ToString());
|
||||
}
|
||||
|
||||
// Read the response headers, fail if it's not a 101
|
||||
private async Task ParseResponseAsync(NetworkStream stream)
|
||||
{
|
||||
StreamReader reader = new StreamReader(stream);
|
||||
string statusLine = await reader.ReadLineAsync();
|
||||
string[] parts = statusLine.Split(' ');
|
||||
if (int.Parse(parts[1]) != 101)
|
||||
{
|
||||
throw new InvalidOperationException("The response status code was incorrect: " + statusLine);
|
||||
}
|
||||
|
||||
// Scan to the end of the headers
|
||||
while (!string.IsNullOrEmpty(reader.ReadLine()))
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -26,7 +26,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
|
||||
Assert.True(server.Options.AllowSynchronousIO);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
byte[] input = new byte[100];
|
||||
|
||||
Assert.True(context.AllowSynchronousIO);
|
||||
|
|
@ -42,162 +42,6 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task RequestBody_ReadSync_Success()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
Task<string> responseTask = SendRequestAsync(address, "Hello World");
|
||||
|
||||
server.Options.AllowSynchronousIO = true;
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
byte[] input = new byte[100];
|
||||
int read = context.Request.Body.Read(input, 0, input.Length);
|
||||
context.Response.ContentLength = read;
|
||||
context.Response.Body.Write(input, 0, read);
|
||||
|
||||
string response = await responseTask;
|
||||
Assert.Equal("Hello World", response);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task RequestBody_ReadAsync_Success()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
Task<string> responseTask = SendRequestAsync(address, "Hello World");
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
byte[] input = new byte[100];
|
||||
int read = await context.Request.Body.ReadAsync(input, 0, input.Length);
|
||||
context.Response.ContentLength = read;
|
||||
await context.Response.Body.WriteAsync(input, 0, read);
|
||||
|
||||
string response = await responseTask;
|
||||
Assert.Equal("Hello World", response);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task RequestBody_ReadBeginEnd_Success()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
Task<string> responseTask = SendRequestAsync(address, "Hello World");
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
byte[] input = new byte[100];
|
||||
int read = context.Request.Body.EndRead(context.Request.Body.BeginRead(input, 0, input.Length, null, null));
|
||||
context.Response.ContentLength = read;
|
||||
context.Response.Body.EndWrite(context.Response.Body.BeginWrite(input, 0, read, null, null));
|
||||
|
||||
string response = await responseTask;
|
||||
Assert.Equal("Hello World", response);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task RequestBody_InvalidBuffer_ArgumentException()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
Task<string> responseTask = SendRequestAsync(address, "Hello World");
|
||||
|
||||
server.Options.AllowSynchronousIO = true;
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
byte[] input = new byte[100];
|
||||
Assert.Throws<ArgumentNullException>("buffer", () => context.Request.Body.Read(null, 0, 1));
|
||||
Assert.Throws<ArgumentOutOfRangeException>("offset", () => context.Request.Body.Read(input, -1, 1));
|
||||
Assert.Throws<ArgumentOutOfRangeException>("offset", () => context.Request.Body.Read(input, input.Length + 1, 1));
|
||||
Assert.Throws<ArgumentOutOfRangeException>("size", () => context.Request.Body.Read(input, 10, -1));
|
||||
Assert.Throws<ArgumentOutOfRangeException>("size", () => context.Request.Body.Read(input, 0, 0));
|
||||
Assert.Throws<ArgumentOutOfRangeException>("size", () => context.Request.Body.Read(input, 1, input.Length));
|
||||
Assert.Throws<ArgumentOutOfRangeException>("size", () => context.Request.Body.Read(input, 0, input.Length + 1));
|
||||
context.Dispose();
|
||||
|
||||
string response = await responseTask;
|
||||
Assert.Equal(string.Empty, response);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task RequestBody_ReadSyncPartialBody_Success()
|
||||
{
|
||||
StaggardContent content = new StaggardContent();
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
Task<string> responseTask = SendRequestAsync(address, content);
|
||||
|
||||
server.Options.AllowSynchronousIO = true;
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
byte[] input = new byte[10];
|
||||
int read = context.Request.Body.Read(input, 0, input.Length);
|
||||
Assert.Equal(5, read);
|
||||
content.Block.Release();
|
||||
read = context.Request.Body.Read(input, 0, input.Length);
|
||||
Assert.Equal(5, read);
|
||||
context.Dispose();
|
||||
|
||||
string response = await responseTask;
|
||||
Assert.Equal(string.Empty, response);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task RequestBody_ReadAsyncPartialBody_Success()
|
||||
{
|
||||
StaggardContent content = new StaggardContent();
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
Task<string> responseTask = SendRequestAsync(address, content);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
byte[] input = new byte[10];
|
||||
int read = await context.Request.Body.ReadAsync(input, 0, input.Length);
|
||||
Assert.Equal(5, read);
|
||||
content.Block.Release();
|
||||
read = await context.Request.Body.ReadAsync(input, 0, input.Length);
|
||||
Assert.Equal(5, read);
|
||||
context.Dispose();
|
||||
|
||||
string response = await responseTask;
|
||||
Assert.Equal(string.Empty, response);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task RequestBody_PostWithImidateBody_Success()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
Task<string> responseTask = SendSocketRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
byte[] input = new byte[11];
|
||||
int read = await context.Request.Body.ReadAsync(input, 0, input.Length);
|
||||
Assert.Equal(10, read);
|
||||
read = await context.Request.Body.ReadAsync(input, 0, input.Length);
|
||||
Assert.Equal(0, read);
|
||||
context.Response.ContentLength = 10;
|
||||
await context.Response.Body.WriteAsync(input, 0, 10);
|
||||
context.Dispose();
|
||||
|
||||
string response = await responseTask;
|
||||
string[] lines = response.Split('\r', '\n');
|
||||
Assert.Equal(13, lines.Length);
|
||||
Assert.Equal("HTTP/1.1 200 OK", lines[0]);
|
||||
Assert.Equal("0123456789", lines[12]);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task RequestBody_ReadAsyncAlreadyCanceled_ReturnsCanceledTask()
|
||||
{
|
||||
|
|
@ -206,7 +50,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
{
|
||||
Task<string> responseTask = SendRequestAsync(address, "Hello World");
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
|
||||
byte[] input = new byte[10];
|
||||
var cts = new CancellationTokenSource();
|
||||
|
|
@ -231,7 +75,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
{
|
||||
Task<string> responseTask = SendRequestAsync(address, content);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
byte[] input = new byte[10];
|
||||
var cts = new CancellationTokenSource();
|
||||
int read = await context.Request.Body.ReadAsync(input, 0, input.Length, cts.Token);
|
||||
|
|
@ -255,7 +99,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
{
|
||||
Task<string> responseTask = SendRequestAsync(address, content);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
byte[] input = new byte[10];
|
||||
var cts = new CancellationTokenSource();
|
||||
cts.CancelAfter(TimeSpan.FromSeconds(5));
|
||||
|
|
@ -280,7 +124,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
{
|
||||
Task<string> responseTask = SendRequestAsync(address, content);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
byte[] input = new byte[10];
|
||||
var cts = new CancellationTokenSource();
|
||||
int read = await context.Request.Body.ReadAsync(input, 0, input.Length, cts.Token);
|
||||
|
|
@ -305,7 +149,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
{
|
||||
Task<string> responseTask = SendRequestAsync(address, content);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
byte[] input = new byte[10];
|
||||
var cts = new CancellationTokenSource();
|
||||
int read = await context.Request.Body.ReadAsync(input, 0, input.Length, cts.Token);
|
||||
|
|
@ -333,7 +177,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
var client = new HttpClient();
|
||||
var responseTask = client.PostAsync(address, content);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
byte[] input = new byte[10];
|
||||
int read = await context.Request.Body.ReadAsync(input, 0, input.Length, context.DisconnectToken);
|
||||
Assert.False(context.DisconnectToken.IsCancellationRequested);
|
||||
|
|
@ -364,51 +208,6 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
}
|
||||
}
|
||||
|
||||
private async Task<string> SendSocketRequestAsync(string address)
|
||||
{
|
||||
// Connect with a socket
|
||||
Uri uri = new Uri(address);
|
||||
TcpClient client = new TcpClient();
|
||||
try
|
||||
{
|
||||
await client.ConnectAsync(uri.Host, uri.Port);
|
||||
NetworkStream stream = client.GetStream();
|
||||
|
||||
// Send an HTTP GET request
|
||||
byte[] requestBytes = BuildPostRequest(uri);
|
||||
await stream.WriteAsync(requestBytes, 0, requestBytes.Length);
|
||||
StreamReader reader = new StreamReader(stream);
|
||||
return await reader.ReadToEndAsync();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
((IDisposable)client).Dispose();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] BuildPostRequest(Uri uri)
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.Append("POST");
|
||||
builder.Append(" ");
|
||||
builder.Append(uri.PathAndQuery);
|
||||
builder.Append(" HTTP/1.1");
|
||||
builder.AppendLine();
|
||||
|
||||
builder.Append("Host: ");
|
||||
builder.Append(uri.Host);
|
||||
builder.Append(':');
|
||||
builder.Append(uri.Port);
|
||||
builder.AppendLine();
|
||||
|
||||
builder.AppendLine("Connection: close");
|
||||
builder.AppendLine("Content-Length: 10");
|
||||
builder.AppendLine();
|
||||
builder.Append("0123456789");
|
||||
return Encoding.ASCII.GetBytes(builder.ToString());
|
||||
}
|
||||
|
||||
private class StaggardContent : HttpContent
|
||||
{
|
||||
public StaggardContent()
|
||||
|
|
|
|||
|
|
@ -15,57 +15,6 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
{
|
||||
public class RequestHeaderTests
|
||||
{
|
||||
[ConditionalFact]
|
||||
public async Task RequestHeaders_ClientSendsDefaultHeaders_Success()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
Task<string> responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var requestHeaders = context.Request.Headers;
|
||||
// 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("Keep-Alive", requestHeaders.Get("Connection"));
|
||||
Assert.Equal(new Uri(address).Authority, requestHeaders["Host"]);
|
||||
StringValues values;
|
||||
Assert.False(requestHeaders.TryGetValue("Accept", out values));
|
||||
Assert.False(requestHeaders.ContainsKey("Accept"));
|
||||
Assert.True(StringValues.IsNullOrEmpty(requestHeaders["Accept"]));
|
||||
context.Dispose();
|
||||
|
||||
string response = await responseTask;
|
||||
Assert.Equal(string.Empty, response);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task RequestHeaders_ClientSendsCustomHeaders_Success()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
string[] customValues = new string[] { "custom1, and custom2", "custom3" };
|
||||
Task responseTask = SendRequestAsync(address, "Custom-Header", customValues);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var requestHeaders = context.Request.Headers;
|
||||
Assert.Equal(4, requestHeaders.Count);
|
||||
Assert.Equal(new Uri(address).Authority, requestHeaders["Host"]);
|
||||
Assert.Equal(new[] { new Uri(address).Authority }, requestHeaders.GetValues("Host"));
|
||||
Assert.Equal("close", requestHeaders["Connection"]);
|
||||
Assert.Equal(new[] { "close" }, requestHeaders.GetValues("Connection"));
|
||||
// Apparently Http.Sys squashes request headers together.
|
||||
Assert.Equal("custom1, and custom2, custom3", requestHeaders["Custom-Header"]);
|
||||
Assert.Equal(new[] { "custom1", "and custom2", "custom3" }, requestHeaders.GetValues("Custom-Header"));
|
||||
Assert.Equal("spacervalue, spacervalue", requestHeaders["Spacer-Header"]);
|
||||
Assert.Equal(new[] { "spacervalue", "spacervalue" }, requestHeaders.GetValues("Spacer-Header"));
|
||||
context.Dispose();
|
||||
|
||||
await responseTask;
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task RequestHeaders_ClientSendsUtf8Headers_Success()
|
||||
|
|
@ -144,14 +93,6 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
}
|
||||
}
|
||||
|
||||
private async Task<string> SendRequestAsync(string uri)
|
||||
{
|
||||
using (HttpClient client = new HttpClient())
|
||||
{
|
||||
return await client.GetStringAsync(uri);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SendRequestAsync(string address, string customHeader, string[] customValues)
|
||||
{
|
||||
var uri = new Uri(address);
|
||||
|
|
|
|||
|
|
@ -15,74 +15,6 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
{
|
||||
public class RequestTests
|
||||
{
|
||||
[ConditionalFact]
|
||||
public async Task Request_SimpleGet_Success()
|
||||
{
|
||||
string root;
|
||||
using (var server = Utilities.CreateHttpServerReturnRoot("/basepath", out root))
|
||||
{
|
||||
Task<string> responseTask = SendRequestAsync(root + "/basepath/SomePath?SomeQuery");
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
|
||||
// General fields
|
||||
var request = context.Request;
|
||||
|
||||
// Request Keys
|
||||
Assert.Equal("GET", request.Method);
|
||||
Assert.Equal(Stream.Null, request.Body);
|
||||
Assert.NotNull(request.Headers);
|
||||
Assert.Equal("http", request.Scheme);
|
||||
Assert.Equal("/basepath", request.PathBase);
|
||||
Assert.Equal("/SomePath", request.Path);
|
||||
Assert.Equal("?SomeQuery", request.QueryString);
|
||||
Assert.Equal(new Version(1, 1), request.ProtocolVersion);
|
||||
|
||||
Assert.Equal("::1", request.RemoteIpAddress.ToString());
|
||||
Assert.NotEqual(0, request.RemotePort);
|
||||
Assert.Equal("::1", request.LocalIpAddress.ToString());
|
||||
Assert.NotEqual(0, request.LocalPort);
|
||||
|
||||
// Note: Response keys are validated in the ResponseTests
|
||||
|
||||
context.Dispose();
|
||||
|
||||
string response = await responseTask;
|
||||
Assert.Equal(string.Empty, response);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData("/", "/", "", "/")]
|
||||
[InlineData("/basepath/", "/basepath", "/basepath", "")]
|
||||
[InlineData("/basepath/", "/basepath/", "/basepath", "/")]
|
||||
[InlineData("/basepath/", "/basepath/subpath", "/basepath", "/subpath")]
|
||||
[InlineData("/base path/", "/base%20path/sub%20path", "/base path", "/sub path")]
|
||||
[InlineData("/base葉path/", "/base%E8%91%89path/sub%E8%91%89path", "/base葉path", "/sub葉path")]
|
||||
[InlineData("/basepath/", "/basepath/sub%2Fpath", "/basepath", "/sub%2Fpath")]
|
||||
public async Task Request_PathSplitting(string pathBase, string requestPath, string expectedPathBase, string expectedPath)
|
||||
{
|
||||
string root;
|
||||
using (var server = Utilities.CreateHttpServerReturnRoot(pathBase, out root))
|
||||
{
|
||||
Task<string> responseTask = SendRequestAsync(root + requestPath);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
|
||||
// General fields
|
||||
var request = context.Request;
|
||||
|
||||
// Request Keys
|
||||
Assert.Equal("http", request.Scheme);
|
||||
Assert.Equal(expectedPath, request.Path);
|
||||
Assert.Equal(expectedPathBase, request.PathBase);
|
||||
Assert.Equal(string.Empty, request.QueryString);
|
||||
context.Dispose();
|
||||
|
||||
string response = await responseTask;
|
||||
Assert.Equal(string.Empty, response);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData("/path%")]
|
||||
|
|
@ -102,35 +34,6 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task Request_DoubleEscapingAllowed()
|
||||
{
|
||||
string root;
|
||||
using (var server = Utilities.CreateHttpServerReturnRoot("/", out root))
|
||||
{
|
||||
var responseTask = SendSocketRequestAsync(root, "/%252F");
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
Assert.Equal("/%2F", context.Request.Path);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task Request_FullUriInRequestLine_ParsesPath()
|
||||
{
|
||||
string root;
|
||||
using (var server = Utilities.CreateHttpServerReturnRoot("/", out root))
|
||||
{
|
||||
// Send a HTTP request with the request line:
|
||||
// GET http://localhost:5001 HTTP/1.1
|
||||
var responseTask = SendSocketRequestAsync(root, root);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
Assert.Equal("/", context.Request.Path);
|
||||
Assert.Equal("", context.Request.PathBase);
|
||||
Assert.Equal(root, context.Request.RawUrl);
|
||||
Assert.False(root.EndsWith("/")); // make sure root doesn't have a trailing slash
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task Request_OptionsStar_EmptyPath()
|
||||
{
|
||||
|
|
@ -138,7 +41,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
using (var server = Utilities.CreateHttpServerReturnRoot("/", out root))
|
||||
{
|
||||
var responseTask = SendSocketRequestAsync(root, "*", "OPTIONS");
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
Assert.Equal("", context.Request.PathBase);
|
||||
Assert.Equal("", context.Request.Path);
|
||||
Assert.Equal("*", context.Request.RawUrl);
|
||||
|
|
@ -146,50 +49,6 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
}
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
// The test server defines these prefixes: "/", "/11", "/2/3", "/2", "/11/2"
|
||||
[InlineData("/", "", "/")]
|
||||
[InlineData("/random", "", "/random")]
|
||||
[InlineData("/11", "/11", "")]
|
||||
[InlineData("/11/", "/11", "/")]
|
||||
[InlineData("/11/random", "/11", "/random")]
|
||||
[InlineData("/2", "/2", "")]
|
||||
[InlineData("/2/", "/2", "/")]
|
||||
[InlineData("/2/random", "/2", "/random")]
|
||||
[InlineData("/2/3", "/2/3", "")]
|
||||
[InlineData("/2/3/", "/2/3", "/")]
|
||||
[InlineData("/2/3/random", "/2/3", "/random")]
|
||||
public async Task Request_MultiplePrefixes(string requestUri, string expectedPathBase, string expectedPath)
|
||||
{
|
||||
// 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 HttpSysListener(new HttpSysOptions(), new LoggerFactory());
|
||||
using (server)
|
||||
{
|
||||
var uriBuilder = new UriBuilder(root);
|
||||
foreach (string path in new[] { "/", "/11", "/2/3", "/2", "/11/2" })
|
||||
{
|
||||
server.Options.UrlPrefixes.Add(UrlPrefix.Create(uriBuilder.Scheme, uriBuilder.Host, uriBuilder.Port, path));
|
||||
}
|
||||
server.Start();
|
||||
|
||||
Task<string> responseTask = SendRequestAsync(root + requestUri);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var request = context.Request;
|
||||
|
||||
Assert.Equal(expectedPath, request.Path);
|
||||
Assert.Equal(expectedPathBase, request.PathBase);
|
||||
|
||||
context.Dispose();
|
||||
|
||||
string response = await responseTask;
|
||||
Assert.Equal(string.Empty, response);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData("%D0%A4", "Ф")]
|
||||
[InlineData("%d0%a4", "Ф")]
|
||||
|
|
@ -220,7 +79,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
using (var server = Utilities.CreateHttpServerReturnRoot("/", out root))
|
||||
{
|
||||
var responseTask = SendSocketRequestAsync(root, "/" + requestPath);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
actualPath = context.Request.Path;
|
||||
context.Dispose();
|
||||
|
||||
|
|
@ -270,7 +129,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
using (var server = Utilities.CreateHttpServerReturnRoot("/", out root))
|
||||
{
|
||||
var responseTask = SendSocketRequestAsync(root, requestPath);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
Assert.Equal(expectedPath, context.Request.Path);
|
||||
context.Dispose();
|
||||
|
||||
|
|
@ -279,14 +138,6 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
}
|
||||
}
|
||||
|
||||
private async Task<string> SendRequestAsync(string uri)
|
||||
{
|
||||
using (HttpClient client = new HttpClient())
|
||||
{
|
||||
return await client.GetStringAsync(uri);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<string> SendSocketRequestAsync(string address, string path, string method = "GET")
|
||||
{
|
||||
var uri = new Uri(address);
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
{
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
|
||||
Assert.True(context.AllowSynchronousIO);
|
||||
|
||||
|
|
@ -51,30 +51,6 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ResponseBody_WriteNoHeaders_DefaultsToChunked()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
server.Options.AllowSynchronousIO = true;
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context.Response.Body.Write(new byte[10], 0, 10);
|
||||
await context.Response.Body.WriteAsync(new byte[10], 0, 10);
|
||||
context.Dispose();
|
||||
|
||||
var response = await responseTask;
|
||||
Assert.Equal(200, (int)response.StatusCode);
|
||||
Assert.Equal(new Version(1, 1), response.Version);
|
||||
IEnumerable<string> ignored;
|
||||
Assert.False(response.Content.Headers.TryGetValues("content-length", out ignored), "Content-Length");
|
||||
Assert.True(response.Headers.TransferEncodingChunked.Value, "Chunked");
|
||||
Assert.Equal(new byte[20], await response.Content.ReadAsByteArrayAsync());
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ResponseBody_FlushThenWrite_DefaultsToChunkedAndTerminates()
|
||||
{
|
||||
|
|
@ -84,7 +60,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
server.Options.AllowSynchronousIO = true;
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Body.Write(new byte[10], 0, 10);
|
||||
context.Response.Body.Flush();
|
||||
await context.Response.Body.WriteAsync(new byte[10], 0, 10);
|
||||
|
|
@ -99,144 +75,6 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ResponseBody_WriteChunked_ManuallyChunked()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context.Response.Headers["transfeR-Encoding"] = "CHunked";
|
||||
Stream stream = context.Response.Body;
|
||||
var responseBytes = Encoding.ASCII.GetBytes("10\r\nManually Chunked\r\n0\r\n\r\n");
|
||||
await stream.WriteAsync(responseBytes, 0, responseBytes.Length);
|
||||
context.Dispose();
|
||||
|
||||
var response = await responseTask;
|
||||
Assert.Equal(200, (int)response.StatusCode);
|
||||
Assert.Equal(new Version(1, 1), response.Version);
|
||||
IEnumerable<string> ignored;
|
||||
Assert.False(response.Content.Headers.TryGetValues("content-length", out ignored), "Content-Length");
|
||||
Assert.True(response.Headers.TransferEncodingChunked.Value, "Chunked");
|
||||
Assert.Equal("Manually Chunked", await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ResponseBody_WriteContentLength_PassedThrough()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
server.Options.AllowSynchronousIO = true;
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context.Response.Headers["Content-lenGth"] = " 30 ";
|
||||
var stream = context.Response.Body;
|
||||
stream.EndWrite(stream.BeginWrite(new byte[10], 0, 10, null, null));
|
||||
stream.Write(new byte[10], 0, 10);
|
||||
await stream.WriteAsync(new byte[10], 0, 10);
|
||||
context.Dispose();
|
||||
|
||||
var response = await responseTask;
|
||||
Assert.Equal(200, (int)response.StatusCode);
|
||||
Assert.Equal(new Version(1, 1), response.Version);
|
||||
IEnumerable<string> contentLength;
|
||||
Assert.True(response.Content.Headers.TryGetValues("content-length", out contentLength), "Content-Length");
|
||||
Assert.Equal("30", contentLength.First());
|
||||
Assert.Null(response.Headers.TransferEncodingChunked);
|
||||
Assert.Equal(new byte[30], await response.Content.ReadAsByteArrayAsync());
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ResponseBody_WriteContentLengthNoneWritten_Aborts()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context.Response.Headers["Content-lenGth"] = " 20 ";
|
||||
context.Dispose();
|
||||
#if NET461
|
||||
// HttpClient retries the request because it didn't get a response.
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context.Response.Headers["Content-lenGth"] = " 20 ";
|
||||
context.Dispose();
|
||||
#elif NETCOREAPP2_0 || NETCOREAPP2_1
|
||||
#else
|
||||
#error Target framework needs to be updated
|
||||
#endif
|
||||
await Assert.ThrowsAsync<HttpRequestException>(() => responseTask);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ResponseBody_WriteContentLengthNotEnoughWritten_Aborts()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context.Response.Headers["Content-lenGth"] = " 20 ";
|
||||
context.Response.Body.Write(new byte[5], 0, 5);
|
||||
context.Dispose();
|
||||
|
||||
await Assert.ThrowsAsync<HttpRequestException>(() => responseTask);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ResponseBody_WriteContentLengthTooMuchWritten_Throws()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context.Response.Headers["Content-lenGth"] = " 10 ";
|
||||
context.Response.Body.Write(new byte[5], 0, 5);
|
||||
Assert.Throws<InvalidOperationException>(() => context.Response.Body.Write(new byte[6], 0, 6));
|
||||
context.Dispose();
|
||||
|
||||
await Assert.ThrowsAsync<HttpRequestException>(() => responseTask);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ResponseBody_WriteContentLengthExtraWritten_Throws()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
server.Options.AllowSynchronousIO = true;
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context.Response.Headers["Content-lenGth"] = " 10 ";
|
||||
context.Response.Body.Write(new byte[10], 0, 10);
|
||||
Assert.Throws<ObjectDisposedException>(() => context.Response.Body.Write(new byte[6], 0, 6));
|
||||
context.Dispose();
|
||||
|
||||
var response = await responseTask;
|
||||
Assert.Equal(200, (int)response.StatusCode);
|
||||
Assert.Equal(new Version(1, 1), response.Version);
|
||||
IEnumerable<string> contentLength;
|
||||
Assert.True(response.Content.Headers.TryGetValues("content-length", out contentLength), "Content-Length");
|
||||
Assert.Equal("10", contentLength.First());
|
||||
Assert.Null(response.Headers.TransferEncodingChunked);
|
||||
Assert.Equal(new byte[10], await response.Content.ReadAsByteArrayAsync());
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ResponseBody_WriteZeroCount_StartsChunkedResponse()
|
||||
{
|
||||
|
|
@ -246,7 +84,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
server.Options.AllowSynchronousIO = true;
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Body.Write(new byte[10], 0, 0);
|
||||
Assert.True(context.Response.HasStarted);
|
||||
await context.Response.Body.WriteAsync(new byte[10], 0, 0);
|
||||
|
|
@ -270,7 +108,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
{
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
var cts = new CancellationTokenSource();
|
||||
// First write sends headers
|
||||
await context.Response.Body.WriteAsync(new byte[10], 0, 10, cts.Token);
|
||||
|
|
@ -291,7 +129,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
{
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
var cts = new CancellationTokenSource();
|
||||
cts.CancelAfter(TimeSpan.FromSeconds(10));
|
||||
// First write sends headers
|
||||
|
|
@ -314,23 +152,23 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
server.Options.ThrowWriteExceptions = true;
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
var cts = new CancellationTokenSource();
|
||||
cts.Cancel();
|
||||
// First write sends headers
|
||||
var writeTask = context.Response.Body.WriteAsync(new byte[10], 0, 10, cts.Token);
|
||||
Assert.True(writeTask.IsCanceled);
|
||||
context.Dispose();
|
||||
#if NET461
|
||||
#if NET472
|
||||
// HttpClient retries the request because it didn't get a response.
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
cts = new CancellationTokenSource();
|
||||
cts.Cancel();
|
||||
// First write sends headers
|
||||
writeTask = context.Response.Body.WriteAsync(new byte[10], 0, 10, cts.Token);
|
||||
Assert.True(writeTask.IsCanceled);
|
||||
context.Dispose();
|
||||
#elif NETCOREAPP2_0 || NETCOREAPP2_1
|
||||
#elif NETCOREAPP2_2
|
||||
#else
|
||||
#error Target framework needs to be updated
|
||||
#endif
|
||||
|
|
@ -346,23 +184,23 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
{
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
var cts = new CancellationTokenSource();
|
||||
cts.Cancel();
|
||||
// First write sends headers
|
||||
var writeTask = context.Response.Body.WriteAsync(new byte[10], 0, 10, cts.Token);
|
||||
Assert.True(writeTask.IsCanceled);
|
||||
context.Dispose();
|
||||
#if NET461
|
||||
#if NET472
|
||||
// HttpClient retries the request because it didn't get a response.
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
cts = new CancellationTokenSource();
|
||||
cts.Cancel();
|
||||
// First write sends headers
|
||||
writeTask = context.Response.Body.WriteAsync(new byte[10], 0, 10, cts.Token);
|
||||
Assert.True(writeTask.IsCanceled);
|
||||
context.Dispose();
|
||||
#elif NETCOREAPP2_0 || NETCOREAPP2_1
|
||||
#elif NETCOREAPP2_2
|
||||
#else
|
||||
#error Target framework needs to be updated
|
||||
#endif
|
||||
|
|
@ -379,16 +217,17 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
server.Options.ThrowWriteExceptions = true;
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
var cts = new CancellationTokenSource();
|
||||
// First write sends headers
|
||||
await context.Response.Body.WriteAsync(new byte[10], 0, 10, cts.Token);
|
||||
var response = await responseTask;
|
||||
cts.Cancel();
|
||||
var writeTask = context.Response.Body.WriteAsync(new byte[10], 0, 10, cts.Token);
|
||||
Assert.True(writeTask.IsCanceled);
|
||||
context.Dispose();
|
||||
|
||||
await Assert.ThrowsAsync<HttpRequestException>(() => responseTask);
|
||||
await Assert.ThrowsAsync<HttpRequestException>(() => response.Content.LoadIntoBufferAsync());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -400,16 +239,17 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
{
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
var cts = new CancellationTokenSource();
|
||||
// First write sends headers
|
||||
await context.Response.Body.WriteAsync(new byte[10], 0, 10, cts.Token);
|
||||
var response = await responseTask;
|
||||
cts.Cancel();
|
||||
var writeTask = context.Response.Body.WriteAsync(new byte[10], 0, 10, cts.Token);
|
||||
Assert.True(writeTask.IsCanceled);
|
||||
context.Dispose();
|
||||
|
||||
await Assert.ThrowsAsync<HttpRequestException>(() => responseTask);
|
||||
await Assert.ThrowsAsync<HttpRequestException>(() => response.Content.LoadIntoBufferAsync());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -424,7 +264,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
var cts = new CancellationTokenSource();
|
||||
var responseTask = SendRequestAsync(address, cts.Token);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
// First write sends headers
|
||||
cts.Cancel();
|
||||
await Assert.ThrowsAnyAsync<OperationCanceledException>(() => responseTask);
|
||||
|
|
@ -454,7 +294,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
var cts = new CancellationTokenSource();
|
||||
var responseTask = SendRequestAsync(address, cts.Token);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
|
||||
// First write sends headers
|
||||
cts.Cancel();
|
||||
|
|
@ -486,7 +326,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
var responseTask = SendRequestAsync(address, cts.Token);
|
||||
|
||||
server.Options.AllowSynchronousIO = true;
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
// First write sends headers
|
||||
cts.Cancel();
|
||||
await Assert.ThrowsAnyAsync<OperationCanceledException>(() => responseTask);
|
||||
|
|
@ -509,7 +349,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
var cts = new CancellationTokenSource();
|
||||
var responseTask = SendRequestAsync(address, cts.Token);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
// First write sends headers
|
||||
cts.Cancel();
|
||||
await Assert.ThrowsAnyAsync<OperationCanceledException>(() => responseTask);
|
||||
|
|
@ -535,7 +375,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
{
|
||||
var responseTask = client.GetAsync(address, HttpCompletionOption.ResponseHeadersRead);
|
||||
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
// First write sends headers
|
||||
context.Response.Body.Write(new byte[10], 0, 10);
|
||||
|
||||
|
|
@ -569,7 +409,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
{
|
||||
var responseTask = client.GetAsync(address, HttpCompletionOption.ResponseHeadersRead);
|
||||
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
// First write sends headers
|
||||
await context.Response.Body.WriteAsync(new byte[10], 0, 10);
|
||||
|
||||
|
|
@ -603,7 +443,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
{
|
||||
var responseTask = client.GetAsync(address, HttpCompletionOption.ResponseHeadersRead);
|
||||
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
// First write sends headers
|
||||
context.Response.Body.Write(new byte[10], 0, 10);
|
||||
|
||||
|
|
@ -633,7 +473,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
{
|
||||
var responseTask = client.GetAsync(address, HttpCompletionOption.ResponseHeadersRead);
|
||||
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
// First write sends headers
|
||||
await context.Response.Body.WriteAsync(new byte[10], 0, 10);
|
||||
|
||||
|
|
@ -654,9 +494,9 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
|
||||
private async Task<HttpResponseMessage> SendRequestAsync(string uri, CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
using (HttpClient client = new HttpClient())
|
||||
using (HttpClient client = new HttpClient() { Timeout = Utilities.DefaultTimeout })
|
||||
{
|
||||
return await client.GetAsync(uri, cancellationToken);
|
||||
return await client.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead, cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,9 +30,10 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "1";
|
||||
// Http.sys requires a content-type to cache
|
||||
context.Response.CacheTtl = TimeSpan.FromSeconds(10);
|
||||
|
|
@ -45,7 +46,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
|
||||
responseTask = SendRequestAsync(address);
|
||||
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "2";
|
||||
// Http.sys requires a content-type to cache
|
||||
context.Response.CacheTtl = TimeSpan.FromSeconds(10);
|
||||
|
|
@ -69,9 +70,10 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "1";
|
||||
// Http.sys does not require a content-type to cache on Win7 and Win2008R2
|
||||
context.Response.CacheTtl = TimeSpan.FromSeconds(10);
|
||||
|
|
@ -96,9 +98,10 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "1";
|
||||
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||
context.Response.CacheTtl = TimeSpan.FromSeconds(10);
|
||||
|
|
@ -125,9 +128,10 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "1";
|
||||
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||
context.Response.CacheTtl = TimeSpan.FromSeconds(10);
|
||||
|
|
@ -156,9 +160,10 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "1";
|
||||
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||
context.Response.Headers["age"] = "12345";
|
||||
|
|
@ -188,9 +193,10 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "1";
|
||||
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||
context.Response.CacheTtl = TimeSpan.FromSeconds(0);
|
||||
|
|
@ -203,7 +209,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
|
||||
responseTask = SendRequestAsync(address);
|
||||
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "2";
|
||||
// Http.sys requires a content-type to cache
|
||||
context.Response.CacheTtl = TimeSpan.FromSeconds(10);
|
||||
|
|
@ -222,9 +228,10 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "1";
|
||||
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||
context.Response.CacheTtl = TimeSpan.FromMilliseconds(900);
|
||||
|
|
@ -237,7 +244,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
|
||||
responseTask = SendRequestAsync(address);
|
||||
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "2";
|
||||
// Http.sys requires a content-type to cache
|
||||
context.Response.CacheTtl = TimeSpan.FromSeconds(10);
|
||||
|
|
@ -256,9 +263,10 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "1";
|
||||
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||
context.Response.CacheTtl = TimeSpan.FromSeconds(-10);
|
||||
|
|
@ -271,7 +279,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
|
||||
responseTask = SendRequestAsync(address);
|
||||
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "2";
|
||||
// Http.sys requires a content-type to cache
|
||||
context.Response.CacheTtl = TimeSpan.FromSeconds(10);
|
||||
|
|
@ -290,9 +298,10 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "1";
|
||||
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||
context.Response.CacheTtl = TimeSpan.MaxValue;
|
||||
|
|
@ -317,9 +326,10 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "1";
|
||||
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||
context.Response.ContentLength = 10;
|
||||
|
|
@ -348,9 +358,10 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "1";
|
||||
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||
context.Response.ContentLength = 10;
|
||||
|
|
@ -379,10 +390,11 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
server.Options.AllowSynchronousIO = true;
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "1";
|
||||
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||
context.Response.CacheTtl = TimeSpan.FromSeconds(10);
|
||||
|
|
@ -396,7 +408,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
|
||||
responseTask = SendRequestAsync(address);
|
||||
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "2";
|
||||
context.Dispose();
|
||||
|
||||
|
|
@ -413,9 +425,10 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "1";
|
||||
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||
context.Response.CacheTtl = TimeSpan.FromSeconds(10);
|
||||
|
|
@ -430,7 +443,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
|
||||
responseTask = SendRequestAsync(address);
|
||||
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "2";
|
||||
context.Dispose();
|
||||
|
||||
|
|
@ -447,9 +460,10 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "1";
|
||||
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||
context.Response.ContentLength = 10;
|
||||
|
|
@ -478,9 +492,10 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "1";
|
||||
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||
context.Response.CacheTtl = TimeSpan.FromSeconds(10);
|
||||
|
|
@ -494,7 +509,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
|
||||
responseTask = SendRequestAsync(address);
|
||||
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "2";
|
||||
context.Dispose();
|
||||
|
||||
|
|
@ -511,9 +526,10 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "1";
|
||||
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||
context.Response.ContentLength =_fileLength;
|
||||
|
|
@ -542,6 +558,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
// Http.Sys will cache almost any status code.
|
||||
for (int status = 200; status < 600; status++)
|
||||
{
|
||||
|
|
@ -554,7 +571,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
|
||||
var responseTask = SendRequestAsync(address + status);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.StatusCode = status;
|
||||
context.Response.Headers["x-request-count"] = status.ToString();
|
||||
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||
|
|
@ -618,9 +635,10 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
var responseTask = SendRequestAsync(address, method);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = context.Request.Method + "1";
|
||||
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||
context.Response.CacheTtl = TimeSpan.FromSeconds(10);
|
||||
|
|
@ -633,7 +651,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
|
||||
responseTask = SendRequestAsync(address, method);
|
||||
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = context.Request.Method + "2";
|
||||
// Http.sys requires a content-type to cache
|
||||
context.Response.CacheTtl = TimeSpan.FromSeconds(10);
|
||||
|
|
@ -676,10 +694,11 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
// Cache the first response
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = context.Request.Method + "1";
|
||||
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||
context.Response.CacheTtl = TimeSpan.FromSeconds(10);
|
||||
|
|
@ -693,7 +712,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
// Try to clear the cache with a second request
|
||||
responseTask = SendRequestAsync(address, method);
|
||||
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = context.Request.Method + "2";
|
||||
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||
context.Dispose();
|
||||
|
|
@ -722,9 +741,10 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
var responseTask = SendRequestAsync(address, "GET", "x-vary", "vary1");
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "1";
|
||||
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||
context.Response.Headers["vary"] = "x-vary";
|
||||
|
|
@ -753,9 +773,10 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
var responseTask = SendRequestAsync(address, "GET", "Authorization", "Basic abc123");
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "1";
|
||||
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||
context.Response.CacheTtl = TimeSpan.FromSeconds(10);
|
||||
|
|
@ -768,7 +789,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
|
||||
responseTask = SendRequestAsync(address, "GET", "Authorization", "Basic abc123");
|
||||
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "2";
|
||||
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||
context.Dispose();
|
||||
|
|
@ -787,9 +808,10 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "1";
|
||||
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||
context.Response.CacheTtl = TimeSpan.FromSeconds(10);
|
||||
|
|
@ -802,7 +824,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
|
||||
responseTask = SendRequestAsync(address, "GET", "Authorization", "Basic abc123");
|
||||
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "2";
|
||||
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||
context.Dispose();
|
||||
|
|
@ -823,9 +845,10 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
var responseTask = SendRequestAsync(address, "GET", "Pragma", "no-cache");
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "1";
|
||||
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||
context.Response.CacheTtl = TimeSpan.FromSeconds(10);
|
||||
|
|
@ -852,9 +875,10 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "1";
|
||||
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||
context.Response.CacheTtl = TimeSpan.FromSeconds(10);
|
||||
|
|
@ -880,9 +904,10 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
var responseTask = SendRequestAsync(address, "GET", "Cache-Control", "no-cache");
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "1";
|
||||
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||
context.Response.CacheTtl = TimeSpan.FromSeconds(10);
|
||||
|
|
@ -908,9 +933,10 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "1";
|
||||
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||
context.Response.CacheTtl = TimeSpan.FromSeconds(10);
|
||||
|
|
@ -936,9 +962,10 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "1";
|
||||
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||
context.Response.CacheTtl = TimeSpan.FromSeconds(10);
|
||||
|
|
@ -964,9 +991,10 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "1";
|
||||
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||
context.Response.CacheTtl = TimeSpan.FromSeconds(10);
|
||||
|
|
@ -991,9 +1019,10 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
var responseTask = SendRequestAsync(address, "GET", "Range", "bytes=0-10");
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.StatusCode = 206;
|
||||
context.Response.Headers["x-request-count"] = "1";
|
||||
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||
|
|
@ -1010,7 +1039,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
|
||||
responseTask = SendRequestAsync(address, "GET", "Range", "bytes=0-10");
|
||||
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.StatusCode = 206;
|
||||
context.Response.Headers["x-request-count"] = "2";
|
||||
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||
|
|
@ -1035,9 +1064,10 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "1";
|
||||
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||
context.Response.ContentLength = 100;
|
||||
|
|
@ -1065,9 +1095,10 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "1";
|
||||
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||
context.Response.ContentLength = 100;
|
||||
|
|
@ -1093,10 +1124,11 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
var responseLength = _fileLength / 2; // Make sure it handles partial files.
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "1";
|
||||
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||
context.Response.ContentLength = responseLength;
|
||||
|
|
@ -1125,10 +1157,11 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
var responseLength = _fileLength / 2; // Make sure it handles partial files.
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.Headers["x-request-count"] = "1";
|
||||
context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache
|
||||
context.Response.ContentLength = responseLength;
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
{
|
||||
Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Dispose();
|
||||
|
||||
HttpResponseMessage response = await responseTask;
|
||||
|
|
@ -53,7 +53,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
{
|
||||
Task<HttpResponseMessage> responseTask = SendRequestAsync(address, usehttp11: false);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Dispose();
|
||||
|
||||
HttpResponseMessage response = await responseTask;
|
||||
|
|
@ -76,7 +76,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
{
|
||||
Task<HttpResponseMessage> responseTask = SendHeadRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Dispose();
|
||||
|
||||
HttpResponseMessage response = await responseTask;
|
||||
|
|
@ -104,7 +104,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
{
|
||||
Task<HttpResponseMessage> responseTask = SendHeadRequestAsync(address, usehttp11: false);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Dispose();
|
||||
|
||||
HttpResponseMessage response = await responseTask;
|
||||
|
|
@ -119,7 +119,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
|
||||
// Send a second request to check that the connection wasn't corrupted.
|
||||
responseTask = SendHeadRequestAsync(address);
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Dispose();
|
||||
response = await responseTask;
|
||||
}
|
||||
|
|
@ -133,7 +133,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
{
|
||||
Task<HttpResponseMessage> responseTask = SendHeadRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.ContentLength = 20;
|
||||
context.Dispose();
|
||||
|
||||
|
|
@ -148,7 +148,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
|
||||
// Send a second request to check that the connection wasn't corrupted.
|
||||
responseTask = SendHeadRequestAsync(address);
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Dispose();
|
||||
response = await responseTask;
|
||||
}
|
||||
|
|
@ -162,7 +162,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
{
|
||||
Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.StatusCode = 204; // No Content
|
||||
context.Dispose();
|
||||
|
||||
|
|
@ -185,7 +185,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
{
|
||||
Task<HttpResponseMessage> responseTask = SendHeadRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Response.StatusCode = 204; // No Content
|
||||
context.Dispose();
|
||||
|
||||
|
|
@ -200,169 +200,12 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
|
||||
// Send a second request to check that the connection wasn't corrupted.
|
||||
responseTask = SendHeadRequestAsync(address);
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Dispose();
|
||||
response = await responseTask;
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ResponseHeaders_ServerSendsSingleValueKnownHeaders_Success()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
WebRequest request = WebRequest.Create(address);
|
||||
Task<WebResponse> responseTask = request.GetResponseAsync();
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var responseHeaders = context.Response.Headers;
|
||||
responseHeaders["WWW-Authenticate"] = "custom1";
|
||||
context.Dispose();
|
||||
|
||||
// HttpClient would merge the headers no matter what
|
||||
HttpWebResponse response = (HttpWebResponse)await responseTask;
|
||||
Assert.Equal(4, response.Headers.Count);
|
||||
Assert.Null(response.Headers["Transfer-Encoding"]);
|
||||
Assert.Equal(0, response.ContentLength);
|
||||
Assert.NotNull(response.Headers["Date"]);
|
||||
Assert.Equal("Microsoft-HTTPAPI/2.0", response.Headers["Server"]);
|
||||
Assert.Equal("custom1", response.Headers["WWW-Authenticate"]);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ResponseHeaders_ServerSendsMultiValueKnownHeaders_Success()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
WebRequest request = WebRequest.Create(address);
|
||||
Task<WebResponse> responseTask = request.GetResponseAsync();
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var responseHeaders = context.Response.Headers;
|
||||
responseHeaders["WWW-Authenticate"] = new[] { "custom1, and custom2", "custom3" };
|
||||
context.Dispose();
|
||||
|
||||
// HttpClient would merge the headers no matter what
|
||||
HttpWebResponse response = (HttpWebResponse)await responseTask;
|
||||
Assert.Equal(4, response.Headers.Count);
|
||||
Assert.Null(response.Headers["Transfer-Encoding"]);
|
||||
Assert.Equal(0, response.ContentLength);
|
||||
Assert.NotNull(response.Headers["Date"]);
|
||||
Assert.Equal("Microsoft-HTTPAPI/2.0", response.Headers["Server"]);
|
||||
#if NETCOREAPP2_0 || NETCOREAPP2_1 // WebHeaderCollection.GetValues() not available in CoreCLR.
|
||||
Assert.Equal("custom1, and custom2, custom3", response.Headers["WWW-Authenticate"]);
|
||||
#elif NET461
|
||||
Assert.Equal(new string[] { "custom1, and custom2", "custom3" }, response.Headers.GetValues("WWW-Authenticate"));
|
||||
#else
|
||||
#error Target framework needs to be updated
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ResponseHeaders_ServerSendsCustomHeaders_Success()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
WebRequest request = WebRequest.Create(address);
|
||||
Task<WebResponse> responseTask = request.GetResponseAsync();
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var responseHeaders = context.Response.Headers;
|
||||
responseHeaders["Custom-Header1"] = new[] { "custom1, and custom2", "custom3" };
|
||||
context.Dispose();
|
||||
|
||||
// HttpClient would merge the headers no matter what
|
||||
HttpWebResponse response = (HttpWebResponse)await responseTask;
|
||||
Assert.Equal(4, response.Headers.Count);
|
||||
Assert.Null(response.Headers["Transfer-Encoding"]);
|
||||
Assert.Equal(0, response.ContentLength);
|
||||
Assert.NotNull(response.Headers["Date"]);
|
||||
Assert.Equal("Microsoft-HTTPAPI/2.0", response.Headers["Server"]);
|
||||
#if NETCOREAPP2_0 || NETCOREAPP2_1 // WebHeaderCollection.GetValues() not available in CoreCLR.
|
||||
Assert.Equal("custom1, and custom2, custom3", response.Headers["Custom-Header1"]);
|
||||
#elif NET461
|
||||
Assert.Equal(new string[] { "custom1, and custom2", "custom3" }, response.Headers.GetValues("Custom-Header1"));
|
||||
#else
|
||||
#error Target framework needs to be updated
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ResponseHeaders_ServerSendsConnectionClose_Closed()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var responseHeaders = context.Response.Headers;
|
||||
responseHeaders["Connection"] = "Close";
|
||||
context.Dispose();
|
||||
|
||||
HttpResponseMessage response = await responseTask;
|
||||
response.EnsureSuccessStatusCode();
|
||||
Assert.True(response.Headers.ConnectionClose.Value);
|
||||
Assert.Equal(new string[] { "close" }, response.Headers.GetValues("Connection"));
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ResponseHeaders_HTTP10Request_Gets11Close()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
Task<HttpResponseMessage> responseTask = SendRequestAsync(address, usehttp11: false);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context.Dispose();
|
||||
|
||||
HttpResponseMessage response = await responseTask;
|
||||
response.EnsureSuccessStatusCode();
|
||||
Assert.Equal(new Version(1, 1), response.Version);
|
||||
Assert.True(response.Headers.ConnectionClose.Value);
|
||||
Assert.Equal(new string[] { "close" }, response.Headers.GetValues("Connection"));
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ResponseHeaders_HTTP10Request_AllowsManualChunking()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
using (HttpClient client = new HttpClient())
|
||||
{
|
||||
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, address);
|
||||
request.Version = new Version(1, 0);
|
||||
Task<HttpResponseMessage> responseTask = client.SendAsync(request);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var responseHeaders = context.Response.Headers;
|
||||
responseHeaders["Transfer-Encoding"] = "chunked";
|
||||
var responseBytes = Encoding.ASCII.GetBytes("10\r\nManually Chunked\r\n0\r\n\r\n");
|
||||
await context.Response.Body.WriteAsync(responseBytes, 0, responseBytes.Length);
|
||||
context.Dispose();
|
||||
|
||||
HttpResponseMessage response = await responseTask;
|
||||
response.EnsureSuccessStatusCode();
|
||||
Assert.Equal(new Version(1, 1), response.Version);
|
||||
Assert.True(response.Headers.TransferEncodingChunked.Value);
|
||||
Assert.False(response.Content.Headers.Contains("Content-Length"));
|
||||
Assert.True(response.Headers.ConnectionClose.Value);
|
||||
Assert.Equal(new string[] { "close" }, response.Headers.GetValues("Connection"));
|
||||
Assert.Equal("Manually Chunked", await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ResponseHeaders_HTTP10KeepAliveRequest_Gets11Close()
|
||||
{
|
||||
|
|
@ -372,7 +215,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
// Http.Sys does not support 1.0 keep-alives.
|
||||
Task<HttpResponseMessage> responseTask = SendRequestAsync(address, usehttp11: false, sendKeepAlive: true);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Dispose();
|
||||
|
||||
HttpResponseMessage response = await responseTask;
|
||||
|
|
@ -382,79 +225,6 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task Headers_FlushSendsHeaders_Success()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
|
||||
|
||||
server.Options.AllowSynchronousIO = true;
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var responseHeaders = context.Response.Headers;
|
||||
|
||||
responseHeaders["Custom1"] = new[] { "value1a", "value1b" };
|
||||
responseHeaders["Custom2"] = "value2a, value2b";
|
||||
var body = context.Response.Body;
|
||||
Assert.False(context.Response.HasStarted);
|
||||
body.Flush();
|
||||
Assert.True(context.Response.HasStarted);
|
||||
var ex = Assert.Throws<InvalidOperationException>(() => context.Response.StatusCode = 404);
|
||||
Assert.Equal("Headers already sent.", ex.Message);
|
||||
ex = Assert.Throws<InvalidOperationException>(() => responseHeaders.Add("Custom3", new string[] { "value3a, value3b", "value3c" }));
|
||||
Assert.Equal("The response headers cannot be modified because the response has already started.", ex.Message);
|
||||
|
||||
context.Dispose();
|
||||
|
||||
HttpResponseMessage response = await responseTask;
|
||||
response.EnsureSuccessStatusCode();
|
||||
Assert.Equal(5, response.Headers.Count()); // Date, Server, Chunked
|
||||
|
||||
Assert.Equal(2, response.Headers.GetValues("Custom1").Count());
|
||||
Assert.Equal("value1a", response.Headers.GetValues("Custom1").First());
|
||||
Assert.Equal("value1b", response.Headers.GetValues("Custom1").Skip(1).First());
|
||||
Assert.Single(response.Headers.GetValues("Custom2"));
|
||||
Assert.Equal("value2a, value2b", response.Headers.GetValues("Custom2").First());
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task Headers_FlushAsyncSendsHeaders_Success()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var responseHeaders = context.Response.Headers;
|
||||
|
||||
responseHeaders["Custom1"] = new[] { "value1a", "value1b" };
|
||||
responseHeaders["Custom2"] = "value2a, value2b";
|
||||
var body = context.Response.Body;
|
||||
Assert.False(context.Response.HasStarted);
|
||||
await body.FlushAsync();
|
||||
Assert.True(context.Response.HasStarted);
|
||||
var ex = Assert.Throws<InvalidOperationException>(() => context.Response.StatusCode = 404);
|
||||
Assert.Equal("Headers already sent.", ex.Message);
|
||||
ex = Assert.Throws<InvalidOperationException>(() => responseHeaders.Add("Custom3", new string[] { "value3a, value3b", "value3c" }));
|
||||
Assert.Equal("The response headers cannot be modified because the response has already started.", ex.Message);
|
||||
|
||||
context.Dispose();
|
||||
|
||||
HttpResponseMessage response = await responseTask;
|
||||
response.EnsureSuccessStatusCode();
|
||||
Assert.Equal(5, response.Headers.Count()); // Date, Server, Chunked
|
||||
|
||||
Assert.Equal(2, response.Headers.GetValues("Custom1").Count());
|
||||
Assert.Equal("value1a", response.Headers.GetValues("Custom1").First());
|
||||
Assert.Equal("value1b", response.Headers.GetValues("Custom1").Skip(1).First());
|
||||
Assert.Single(response.Headers.GetValues("Custom2"));
|
||||
Assert.Equal("value2a, value2b", response.Headers.GetValues("Custom2").First());
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData("Server", "\r\nData")]
|
||||
[InlineData("Server", "\0Data")]
|
||||
|
|
@ -481,7 +251,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
{
|
||||
Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
|
||||
var responseHeaders = context.Response.Headers;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
|
|
@ -26,187 +26,6 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
FileLength = new FileInfo(AbsoluteFilePath).Length;
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ResponseSendFile_MissingFile_Throws()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
await Assert.ThrowsAsync<FileNotFoundException>(() =>
|
||||
context.Response.SendFileAsync("Missing.txt", 0, null, CancellationToken.None));
|
||||
context.Dispose();
|
||||
|
||||
var response = await responseTask;
|
||||
response.EnsureSuccessStatusCode();
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ResponseSendFile_NoHeaders_DefaultsToChunked()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
await context.Response.SendFileAsync(AbsoluteFilePath, 0, null, CancellationToken.None);
|
||||
context.Dispose();
|
||||
|
||||
var response = await responseTask;
|
||||
Assert.Equal(200, (int)response.StatusCode);
|
||||
IEnumerable<string> ignored;
|
||||
Assert.False(response.Content.Headers.TryGetValues("content-length", out ignored), "Content-Length");
|
||||
Assert.True(response.Headers.TransferEncodingChunked.Value, "Chunked");
|
||||
Assert.Equal(FileLength, (await response.Content.ReadAsByteArrayAsync()).Length);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ResponseSendFile_RelativeFile_Success()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
await context.Response.SendFileAsync(RelativeFilePath, 0, null, CancellationToken.None);
|
||||
context.Dispose();
|
||||
|
||||
var response = await responseTask;
|
||||
Assert.Equal(200, (int)response.StatusCode);
|
||||
IEnumerable<string> ignored;
|
||||
Assert.False(response.Content.Headers.TryGetValues("content-length", out ignored), "Content-Length");
|
||||
Assert.True(response.Headers.TransferEncodingChunked.Value, "Chunked");
|
||||
Assert.Equal(FileLength, (await response.Content.ReadAsByteArrayAsync()).Length);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ResponseSendFile_Unspecified_Chunked()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
await context.Response.SendFileAsync(AbsoluteFilePath, 0, null, CancellationToken.None);
|
||||
context.Dispose();
|
||||
|
||||
var response = await responseTask;
|
||||
Assert.Equal(200, (int)response.StatusCode);
|
||||
IEnumerable<string> contentLength;
|
||||
Assert.False(response.Content.Headers.TryGetValues("content-length", out contentLength), "Content-Length");
|
||||
Assert.True(response.Headers.TransferEncodingChunked.Value);
|
||||
Assert.Equal(FileLength, (await response.Content.ReadAsByteArrayAsync()).Length);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ResponseSendFile_MultipleWrites_Chunked()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
await context.Response.SendFileAsync(AbsoluteFilePath, 0, null, CancellationToken.None);
|
||||
await context.Response.SendFileAsync(AbsoluteFilePath, 0, null, CancellationToken.None);
|
||||
context.Dispose();
|
||||
|
||||
var response = await responseTask;
|
||||
Assert.Equal(200, (int)response.StatusCode);
|
||||
IEnumerable<string> contentLength;
|
||||
Assert.False(response.Content.Headers.TryGetValues("content-length", out contentLength), "Content-Length");
|
||||
Assert.True(response.Headers.TransferEncodingChunked.Value);
|
||||
Assert.Equal(FileLength * 2, (await response.Content.ReadAsByteArrayAsync()).Length);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ResponseSendFile_HalfOfFile_Chunked()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
await context.Response.SendFileAsync(AbsoluteFilePath, 0, FileLength / 2, CancellationToken.None);
|
||||
context.Dispose();
|
||||
|
||||
var response = await responseTask;
|
||||
Assert.Equal(200, (int)response.StatusCode);
|
||||
IEnumerable<string> contentLength;
|
||||
Assert.False(response.Content.Headers.TryGetValues("content-length", out contentLength), "Content-Length");
|
||||
Assert.True(response.Headers.TransferEncodingChunked.Value);
|
||||
Assert.Equal(FileLength / 2, (await response.Content.ReadAsByteArrayAsync()).Length);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ResponseSendFile_OffsetOutOfRange_Throws()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
await Assert.ThrowsAsync<ArgumentOutOfRangeException>(
|
||||
() => context.Response.SendFileAsync(AbsoluteFilePath, 1234567, null, CancellationToken.None));
|
||||
context.Dispose();
|
||||
|
||||
var response = await responseTask;
|
||||
response.EnsureSuccessStatusCode();
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ResponseSendFile_CountOutOfRange_Throws()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
await Assert.ThrowsAsync<ArgumentOutOfRangeException>(
|
||||
() => context.Response.SendFileAsync(AbsoluteFilePath, 0, 1234567, CancellationToken.None));
|
||||
context.Dispose();
|
||||
|
||||
var response = await responseTask;
|
||||
response.EnsureSuccessStatusCode();
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ResponseSendFile_Count0_Chunked()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
await context.Response.SendFileAsync(AbsoluteFilePath, 0, 0, CancellationToken.None);
|
||||
context.Dispose();
|
||||
|
||||
var response = await responseTask;
|
||||
Assert.Equal(200, (int)response.StatusCode);
|
||||
IEnumerable<string> contentLength;
|
||||
Assert.False(response.Content.Headers.TryGetValues("content-length", out contentLength), "Content-Length");
|
||||
Assert.True(response.Headers.TransferEncodingChunked.Value);
|
||||
Assert.Empty((await response.Content.ReadAsByteArrayAsync()));
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ResponseSendFile_EmptyFileCountUnspecified_SetsChunkedAndFlushesHeaders()
|
||||
{
|
||||
|
|
@ -219,7 +38,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
{
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
await context.Response.SendFileAsync(emptyFilePath, 0, null, CancellationToken.None);
|
||||
Assert.True(context.Response.HasStarted);
|
||||
await context.Response.Body.WriteAsync(new byte[10], 0, 10, CancellationToken.None);
|
||||
|
|
@ -235,74 +54,6 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ResponseSendFile_ContentLength_PassedThrough()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context.Response.Headers["Content-lenGth"] = FileLength.ToString();
|
||||
await context.Response.SendFileAsync(AbsoluteFilePath, 0, null, CancellationToken.None);
|
||||
|
||||
var response = await responseTask;
|
||||
Assert.Equal(200, (int)response.StatusCode);
|
||||
IEnumerable<string> contentLength;
|
||||
Assert.True(response.Content.Headers.TryGetValues("content-length", out contentLength), "Content-Length");
|
||||
Assert.Equal(FileLength.ToString(), contentLength.First());
|
||||
Assert.Null(response.Headers.TransferEncodingChunked);
|
||||
Assert.Equal(FileLength, (await response.Content.ReadAsByteArrayAsync()).Length);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ResponseSendFile_ContentLengthSpecific_PassedThrough()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context.Response.Headers["Content-lenGth"] = "10";
|
||||
await context.Response.SendFileAsync(AbsoluteFilePath, 0, 10, CancellationToken.None);
|
||||
context.Dispose();
|
||||
|
||||
var response = await responseTask;
|
||||
Assert.Equal(200, (int)response.StatusCode);
|
||||
IEnumerable<string> contentLength;
|
||||
Assert.True(response.Content.Headers.TryGetValues("content-length", out contentLength), "Content-Length");
|
||||
Assert.Equal("10", contentLength.First());
|
||||
Assert.Null(response.Headers.TransferEncodingChunked);
|
||||
Assert.Equal(10, (await response.Content.ReadAsByteArrayAsync()).Length);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ResponseSendFile_ContentLength0_PassedThrough()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context.Response.Headers["Content-lenGth"] = "0";
|
||||
await context.Response.SendFileAsync(AbsoluteFilePath, 0, 0, CancellationToken.None);
|
||||
context.Dispose();
|
||||
|
||||
var response = await responseTask;
|
||||
Assert.Equal(200, (int)response.StatusCode);
|
||||
IEnumerable<string> contentLength;
|
||||
Assert.True(response.Content.Headers.TryGetValues("content-length", out contentLength), "Content-Length");
|
||||
Assert.Equal("0", contentLength.First());
|
||||
Assert.Null(response.Headers.TransferEncodingChunked);
|
||||
Assert.Empty((await response.Content.ReadAsByteArrayAsync()));
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ResponseSendFile_WithActiveCancellationToken_Success()
|
||||
{
|
||||
|
|
@ -311,7 +62,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
{
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
var cts = new CancellationTokenSource();
|
||||
// First write sends headers
|
||||
await context.Response.SendFileAsync(AbsoluteFilePath, 0, null, cts.Token);
|
||||
|
|
@ -332,7 +83,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
{
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
var cts = new CancellationTokenSource();
|
||||
cts.CancelAfter(TimeSpan.FromSeconds(10));
|
||||
// First write sends headers
|
||||
|
|
@ -355,23 +106,23 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
server.Options.ThrowWriteExceptions = true;
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
var cts = new CancellationTokenSource();
|
||||
cts.Cancel();
|
||||
// First write sends headers
|
||||
var writeTask = context.Response.SendFileAsync(AbsoluteFilePath, 0, null, cts.Token);
|
||||
Assert.True(writeTask.IsCanceled);
|
||||
context.Dispose();
|
||||
#if NET461
|
||||
#if NET472
|
||||
// .NET HttpClient automatically retries a request if it does not get a response.
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
cts = new CancellationTokenSource();
|
||||
cts.Cancel();
|
||||
// First write sends headers
|
||||
writeTask = context.Response.SendFileAsync(AbsoluteFilePath, 0, null, cts.Token);
|
||||
Assert.True(writeTask.IsCanceled);
|
||||
context.Dispose();
|
||||
#elif NETCOREAPP2_0 || NETCOREAPP2_1
|
||||
#elif NETCOREAPP2_2
|
||||
#else
|
||||
#error Target framework needs to be updated
|
||||
#endif
|
||||
|
|
@ -387,23 +138,23 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
{
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
var cts = new CancellationTokenSource();
|
||||
cts.Cancel();
|
||||
// First write sends headers
|
||||
var writeTask = context.Response.SendFileAsync(AbsoluteFilePath, 0, null, cts.Token);
|
||||
Assert.True(writeTask.IsCanceled);
|
||||
context.Dispose();
|
||||
#if NET461
|
||||
#if NET472
|
||||
// .NET HttpClient automatically retries a request if it does not get a response.
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
cts = new CancellationTokenSource();
|
||||
cts.Cancel();
|
||||
// First write sends headers
|
||||
writeTask = context.Response.SendFileAsync(AbsoluteFilePath, 0, null, cts.Token);
|
||||
Assert.True(writeTask.IsCanceled);
|
||||
context.Dispose();
|
||||
#elif NETCOREAPP2_0 || NETCOREAPP2_1
|
||||
#elif NETCOREAPP2_2
|
||||
#else
|
||||
#error Target framework needs to be updated
|
||||
#endif
|
||||
|
|
@ -420,7 +171,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
server.Options.ThrowWriteExceptions = true;
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
var cts = new CancellationTokenSource();
|
||||
// First write sends headers
|
||||
await context.Response.SendFileAsync(AbsoluteFilePath, 0, null, cts.Token);
|
||||
|
|
@ -441,7 +192,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
{
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
var cts = new CancellationTokenSource();
|
||||
// First write sends headers
|
||||
await context.Response.SendFileAsync(AbsoluteFilePath, 0, null, cts.Token);
|
||||
|
|
@ -464,7 +215,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
var cts = new CancellationTokenSource();
|
||||
var responseTask = SendRequestAsync(address, cts.Token);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
|
||||
// First write sends headers
|
||||
cts.Cancel();
|
||||
|
|
@ -496,7 +247,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
var cts = new CancellationTokenSource();
|
||||
var responseTask = SendRequestAsync(address, cts.Token);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
// First write sends headers
|
||||
cts.Cancel();
|
||||
await Assert.ThrowsAnyAsync<OperationCanceledException>(() => responseTask);
|
||||
|
|
@ -522,7 +273,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
{
|
||||
var responseTask = client.GetAsync(address, HttpCompletionOption.ResponseHeadersRead);
|
||||
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
// First write sends headers
|
||||
var sendFileTask = context.Response.SendFileAsync(AbsoluteFilePath, 0, null, CancellationToken.None);
|
||||
|
||||
|
|
@ -559,7 +310,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
{
|
||||
var responseTask = client.GetAsync(address, HttpCompletionOption.ResponseHeadersRead);
|
||||
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
// First write sends headers
|
||||
var sendFileTask = context.Response.SendFileAsync(AbsoluteFilePath, 0, null, CancellationToken.None);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,137 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
||||
{
|
||||
public class ResponseTests
|
||||
{
|
||||
[ConditionalFact]
|
||||
public async Task Response_ServerSendsDefaultResponse_ServerProvidesStatusCodeAndReasonPhrase()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
Assert.Equal(200, context.Response.StatusCode);
|
||||
context.Dispose();
|
||||
|
||||
HttpResponseMessage response = await responseTask;
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("OK", response.ReasonPhrase);
|
||||
Assert.Equal(new Version(1, 1), response.Version);
|
||||
Assert.Equal(string.Empty, await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task Response_ServerSendsSpecificStatus_ServerProvidesReasonPhrase()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context.Response.StatusCode = 201;
|
||||
// TODO: env["owin.ResponseProtocol"] = "HTTP/1.0"; // Http.Sys ignores this value
|
||||
context.Dispose();
|
||||
|
||||
HttpResponseMessage response = await responseTask;
|
||||
Assert.Equal(201, (int)response.StatusCode);
|
||||
Assert.Equal("Created", response.ReasonPhrase);
|
||||
Assert.Equal(new Version(1, 1), response.Version);
|
||||
Assert.Equal(string.Empty, await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task Response_ServerSendsSpecificStatusAndReasonPhrase_PassedThrough()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context.Response.StatusCode = 201;
|
||||
context.Response.ReasonPhrase = "CustomReasonPhrase";
|
||||
// TODO: env["owin.ResponseProtocol"] = "HTTP/1.0"; // Http.Sys ignores this value
|
||||
context.Dispose();
|
||||
|
||||
HttpResponseMessage response = await responseTask;
|
||||
Assert.Equal(201, (int)response.StatusCode);
|
||||
Assert.Equal("CustomReasonPhrase", response.ReasonPhrase);
|
||||
Assert.Equal(new Version(1, 1), response.Version);
|
||||
Assert.Equal(string.Empty, await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task Response_ServerSendsCustomStatus_NoReasonPhrase()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context.Response.StatusCode = 901;
|
||||
context.Dispose();
|
||||
|
||||
HttpResponseMessage response = await responseTask;
|
||||
Assert.Equal(901, (int)response.StatusCode);
|
||||
Assert.Equal(string.Empty, response.ReasonPhrase);
|
||||
Assert.Equal(string.Empty, await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task Response_100_Throws()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
Assert.Throws<ArgumentOutOfRangeException>(() => { context.Response.StatusCode = 100; });
|
||||
context.Dispose();
|
||||
|
||||
HttpResponseMessage response = await responseTask;
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task Response_0_Throws()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
Task<HttpResponseMessage> responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
Assert.Throws<ArgumentOutOfRangeException>(() => { context.Response.StatusCode = 0; });
|
||||
context.Dispose();
|
||||
|
||||
HttpResponseMessage response = await responseTask;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<HttpResponseMessage> SendRequestAsync(string uri)
|
||||
{
|
||||
using (HttpClient client = new HttpClient())
|
||||
{
|
||||
return await client.GetAsync(uri);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -16,93 +16,6 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
{
|
||||
public class ServerTests
|
||||
{
|
||||
[ConditionalFact]
|
||||
public async Task Server_200OK_Success()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context.Dispose();
|
||||
|
||||
var response = await responseTask;
|
||||
Assert.Equal(string.Empty, response);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task Server_SendHelloWorld_Success()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
Task<string> responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context.Response.ContentLength = 11;
|
||||
var writer = new StreamWriter(context.Response.Body);
|
||||
await writer.WriteAsync("Hello World");
|
||||
await writer.FlushAsync();
|
||||
|
||||
string response = await responseTask;
|
||||
Assert.Equal("Hello World", response);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task Server_EchoHelloWorld_Success()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
var responseTask = SendRequestAsync(address, "Hello World");
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var input = await new StreamReader(context.Request.Body).ReadToEndAsync();
|
||||
Assert.Equal("Hello World", input);
|
||||
context.Response.ContentLength = 11;
|
||||
var writer = new StreamWriter(context.Response.Body);
|
||||
await writer.WriteAsync("Hello World");
|
||||
await writer.FlushAsync();
|
||||
|
||||
var response = await responseTask;
|
||||
Assert.Equal("Hello World", response);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task Server_ClientDisconnects_CallCanceled()
|
||||
{
|
||||
var interval = TimeSpan.FromSeconds(1);
|
||||
var canceled = new ManualResetEvent(false);
|
||||
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
using (var client = new HttpClient())
|
||||
{
|
||||
var responseTask = client.GetAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var ct = context.DisconnectToken;
|
||||
Assert.True(ct.CanBeCanceled, "CanBeCanceled");
|
||||
Assert.False(ct.IsCancellationRequested, "IsCancellationRequested");
|
||||
ct.Register(() => canceled.Set());
|
||||
|
||||
client.CancelPendingRequests();
|
||||
|
||||
Assert.True(canceled.WaitOne(interval), "canceled");
|
||||
Assert.True(ct.IsCancellationRequested, "IsCancellationRequested");
|
||||
|
||||
await Assert.ThrowsAnyAsync<OperationCanceledException>(() => responseTask);
|
||||
|
||||
context.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task Server_TokenRegisteredAfterClientDisconnects_CallCanceled()
|
||||
{
|
||||
|
|
@ -116,7 +29,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
{
|
||||
var responseTask = client.GetAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
|
||||
client.CancelPendingRequests();
|
||||
await Assert.ThrowsAnyAsync<OperationCanceledException>(() => responseTask);
|
||||
|
|
@ -147,7 +60,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
{
|
||||
var responseTask = client.GetAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Dispose();
|
||||
|
||||
var response = await responseTask;
|
||||
|
|
@ -165,37 +78,6 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task Server_Abort_CallCanceled()
|
||||
{
|
||||
var interval = TimeSpan.FromSeconds(1);
|
||||
var canceled = new ManualResetEvent(false);
|
||||
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var ct = context.DisconnectToken;
|
||||
Assert.True(ct.CanBeCanceled, "CanBeCanceled");
|
||||
Assert.False(ct.IsCancellationRequested, "IsCancellationRequested");
|
||||
ct.Register(() => canceled.Set());
|
||||
context.Abort();
|
||||
Assert.True(canceled.WaitOne(interval), "Aborted");
|
||||
Assert.True(ct.IsCancellationRequested, "IsCancellationRequested");
|
||||
#if NET461
|
||||
// HttpClient re-tries the request because it doesn't know if the request was received.
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context.Abort();
|
||||
#elif NETCOREAPP2_0 || NETCOREAPP2_1
|
||||
#else
|
||||
#error Target framework needs to be updated
|
||||
#endif
|
||||
await Assert.ThrowsAsync<HttpRequestException>(() => responseTask);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task Server_ConnectionCloseHeader_CancellationTokenFires()
|
||||
{
|
||||
|
|
@ -207,7 +89,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
{
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
var ct = context.DisconnectToken;
|
||||
Assert.True(ct.CanBeCanceled, "CanBeCanceled");
|
||||
Assert.False(ct.IsCancellationRequested, "IsCancellationRequested");
|
||||
|
|
@ -228,23 +110,6 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task Server_SetQueueLimit_Success()
|
||||
{
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
{
|
||||
server.Options.RequestQueueLimit = 1001;
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context.Dispose();
|
||||
|
||||
var response = await responseTask;
|
||||
Assert.Equal(string.Empty, response);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task Server_SetRejectionVerbosityLevel_Success()
|
||||
{
|
||||
|
|
@ -253,7 +118,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
server.Options.Http503Verbosity = Http503VerbosityLevel.Limited;
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
context.Dispose();
|
||||
|
||||
var response = await responseTask;
|
||||
|
|
@ -269,7 +134,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
{
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
Assert.Equal(string.Empty, context.Request.PathBase);
|
||||
Assert.Equal("/", context.Request.Path);
|
||||
context.Dispose();
|
||||
|
|
@ -282,7 +147,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
|
||||
responseTask = SendRequestAsync(address);
|
||||
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
Assert.Equal("/pathbase", context.Request.PathBase);
|
||||
Assert.Equal("/", context.Request.Path);
|
||||
context.Dispose();
|
||||
|
|
@ -302,7 +167,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
server.Options.UrlPrefixes.Add(address);
|
||||
var responseTask = SendRequestAsync(address);
|
||||
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
Assert.Equal("/pathbase", context.Request.PathBase);
|
||||
Assert.Equal("/", context.Request.Path);
|
||||
context.Dispose();
|
||||
|
|
@ -314,7 +179,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
|
||||
responseTask = SendRequestAsync(address);
|
||||
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout);
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
Assert.Equal(string.Empty, context.Request.PathBase);
|
||||
Assert.Equal("/pathbase/", context.Request.Path);
|
||||
context.Dispose();
|
||||
|
|
@ -331,15 +196,5 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
return await client.GetStringAsync(uri);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<string> SendRequestAsync(string uri, string upload)
|
||||
{
|
||||
using (HttpClient client = new HttpClient())
|
||||
{
|
||||
HttpResponseMessage response = await client.PostAsync(uri, new StringContent(upload));
|
||||
response.EnsureSuccessStatusCode();
|
||||
return await response.Content.ReadAsStringAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Internal;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
||||
|
|
@ -29,14 +28,6 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
IsWin8orLater = (Environment.OSVersion.Version >= win8Version);
|
||||
}
|
||||
|
||||
internal static HttpSysListener CreateHttpAuthServer(AuthenticationSchemes authScheme, bool allowAnonymos, out string baseAddress)
|
||||
{
|
||||
var listener = CreateHttpServer(out baseAddress);
|
||||
listener.Options.Authentication.Schemes = authScheme;
|
||||
listener.Options.Authentication.AllowAnonymous = allowAnonymos;
|
||||
return listener;
|
||||
}
|
||||
|
||||
internal static HttpSysListener CreateHttpServer(out string baseAddress)
|
||||
{
|
||||
string root;
|
||||
|
|
@ -108,5 +99,21 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
throw new TimeoutException("AcceptAsync has timed out.");
|
||||
}
|
||||
}
|
||||
|
||||
// Fail if the given response task completes before the given accept task.
|
||||
internal static async Task<RequestContext> Before<T>(this Task<RequestContext> acceptTask, Task<T> responseTask)
|
||||
{
|
||||
var completedTask = await Task.WhenAny(acceptTask, responseTask);
|
||||
|
||||
if (completedTask == acceptTask)
|
||||
{
|
||||
return await acceptTask;
|
||||
}
|
||||
else
|
||||
{
|
||||
var response = await responseTask;
|
||||
throw new InvalidOperationException("The response completed prematurely: " + response.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.FunctionalTests
|
|||
return httpContext.Response.Body.WriteAsync(new byte[10], 0, 10);
|
||||
}))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
Assert.Equal("1", await SendRequestAsync(address));
|
||||
Assert.Equal("2", await SendRequestAsync(address));
|
||||
}
|
||||
|
|
@ -44,6 +45,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.FunctionalTests
|
|||
return httpContext.Response.Body.WriteAsync(new byte[10], 0, 10);
|
||||
}))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
Assert.Equal("1", await SendRequestAsync(address));
|
||||
Assert.Equal("2", await SendRequestAsync(address));
|
||||
}
|
||||
|
|
@ -63,6 +65,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.FunctionalTests
|
|||
return httpContext.Response.Body.WriteAsync(new byte[10], 0, 10);
|
||||
}))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
Assert.Equal("1", await SendRequestAsync(address));
|
||||
Assert.Equal("1", await SendRequestAsync(address));
|
||||
}
|
||||
|
|
@ -82,6 +85,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.FunctionalTests
|
|||
return httpContext.Response.Body.WriteAsync(new byte[10], 0, 10);
|
||||
}))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
Assert.Equal("1", await SendRequestAsync(address));
|
||||
Assert.Equal("1", await SendRequestAsync(address));
|
||||
}
|
||||
|
|
@ -101,6 +105,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.FunctionalTests
|
|||
return httpContext.Response.Body.WriteAsync(new byte[10], 0, 10);
|
||||
}))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
Assert.Equal("1", await SendRequestAsync(address));
|
||||
Assert.Equal("1", await SendRequestAsync(address));
|
||||
}
|
||||
|
|
@ -121,6 +126,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.FunctionalTests
|
|||
return httpContext.Response.Body.WriteAsync(new byte[10], 0, 10);
|
||||
}))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
Assert.Equal("1", await SendRequestAsync(address));
|
||||
Assert.Equal("1", await SendRequestAsync(address));
|
||||
}
|
||||
|
|
@ -144,6 +150,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.FunctionalTests
|
|||
return httpContext.Response.Body.WriteAsync(new byte[10], 0, 10);
|
||||
}))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
Assert.Equal("1", await SendRequestAsync(address));
|
||||
Assert.Equal("2", await SendRequestAsync(address));
|
||||
}
|
||||
|
|
@ -166,6 +173,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.FunctionalTests
|
|||
return httpContext.Response.Body.WriteAsync(new byte[10], 0, 10);
|
||||
}))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
Assert.Equal("1", await SendRequestAsync(address));
|
||||
Assert.Equal("2", await SendRequestAsync(address));
|
||||
}
|
||||
|
|
@ -185,6 +193,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.FunctionalTests
|
|||
return httpContext.Response.Body.WriteAsync(new byte[10], 0, 10);
|
||||
}))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
Assert.Equal("1", await SendRequestAsync(address));
|
||||
Assert.Equal("2", await SendRequestAsync(address));
|
||||
}
|
||||
|
|
@ -205,6 +214,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.FunctionalTests
|
|||
return httpContext.Response.Body.WriteAsync(new byte[10], 0, 10);
|
||||
}))
|
||||
{
|
||||
address += Guid.NewGuid().ToString(); // Avoid cache collisions for failed tests.
|
||||
Assert.Equal("1", await SendRequestAsync(address));
|
||||
Assert.Equal("1", await SendRequestAsync(address));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,9 +81,9 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
Assert.Equal(0, response.ContentLength);
|
||||
Assert.NotNull(response.Headers["Date"]);
|
||||
Assert.Equal("Microsoft-HTTPAPI/2.0", response.Headers["Server"]);
|
||||
#if NETCOREAPP2_0 || NETCOREAPP2_1 // WebHeaderCollection.GetValues() not available in CoreCLR.
|
||||
#if NETCOREAPP2_2 // WebHeaderCollection.GetValues() not available in CoreCLR.
|
||||
Assert.Equal("custom1, and custom2, custom3", response.Headers["WWW-Authenticate"]);
|
||||
#elif NET461
|
||||
#elif NET472
|
||||
Assert.Equal(new string[] { "custom1, and custom2", "custom3" }, response.Headers.GetValues("WWW-Authenticate"));
|
||||
#else
|
||||
#error Target framework needs to be updated
|
||||
|
|
@ -111,9 +111,9 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
Assert.Equal(0, response.ContentLength);
|
||||
Assert.NotNull(response.Headers["Date"]);
|
||||
Assert.Equal("Microsoft-HTTPAPI/2.0", response.Headers["Server"]);
|
||||
#if NETCOREAPP2_0 || NETCOREAPP2_1 // WebHeaderCollection.GetValues() not available in CoreCLR.
|
||||
#if NETCOREAPP2_2 // WebHeaderCollection.GetValues() not available in CoreCLR.
|
||||
Assert.Equal("custom1, and custom2, custom3", response.Headers["Custom-Header1"]);
|
||||
#elif NET461
|
||||
#elif NET472
|
||||
Assert.Equal(new string[] { "custom1, and custom2", "custom3" }, response.Headers.GetValues("Custom-Header1"));
|
||||
#else
|
||||
#error Target framework needs to be updated
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<Project>
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<VersionPrefix>2.1.1</VersionPrefix>
|
||||
<VersionPrefix>2.2.0</VersionPrefix>
|
||||
<VersionSuffix>rtm</VersionSuffix>
|
||||
<PackageVersion Condition="'$(IsFinalBuild)' == 'true' AND '$(VersionSuffix)' == 'rtm' ">$(VersionPrefix)</PackageVersion>
|
||||
<PackageVersion Condition="'$(IsFinalBuild)' == 'true' AND '$(VersionSuffix)' != 'rtm' ">$(VersionPrefix)-$(VersionSuffix)-final</PackageVersion>
|
||||
|
|
|
|||
Loading…
Reference in New Issue