Add reset support for IIS (#24552)
This commit is contained in:
parent
8ba7c7b457
commit
6020fdef0b
|
|
@ -589,4 +589,16 @@ http_response_set_trailer(
|
||||||
IHttpResponse4* pHttpResponse = (IHttpResponse4*)pInProcessHandler->QueryHttpContext()->GetResponse();
|
IHttpResponse4* pHttpResponse = (IHttpResponse4*)pInProcessHandler->QueryHttpContext()->GetResponse();
|
||||||
return pHttpResponse->SetTrailer(pszHeaderName, pszHeaderValue, usHeaderValueLength, fReplace);
|
return pHttpResponse->SetTrailer(pszHeaderName, pszHeaderValue, usHeaderValueLength, fReplace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
||||||
|
VOID
|
||||||
|
http_reset_stream(
|
||||||
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
|
||||||
|
ULONG errorCode
|
||||||
|
)
|
||||||
|
{
|
||||||
|
IHttpResponse4* pHttpResponse = (IHttpResponse4*)pInProcessHandler->QueryHttpContext()->GetResponse();
|
||||||
|
pHttpResponse->ResetStream(errorCode);
|
||||||
|
}
|
||||||
|
|
||||||
// End of export
|
// End of export
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,8 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
|
||||||
ITlsConnectionFeature,
|
ITlsConnectionFeature,
|
||||||
IHttpBodyControlFeature,
|
IHttpBodyControlFeature,
|
||||||
IHttpMaxRequestBodySizeFeature,
|
IHttpMaxRequestBodySizeFeature,
|
||||||
IHttpResponseTrailersFeature
|
IHttpResponseTrailersFeature,
|
||||||
|
IHttpResetFeature
|
||||||
{
|
{
|
||||||
// NOTE: When feature interfaces are added to or removed from this HttpProtocol implementation,
|
// NOTE: When feature interfaces are added to or removed from this HttpProtocol implementation,
|
||||||
// then the list of `implementedFeatures` in the generated code project MUST also be updated.
|
// then the list of `implementedFeatures` in the generated code project MUST also be updated.
|
||||||
|
|
@ -394,6 +395,33 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
|
||||||
set => ResponseTrailers = value;
|
set => ResponseTrailers = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal IHttpResetFeature GetResetFeature()
|
||||||
|
{
|
||||||
|
// Check version is above 2.
|
||||||
|
if (HttpVersion >= System.Net.HttpVersion.Version20 && NativeMethods.HttpSupportTrailer(_pInProcessHandler))
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IHttpResetFeature.Reset(int errorCode)
|
||||||
|
{
|
||||||
|
if (errorCode < 0)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException("'errorCode' cannot be negative");
|
||||||
|
}
|
||||||
|
|
||||||
|
SetResetCode(errorCode);
|
||||||
|
AbortIO(clientDisconnect: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal unsafe void SetResetCode(int errorCode)
|
||||||
|
{
|
||||||
|
NativeMethods.HttpResetStream(_pInProcessHandler, (ulong)errorCode);
|
||||||
|
}
|
||||||
|
|
||||||
void IHttpResponseBodyFeature.DisableBuffering()
|
void IHttpResponseBodyFeature.DisableBuffering()
|
||||||
{
|
{
|
||||||
NativeMethods.HttpDisableBuffering(_pInProcessHandler);
|
NativeMethods.HttpDisableBuffering(_pInProcessHandler);
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
|
||||||
private static readonly Type IServerVariablesFeature = typeof(global::Microsoft.AspNetCore.Http.Features.IServerVariablesFeature);
|
private static readonly Type IServerVariablesFeature = typeof(global::Microsoft.AspNetCore.Http.Features.IServerVariablesFeature);
|
||||||
private static readonly Type IHttpMaxRequestBodySizeFeature = typeof(global::Microsoft.AspNetCore.Http.Features.IHttpMaxRequestBodySizeFeature);
|
private static readonly Type IHttpMaxRequestBodySizeFeature = typeof(global::Microsoft.AspNetCore.Http.Features.IHttpMaxRequestBodySizeFeature);
|
||||||
private static readonly Type IHttpResponseTrailersFeature = typeof(global::Microsoft.AspNetCore.Http.Features.IHttpResponseTrailersFeature);
|
private static readonly Type IHttpResponseTrailersFeature = typeof(global::Microsoft.AspNetCore.Http.Features.IHttpResponseTrailersFeature);
|
||||||
|
private static readonly Type IHttpResetFeature = typeof(global::Microsoft.AspNetCore.Http.Features.IHttpResetFeature);
|
||||||
|
|
||||||
private object _currentIHttpRequestFeature;
|
private object _currentIHttpRequestFeature;
|
||||||
private object _currentIHttpResponseFeature;
|
private object _currentIHttpResponseFeature;
|
||||||
|
|
@ -50,6 +51,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
|
||||||
private object _currentIServerVariablesFeature;
|
private object _currentIServerVariablesFeature;
|
||||||
private object _currentIHttpMaxRequestBodySizeFeature;
|
private object _currentIHttpMaxRequestBodySizeFeature;
|
||||||
private object _currentIHttpResponseTrailersFeature;
|
private object _currentIHttpResponseTrailersFeature;
|
||||||
|
private object _currentIHttpResetFeature;
|
||||||
|
|
||||||
private void Initialize()
|
private void Initialize()
|
||||||
{
|
{
|
||||||
|
|
@ -66,6 +68,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
|
||||||
_currentIHttpMaxRequestBodySizeFeature = this;
|
_currentIHttpMaxRequestBodySizeFeature = this;
|
||||||
_currentITlsConnectionFeature = this;
|
_currentITlsConnectionFeature = this;
|
||||||
_currentIHttpResponseTrailersFeature = GetResponseTrailersFeature();
|
_currentIHttpResponseTrailersFeature = GetResponseTrailersFeature();
|
||||||
|
_currentIHttpResetFeature = GetResetFeature();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal object FastFeatureGet(Type key)
|
internal object FastFeatureGet(Type key)
|
||||||
|
|
@ -154,6 +157,10 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
|
||||||
{
|
{
|
||||||
return _currentIHttpResponseTrailersFeature;
|
return _currentIHttpResponseTrailersFeature;
|
||||||
}
|
}
|
||||||
|
if (key == IHttpResetFeature)
|
||||||
|
{
|
||||||
|
return _currentIHttpResetFeature;
|
||||||
|
}
|
||||||
|
|
||||||
return ExtraFeatureGet(key);
|
return ExtraFeatureGet(key);
|
||||||
}
|
}
|
||||||
|
|
@ -260,6 +267,10 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
|
||||||
{
|
{
|
||||||
_currentIHttpResponseTrailersFeature = feature;
|
_currentIHttpResponseTrailersFeature = feature;
|
||||||
}
|
}
|
||||||
|
if (key == IHttpResetFeature)
|
||||||
|
{
|
||||||
|
_currentIHttpResetFeature = feature;
|
||||||
|
}
|
||||||
if (key == IISHttpContextType)
|
if (key == IISHttpContextType)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("Cannot set IISHttpContext in feature collection");
|
throw new InvalidOperationException("Cannot set IISHttpContext in feature collection");
|
||||||
|
|
@ -349,6 +360,10 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
|
||||||
{
|
{
|
||||||
yield return new KeyValuePair<Type, object>(IHttpResponseTrailersFeature, _currentIHttpResponseTrailersFeature as global::Microsoft.AspNetCore.Http.Features.IHttpResponseTrailersFeature);
|
yield return new KeyValuePair<Type, object>(IHttpResponseTrailersFeature, _currentIHttpResponseTrailersFeature as global::Microsoft.AspNetCore.Http.Features.IHttpResponseTrailersFeature);
|
||||||
}
|
}
|
||||||
|
if (_currentIHttpResetFeature != null)
|
||||||
|
{
|
||||||
|
yield return new KeyValuePair<Type, object>(IHttpResponseTrailersFeature, _currentIHttpResetFeature as global::Microsoft.AspNetCore.Http.Features.IHttpResetFeature);
|
||||||
|
}
|
||||||
|
|
||||||
if (MaybeExtra != null)
|
if (MaybeExtra != null)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,13 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
|
||||||
// Dispose
|
// Dispose
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!success && HasResponseStarted)
|
||||||
|
{
|
||||||
|
// HTTP/2 INTERNAL_ERROR = 0x2 https://tools.ietf.org/html/rfc7540#section-7
|
||||||
|
// Otherwise the default is Cancel = 0x8.
|
||||||
|
SetResetCode(2);
|
||||||
|
}
|
||||||
|
|
||||||
if (_onCompleted != null)
|
if (_onCompleted != null)
|
||||||
{
|
{
|
||||||
await FireOnCompleted();
|
await FireOnCompleted();
|
||||||
|
|
|
||||||
|
|
@ -146,6 +146,9 @@ namespace Microsoft.AspNetCore.Server.IIS
|
||||||
[DllImport(AspNetCoreModuleDll)]
|
[DllImport(AspNetCoreModuleDll)]
|
||||||
private static extern unsafe int http_response_set_trailer(IntPtr pInProcessHandler, byte* pszHeaderName, byte* pszHeaderValue, ushort usHeaderValueLength, bool replace);
|
private static extern unsafe int http_response_set_trailer(IntPtr pInProcessHandler, byte* pszHeaderName, byte* pszHeaderValue, ushort usHeaderValueLength, bool replace);
|
||||||
|
|
||||||
|
[DllImport(AspNetCoreModuleDll)]
|
||||||
|
private static extern unsafe int http_reset_stream(IntPtr pInProcessHandler, ulong errorCode);
|
||||||
|
|
||||||
[DllImport(AspNetCoreModuleDll)]
|
[DllImport(AspNetCoreModuleDll)]
|
||||||
private static extern unsafe int http_response_set_known_header(IntPtr pInProcessHandler, int headerId, byte* pHeaderValue, ushort length, bool fReplace);
|
private static extern unsafe int http_response_set_known_header(IntPtr pInProcessHandler, int headerId, byte* pHeaderValue, ushort length, bool fReplace);
|
||||||
|
|
||||||
|
|
@ -318,6 +321,11 @@ namespace Microsoft.AspNetCore.Server.IIS
|
||||||
Validate(http_response_set_trailer(pInProcessHandler, pHeaderName, pHeaderValue, length, false));
|
Validate(http_response_set_trailer(pInProcessHandler, pHeaderName, pHeaderValue, length, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static unsafe void HttpResetStream(IntPtr pInProcessHandler, ulong errorCode)
|
||||||
|
{
|
||||||
|
Validate(http_reset_stream(pInProcessHandler, errorCode));
|
||||||
|
}
|
||||||
|
|
||||||
internal static unsafe bool HttpSupportTrailer(IntPtr pInProcessHandler)
|
internal static unsafe bool HttpSupportTrailer(IntPtr pInProcessHandler)
|
||||||
{
|
{
|
||||||
bool supportsTrailers;
|
bool supportsTrailers;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,413 @@
|
||||||
|
// 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.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Http2Cat;
|
||||||
|
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
|
||||||
|
using Microsoft.AspNetCore.Server.IntegrationTesting.Common;
|
||||||
|
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
|
||||||
|
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2;
|
||||||
|
using Microsoft.AspNetCore.Testing;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.Net.Http.Headers;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests
|
||||||
|
{
|
||||||
|
[Collection(PublishedSitesCollection.Name)]
|
||||||
|
public class ResetTests : IISFunctionalTestBase
|
||||||
|
{
|
||||||
|
public ResetTests(PublishedSitesFixture fixture) : base(fixture)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly Version Win10_Regressed_DataFrame = new Version(10, 0, 20145, 0);
|
||||||
|
|
||||||
|
public static readonly IEnumerable<KeyValuePair<string, string>> Headers = new[]
|
||||||
|
{
|
||||||
|
new KeyValuePair<string, string>(HeaderNames.Method, "GET"),
|
||||||
|
new KeyValuePair<string, string>(HeaderNames.Scheme, "https"),
|
||||||
|
new KeyValuePair<string, string>(HeaderNames.Authority, "localhost:443"),
|
||||||
|
new KeyValuePair<string, string>("user-agent", "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:54.0) Gecko/20100101 Firefox/54.0"),
|
||||||
|
new KeyValuePair<string, string>("accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"),
|
||||||
|
new KeyValuePair<string, string>("accept-language", "en-US,en;q=0.5"),
|
||||||
|
new KeyValuePair<string, string>("accept-encoding", "gzip, deflate, br"),
|
||||||
|
new KeyValuePair<string, string>("upgrade-insecure-requests", "1"),
|
||||||
|
};
|
||||||
|
|
||||||
|
public static readonly IEnumerable<KeyValuePair<string, string>> PostRequestHeaders = new[]
|
||||||
|
{
|
||||||
|
new KeyValuePair<string, string>(HeaderNames.Method, "POST"),
|
||||||
|
new KeyValuePair<string, string>(HeaderNames.Scheme, "https"),
|
||||||
|
new KeyValuePair<string, string>(HeaderNames.Authority, "localhost:80"),
|
||||||
|
};
|
||||||
|
|
||||||
|
[ConditionalFact]
|
||||||
|
[MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10, SkipReason = "Http2 requires Win10")]
|
||||||
|
public async Task AppException_BeforeResponseHeaders_500()
|
||||||
|
{
|
||||||
|
var deploymentParameters = GetHttpsDeploymentParameters();
|
||||||
|
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||||
|
|
||||||
|
await new HostBuilder()
|
||||||
|
.UseHttp2Cat(deploymentResult.ApplicationBaseUri, async h2Connection =>
|
||||||
|
{
|
||||||
|
await h2Connection.InitializeConnectionAsync();
|
||||||
|
|
||||||
|
h2Connection.Logger.LogInformation("Initialized http2 connection. Starting stream 1.");
|
||||||
|
|
||||||
|
await h2Connection.StartStreamAsync(1, GetHeaders("/AppException_BeforeResponseHeaders_500"), endStream: true);
|
||||||
|
|
||||||
|
await h2Connection.ReceiveHeadersAsync(1, decodedHeaders =>
|
||||||
|
{
|
||||||
|
Assert.Equal("500", decodedHeaders[HeaderNames.Status]);
|
||||||
|
});
|
||||||
|
|
||||||
|
var dataFrame = await h2Connection.ReceiveFrameAsync();
|
||||||
|
if (Environment.OSVersion.Version >= Win10_Regressed_DataFrame)
|
||||||
|
{
|
||||||
|
// TODO: Remove when the regression is fixed.
|
||||||
|
// https://github.com/dotnet/aspnetcore/issues/23164#issuecomment-652646163
|
||||||
|
Http2Utilities.VerifyDataFrame(dataFrame, 1, endOfStream: false, length: 0);
|
||||||
|
|
||||||
|
dataFrame = await h2Connection.ReceiveFrameAsync();
|
||||||
|
}
|
||||||
|
Http2Utilities.VerifyDataFrame(dataFrame, 1, endOfStream: true, length: 0);
|
||||||
|
|
||||||
|
h2Connection.Logger.LogInformation("Connection stopped.");
|
||||||
|
})
|
||||||
|
.Build().RunAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
[ConditionalFact]
|
||||||
|
[MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10, SkipReason = "Http2 requires Win10")]
|
||||||
|
[MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "This is last version without custom Reset support")]
|
||||||
|
public async Task AppException_AfterHeaders_PriorOSVersions_ResetCancel()
|
||||||
|
{
|
||||||
|
var deploymentParameters = GetHttpsDeploymentParameters();
|
||||||
|
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||||
|
|
||||||
|
await new HostBuilder()
|
||||||
|
.UseHttp2Cat(deploymentResult.ApplicationBaseUri + "AppException_AfterHeaders_PriorOSVersions_ResetCancel", async h2Connection =>
|
||||||
|
{
|
||||||
|
await h2Connection.InitializeConnectionAsync();
|
||||||
|
|
||||||
|
h2Connection.Logger.LogInformation("Initialized http2 connection. Starting stream 1.");
|
||||||
|
|
||||||
|
await h2Connection.StartStreamAsync(1, GetHeaders("/AppException_AfterHeaders_PriorOSVersions_ResetCancel"), endStream: true);
|
||||||
|
|
||||||
|
await h2Connection.ReceiveHeadersAsync(1, decodedHeaders =>
|
||||||
|
{
|
||||||
|
Assert.Equal("200", decodedHeaders[HeaderNames.Status]);
|
||||||
|
});
|
||||||
|
|
||||||
|
var resetFrame = await h2Connection.ReceiveFrameAsync();
|
||||||
|
Http2Utilities.VerifyResetFrame(resetFrame, expectedStreamId: 1, Http2ErrorCode.CANCEL);
|
||||||
|
|
||||||
|
h2Connection.Logger.LogInformation("Connection stopped.");
|
||||||
|
})
|
||||||
|
.Build().RunAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
[ConditionalFact]
|
||||||
|
[MinimumOSVersion(OperatingSystems.Windows, "10.0.19529", SkipReason = "Custom Reset support was added in Win10_20H2.")]
|
||||||
|
public async Task AppException_AfterHeaders_ResetInternalError()
|
||||||
|
{
|
||||||
|
var deploymentParameters = GetHttpsDeploymentParameters();
|
||||||
|
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||||
|
|
||||||
|
await new HostBuilder()
|
||||||
|
.UseHttp2Cat(deploymentResult.ApplicationBaseUri, async h2Connection =>
|
||||||
|
{
|
||||||
|
await h2Connection.InitializeConnectionAsync();
|
||||||
|
|
||||||
|
h2Connection.Logger.LogInformation("Initialized http2 connection. Starting stream 1.");
|
||||||
|
|
||||||
|
await h2Connection.StartStreamAsync(1, GetHeaders("/AppException_AfterHeaders_ResetInternalError"), endStream: true);
|
||||||
|
|
||||||
|
await h2Connection.ReceiveHeadersAsync(1, decodedHeaders =>
|
||||||
|
{
|
||||||
|
Assert.Equal("200", decodedHeaders[HeaderNames.Status]);
|
||||||
|
});
|
||||||
|
|
||||||
|
var frame = await h2Connection.ReceiveFrameAsync();
|
||||||
|
if (Environment.OSVersion.Version >= Win10_Regressed_DataFrame)
|
||||||
|
{
|
||||||
|
// TODO: Remove when the regression is fixed.
|
||||||
|
// https://github.com/dotnet/aspnetcore/issues/23164#issuecomment-652646163
|
||||||
|
Http2Utilities.VerifyDataFrame(frame, 1, endOfStream: false, length: 0);
|
||||||
|
|
||||||
|
frame = await h2Connection.ReceiveFrameAsync();
|
||||||
|
}
|
||||||
|
Http2Utilities.VerifyResetFrame(frame, expectedStreamId: 1, Http2ErrorCode.INTERNAL_ERROR);
|
||||||
|
|
||||||
|
h2Connection.Logger.LogInformation("Connection stopped.");
|
||||||
|
})
|
||||||
|
.Build().RunAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
[ConditionalFact]
|
||||||
|
public async Task Reset_Http1_NotSupported()
|
||||||
|
{
|
||||||
|
var deploymentParameters = GetHttpsDeploymentParameters();
|
||||||
|
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||||
|
|
||||||
|
var handler = new HttpClientHandler();
|
||||||
|
handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
|
||||||
|
using HttpClient client = new HttpClient(handler);
|
||||||
|
client.DefaultRequestVersion = HttpVersion.Version11;
|
||||||
|
var response = await client.GetStringAsync(deploymentResult.ApplicationBaseUri + "Reset_Http1_NotSupported");
|
||||||
|
Assert.Equal("Hello World", response);
|
||||||
|
}
|
||||||
|
|
||||||
|
[ConditionalFact]
|
||||||
|
[MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10, SkipReason = "Http2 requires Win10")]
|
||||||
|
[MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "This is last version without Reset support")]
|
||||||
|
public async Task Reset_PriorOSVersions_NotSupported()
|
||||||
|
{
|
||||||
|
var deploymentParameters = GetHttpsDeploymentParameters();
|
||||||
|
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||||
|
|
||||||
|
var handler = new HttpClientHandler();
|
||||||
|
handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
|
||||||
|
using HttpClient client = new HttpClient(handler);
|
||||||
|
client.DefaultRequestVersion = HttpVersion.Version20;
|
||||||
|
var response = await client.GetStringAsync(deploymentResult.ApplicationBaseUri);
|
||||||
|
Assert.Equal("Hello World", response);
|
||||||
|
}
|
||||||
|
|
||||||
|
[ConditionalFact]
|
||||||
|
[MinimumOSVersion(OperatingSystems.Windows, "10.0.19529", SkipReason = "Reset support was added in Win10_20H2.")]
|
||||||
|
public async Task Reset_BeforeResponse_Resets()
|
||||||
|
{
|
||||||
|
var deploymentParameters = GetHttpsDeploymentParameters();
|
||||||
|
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||||
|
|
||||||
|
await new HostBuilder()
|
||||||
|
.UseHttp2Cat(deploymentResult.ApplicationBaseUri, async h2Connection =>
|
||||||
|
{
|
||||||
|
await h2Connection.InitializeConnectionAsync();
|
||||||
|
|
||||||
|
h2Connection.Logger.LogInformation("Initialized http2 connection. Starting stream 1.");
|
||||||
|
|
||||||
|
await h2Connection.StartStreamAsync(1, GetHeaders("/Reset_BeforeResponse_Resets"), endStream: true);
|
||||||
|
|
||||||
|
var resetFrame = await h2Connection.ReceiveFrameAsync();
|
||||||
|
Http2Utilities.VerifyResetFrame(resetFrame, expectedStreamId: 1, expectedErrorCode: (Http2ErrorCode)1111);
|
||||||
|
|
||||||
|
// Any app errors?
|
||||||
|
var client = CreateClient();
|
||||||
|
var response = await client.GetAsync(deploymentResult.ApplicationBaseUri + "/Reset_BeforeResponse_Resets_Complete");
|
||||||
|
Assert.True(response.IsSuccessStatusCode);
|
||||||
|
|
||||||
|
h2Connection.Logger.LogInformation("Connection stopped.");
|
||||||
|
})
|
||||||
|
.Build().RunAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
[ConditionalFact]
|
||||||
|
[MinimumOSVersion(OperatingSystems.Windows, "10.0.19529", SkipReason = "Reset support was added in Win10_20H2.")]
|
||||||
|
public async Task Reset_BeforeResponse_Zero_Resets()
|
||||||
|
{
|
||||||
|
var deploymentParameters = GetHttpsDeploymentParameters();
|
||||||
|
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||||
|
|
||||||
|
await new HostBuilder()
|
||||||
|
.UseHttp2Cat(deploymentResult.ApplicationBaseUri, async h2Connection =>
|
||||||
|
{
|
||||||
|
await h2Connection.InitializeConnectionAsync();
|
||||||
|
|
||||||
|
h2Connection.Logger.LogInformation("Initialized http2 connection. Starting stream 1.");
|
||||||
|
|
||||||
|
await h2Connection.StartStreamAsync(1, GetHeaders("/Reset_BeforeResponse_Zero_Resets"), endStream: true);
|
||||||
|
|
||||||
|
var resetFrame = await h2Connection.ReceiveFrameAsync();
|
||||||
|
Http2Utilities.VerifyResetFrame(resetFrame, expectedStreamId: 1, expectedErrorCode: (Http2ErrorCode)0);
|
||||||
|
|
||||||
|
// Any app errors?
|
||||||
|
var client = CreateClient();
|
||||||
|
var response = await client.GetAsync(deploymentResult.ApplicationBaseUri + "/Reset_BeforeResponse_Zero_Resets_Complete");
|
||||||
|
Assert.True(response.IsSuccessStatusCode);
|
||||||
|
|
||||||
|
h2Connection.Logger.LogInformation("Connection stopped.");
|
||||||
|
})
|
||||||
|
.Build().RunAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
[ConditionalFact]
|
||||||
|
[MinimumOSVersion(OperatingSystems.Windows, "10.0.19529", SkipReason = "Reset support was added in Win10_20H2.")]
|
||||||
|
public async Task Reset_AfterResponseHeaders_Resets()
|
||||||
|
{
|
||||||
|
var deploymentParameters = GetHttpsDeploymentParameters();
|
||||||
|
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||||
|
|
||||||
|
await new HostBuilder()
|
||||||
|
.UseHttp2Cat(deploymentResult.ApplicationBaseUri, async h2Connection =>
|
||||||
|
{
|
||||||
|
await h2Connection.InitializeConnectionAsync();
|
||||||
|
|
||||||
|
h2Connection.Logger.LogInformation("Initialized http2 connection. Starting stream 1.");
|
||||||
|
|
||||||
|
await h2Connection.StartStreamAsync(1, GetHeaders("/Reset_AfterResponseHeaders_Resets"), endStream: true);
|
||||||
|
|
||||||
|
// Any app errors?
|
||||||
|
var client = CreateClient();
|
||||||
|
var response = await client.GetAsync(deploymentResult.ApplicationBaseUri + "/Reset_AfterResponseHeaders_Resets_Complete");
|
||||||
|
Assert.True(response.IsSuccessStatusCode);
|
||||||
|
|
||||||
|
await h2Connection.ReceiveHeadersAsync(1, decodedHeaders =>
|
||||||
|
{
|
||||||
|
Assert.Equal("200", decodedHeaders[HeaderNames.Status]);
|
||||||
|
});
|
||||||
|
|
||||||
|
var dataFrame = await h2Connection.ReceiveFrameAsync();
|
||||||
|
Http2Utilities.VerifyDataFrame(dataFrame, expectedStreamId: 1, endOfStream: false, length: 0);
|
||||||
|
|
||||||
|
var resetFrame = await h2Connection.ReceiveFrameAsync();
|
||||||
|
Http2Utilities.VerifyResetFrame(resetFrame, expectedStreamId: 1, expectedErrorCode: (Http2ErrorCode)1111);
|
||||||
|
|
||||||
|
h2Connection.Logger.LogInformation("Connection stopped.");
|
||||||
|
})
|
||||||
|
.Build().RunAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
[ConditionalFact]
|
||||||
|
[MinimumOSVersion(OperatingSystems.Windows, "10.0.19529", SkipReason = "Reset support was added in Win10_20H2.")]
|
||||||
|
public async Task Reset_DuringResponseBody_Resets()
|
||||||
|
{
|
||||||
|
var deploymentParameters = GetHttpsDeploymentParameters();
|
||||||
|
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||||
|
|
||||||
|
await new HostBuilder()
|
||||||
|
.UseHttp2Cat(deploymentResult.ApplicationBaseUri, async h2Connection =>
|
||||||
|
{
|
||||||
|
await h2Connection.InitializeConnectionAsync();
|
||||||
|
|
||||||
|
h2Connection.Logger.LogInformation("Initialized http2 connection. Starting stream 1.");
|
||||||
|
|
||||||
|
await h2Connection.StartStreamAsync(1, GetHeaders("/Reset_DuringResponseBody_Resets"), endStream: true);
|
||||||
|
|
||||||
|
// This is currently flaky, can either receive header or reset at this point
|
||||||
|
var headerOrResetFrame = await h2Connection.ReceiveFrameAsync();
|
||||||
|
Assert.True(headerOrResetFrame.Type == Http2FrameType.HEADERS || headerOrResetFrame.Type == Http2FrameType.RST_STREAM);
|
||||||
|
|
||||||
|
if (headerOrResetFrame.Type == Http2FrameType.HEADERS)
|
||||||
|
{
|
||||||
|
var dataFrame = await h2Connection.ReceiveFrameAsync();
|
||||||
|
Http2Utilities.VerifyDataFrame(dataFrame, 1, endOfStream: false, length: 11);
|
||||||
|
|
||||||
|
var resetFrame = await h2Connection.ReceiveFrameAsync();
|
||||||
|
Http2Utilities.VerifyResetFrame(resetFrame, expectedStreamId: 1, expectedErrorCode: (Http2ErrorCode)1111);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Http2Utilities.VerifyResetFrame(headerOrResetFrame, expectedStreamId: 1, expectedErrorCode: (Http2ErrorCode)1111);
|
||||||
|
}
|
||||||
|
|
||||||
|
h2Connection.Logger.LogInformation("Connection stopped.");
|
||||||
|
})
|
||||||
|
.Build().RunAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[ConditionalFact]
|
||||||
|
[MinimumOSVersion(OperatingSystems.Windows, "10.0.19529", SkipReason = "Reset support was added in Win10_20H2.")]
|
||||||
|
public async Task Reset_BeforeRequestBody_Resets()
|
||||||
|
{
|
||||||
|
var deploymentParameters = GetHttpsDeploymentParameters();
|
||||||
|
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||||
|
|
||||||
|
await new HostBuilder()
|
||||||
|
.UseHttp2Cat(deploymentResult.ApplicationBaseUri, async h2Connection =>
|
||||||
|
{
|
||||||
|
await h2Connection.InitializeConnectionAsync();
|
||||||
|
|
||||||
|
h2Connection.Logger.LogInformation("Initialized http2 connection. Starting stream 1.");
|
||||||
|
|
||||||
|
await h2Connection.StartStreamAsync(1, GetPostHeaders("/Reset_BeforeRequestBody_Resets"), endStream: false);
|
||||||
|
|
||||||
|
// Any app errors?
|
||||||
|
//Assert.Equal(0, await appResult.Task.DefaultTimeout());
|
||||||
|
|
||||||
|
var resetFrame = await h2Connection.ReceiveFrameAsync();
|
||||||
|
Http2Utilities.VerifyResetFrame(resetFrame, expectedStreamId: 1, expectedErrorCode: (Http2ErrorCode)1111);
|
||||||
|
|
||||||
|
h2Connection.Logger.LogInformation("Connection stopped.");
|
||||||
|
})
|
||||||
|
.Build().RunAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
[ConditionalFact]
|
||||||
|
[MinimumOSVersion(OperatingSystems.Windows, "10.0.19529", SkipReason = "Reset support was added in Win10_20H2.")]
|
||||||
|
public async Task Reset_DuringRequestBody_Resets()
|
||||||
|
{
|
||||||
|
var deploymentParameters = GetHttpsDeploymentParameters();
|
||||||
|
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||||
|
|
||||||
|
await new HostBuilder()
|
||||||
|
.UseHttp2Cat(deploymentResult.ApplicationBaseUri, async h2Connection =>
|
||||||
|
{
|
||||||
|
await h2Connection.InitializeConnectionAsync();
|
||||||
|
|
||||||
|
h2Connection.Logger.LogInformation("Initialized http2 connection. Starting stream 1.");
|
||||||
|
|
||||||
|
await h2Connection.StartStreamAsync(1, GetPostHeaders("/Reset_DuringRequestBody_Resets"), endStream: false);
|
||||||
|
await h2Connection.SendDataAsync(1, new byte[10], endStream: false);
|
||||||
|
|
||||||
|
// Any app errors?
|
||||||
|
//Assert.Equal(0, await appResult.Task.DefaultTimeout());
|
||||||
|
|
||||||
|
var resetFrame = await h2Connection.ReceiveFrameAsync();
|
||||||
|
Http2Utilities.VerifyResetFrame(resetFrame, expectedStreamId: 1, expectedErrorCode: (Http2ErrorCode)1111);
|
||||||
|
|
||||||
|
h2Connection.Logger.LogInformation("Connection stopped.");
|
||||||
|
})
|
||||||
|
.Build().RunAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<KeyValuePair<string, string>> GetHeaders(string path)
|
||||||
|
{
|
||||||
|
var headers = Headers.ToList();
|
||||||
|
|
||||||
|
var kvp = new KeyValuePair<string, string>(HeaderNames.Path, path);
|
||||||
|
headers.Add(kvp);
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<KeyValuePair<string, string>> GetPostHeaders(string path)
|
||||||
|
{
|
||||||
|
var headers = PostRequestHeaders.ToList();
|
||||||
|
|
||||||
|
var kvp = new KeyValuePair<string, string>(HeaderNames.Path, path);
|
||||||
|
headers.Add(kvp);
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private IISDeploymentParameters GetHttpsDeploymentParameters()
|
||||||
|
{
|
||||||
|
var port = TestPortHelper.GetNextSSLPort();
|
||||||
|
var deploymentParameters = Fixture.GetBaseDeploymentParameters();
|
||||||
|
deploymentParameters.ApplicationBaseUriHint = $"https://localhost:{port}/";
|
||||||
|
deploymentParameters.AddHttpsToServerConfig();
|
||||||
|
return deploymentParameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static HttpClient CreateClient()
|
||||||
|
{
|
||||||
|
var handler = new HttpClientHandler();
|
||||||
|
handler.MaxResponseHeadersLength = 128;
|
||||||
|
handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
|
||||||
|
var client = new HttpClient(handler);
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
<TestGroupName>IIS.FunctionalTests</TestGroupName>
|
<TestGroupName>IIS.FunctionalTests</TestGroupName>
|
||||||
<DisableFastUpToDateCheck>True</DisableFastUpToDateCheck>
|
<DisableFastUpToDateCheck>True</DisableFastUpToDateCheck>
|
||||||
<SkipTests Condition=" '$(SkipIISTests)' == 'true' ">true</SkipTests>
|
<SkipTests Condition=" '$(SkipIISTests)' == 'true' ">true</SkipTests>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<Import Project="../FunctionalTest.props" />
|
<Import Project="../FunctionalTest.props" />
|
||||||
|
|
@ -19,13 +20,30 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="..\Common.FunctionalTests\**\*.cs" />
|
<Compile Include="..\Common.FunctionalTests\**\*.cs" />
|
||||||
<Compile Include="..\IIS.Shared.FunctionalTests\**\*.cs" />
|
<Compile Include="..\IIS.Shared.FunctionalTests\**\*.cs" />
|
||||||
|
<Compile Include="$(SharedSourceRoot)Http2cat\**\*.cs" LinkBase="Shared\Http2cat" />
|
||||||
|
<Compile Include="$(SharedSourceRoot)runtime\Http2\**\*.cs" LinkBase="Shared\Http2\" />
|
||||||
|
<Compile Include="$(SharedSourceRoot)runtime\IHttpHeadersHandler.cs" LinkBase="Shared\IHttpHeadersHandler.cs" />
|
||||||
|
<Compile Include="$(SharedSourceRoot)runtime\SR.cs" LinkBase="Shared\SR.cs" />
|
||||||
|
<Compile Include="$(SharedSourceRoot)ServerInfrastructure\**\*.cs" LinkBase="Shared\" />
|
||||||
|
<Compile Include="$(SharedSourceRoot)TaskToApm.cs" Link="Shared\TaskToApm.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="Microsoft.AspNetCore.Hosting" />
|
<Reference Include="Microsoft.AspNetCore.Hosting" />
|
||||||
|
<Reference Include="Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets" />
|
||||||
<Reference Include="Microsoft.Extensions.Logging" />
|
<Reference Include="Microsoft.Extensions.Logging" />
|
||||||
<Reference Include="System.Diagnostics.EventLog" />
|
<Reference Include="System.Diagnostics.EventLog" />
|
||||||
<Reference Include="System.Net.Http.WinHttpHandler" />
|
<Reference Include="System.Net.Http.WinHttpHandler" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="$(SharedSourceRoot)ServerInfrastructure\SharedStrings.resx" Link="Shared\SharedStrings.resx">
|
||||||
|
<ManifestResourceName>Microsoft.AspNetCore.Server.SharedStrings</ManifestResourceName>
|
||||||
|
<Generator></Generator>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="$(SharedSourceRoot)runtime\SR.resx" Link="Shared\runtime\SR.resx">
|
||||||
|
<ManifestResourceName>System.Net.Http.SR</ManifestResourceName>
|
||||||
|
<Generator></Generator>
|
||||||
|
</EmbeddedResource>
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
<TestGroupName>IISNewHandler.FunctionalTests</TestGroupName>
|
<TestGroupName>IISNewHandler.FunctionalTests</TestGroupName>
|
||||||
<DisableFastUpToDateCheck>True</DisableFastUpToDateCheck>
|
<DisableFastUpToDateCheck>True</DisableFastUpToDateCheck>
|
||||||
<SkipTests Condition=" '$(SkipIISNewHandlerTests)' == 'true' ">true</SkipTests>
|
<SkipTests Condition=" '$(SkipIISNewHandlerTests)' == 'true' ">true</SkipTests>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<Import Project="../FunctionalTest.props" />
|
<Import Project="../FunctionalTest.props" />
|
||||||
|
|
@ -12,6 +13,12 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="..\Common.FunctionalTests\**\*.cs" />
|
<Compile Include="..\Common.FunctionalTests\**\*.cs" />
|
||||||
<Compile Include="..\IIS.Shared.FunctionalTests\**\*.cs" />
|
<Compile Include="..\IIS.Shared.FunctionalTests\**\*.cs" />
|
||||||
|
<Compile Include="$(SharedSourceRoot)Http2cat\**\*.cs" LinkBase="Shared\Http2cat" />
|
||||||
|
<Compile Include="$(SharedSourceRoot)runtime\Http2\**\*.cs" LinkBase="Shared\Http2\" />
|
||||||
|
<Compile Include="$(SharedSourceRoot)runtime\IHttpHeadersHandler.cs" LinkBase="Shared\IHttpHeadersHandler.cs" />
|
||||||
|
<Compile Include="$(SharedSourceRoot)runtime\SR.cs" LinkBase="Shared\SR.cs" />
|
||||||
|
<Compile Include="$(SharedSourceRoot)ServerInfrastructure\**\*.cs" LinkBase="Shared\" />
|
||||||
|
<Compile Include="$(SharedSourceRoot)TaskToApm.cs" Link="Shared\TaskToApm.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
@ -30,10 +37,22 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="Microsoft.AspNetCore.Hosting" />
|
<Reference Include="Microsoft.AspNetCore.Hosting" />
|
||||||
|
<Reference Include="Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets" />
|
||||||
<Reference Include="Microsoft.Extensions.Logging" />
|
<Reference Include="Microsoft.Extensions.Logging" />
|
||||||
<Reference Include="System.Diagnostics.EventLog" />
|
<Reference Include="System.Diagnostics.EventLog" />
|
||||||
<Reference Include="System.Net.WebSockets.WebSocketProtocol" />
|
<Reference Include="System.Net.WebSockets.WebSocketProtocol" />
|
||||||
<Reference Include="System.Net.Http.WinHttpHandler" />
|
<Reference Include="System.Net.Http.WinHttpHandler" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="$(SharedSourceRoot)ServerInfrastructure\SharedStrings.resx" Link="Shared\SharedStrings.resx">
|
||||||
|
<ManifestResourceName>Microsoft.AspNetCore.Server.SharedStrings</ManifestResourceName>
|
||||||
|
<Generator></Generator>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="$(SharedSourceRoot)runtime\SR.resx" Link="Shared\runtime\SR.resx">
|
||||||
|
<ManifestResourceName>System.Net.Http.SR</ManifestResourceName>
|
||||||
|
<Generator></Generator>
|
||||||
|
</EmbeddedResource>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
<TestGroupName>IISNewShim.FunctionalTests</TestGroupName>
|
<TestGroupName>IISNewShim.FunctionalTests</TestGroupName>
|
||||||
<DisableFastUpToDateCheck>True</DisableFastUpToDateCheck>
|
<DisableFastUpToDateCheck>True</DisableFastUpToDateCheck>
|
||||||
<SkipTests Condition=" '$(SkipIISNewShimTests)' == 'true' ">true</SkipTests>
|
<SkipTests Condition=" '$(SkipIISNewShimTests)' == 'true' ">true</SkipTests>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<Import Project="../FunctionalTest.props" />
|
<Import Project="../FunctionalTest.props" />
|
||||||
|
|
@ -21,13 +22,30 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="..\Common.FunctionalTests\**\*.cs" />
|
<Compile Include="..\Common.FunctionalTests\**\*.cs" />
|
||||||
<Compile Include="..\IIS.Shared.FunctionalTests\**\*.cs" />
|
<Compile Include="..\IIS.Shared.FunctionalTests\**\*.cs" />
|
||||||
|
<Compile Include="$(SharedSourceRoot)Http2cat\**\*.cs" LinkBase="Shared\Http2cat" />
|
||||||
|
<Compile Include="$(SharedSourceRoot)runtime\Http2\**\*.cs" LinkBase="Shared\Http2\" />
|
||||||
|
<Compile Include="$(SharedSourceRoot)runtime\IHttpHeadersHandler.cs" LinkBase="Shared\IHttpHeadersHandler.cs" />
|
||||||
|
<Compile Include="$(SharedSourceRoot)runtime\SR.cs" LinkBase="Shared\SR.cs" />
|
||||||
|
<Compile Include="$(SharedSourceRoot)ServerInfrastructure\**\*.cs" LinkBase="Shared\" />
|
||||||
|
<Compile Include="$(SharedSourceRoot)TaskToApm.cs" Link="Shared\TaskToApm.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="Microsoft.AspNetCore.Hosting" />
|
<Reference Include="Microsoft.AspNetCore.Hosting" />
|
||||||
|
<Reference Include="Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets" />
|
||||||
<Reference Include="Microsoft.Extensions.Logging" />
|
<Reference Include="Microsoft.Extensions.Logging" />
|
||||||
<Reference Include="System.Diagnostics.EventLog" />
|
<Reference Include="System.Diagnostics.EventLog" />
|
||||||
<Reference Include="System.Net.Http.WinHttpHandler" />
|
<Reference Include="System.Net.Http.WinHttpHandler" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="$(SharedSourceRoot)ServerInfrastructure\SharedStrings.resx" Link="Shared\SharedStrings.resx">
|
||||||
|
<ManifestResourceName>Microsoft.AspNetCore.Server.SharedStrings</ManifestResourceName>
|
||||||
|
<Generator></Generator>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="$(SharedSourceRoot)runtime\SR.resx" Link="Shared\runtime\SR.resx">
|
||||||
|
<ManifestResourceName>System.Net.Http.SR</ManifestResourceName>
|
||||||
|
<Generator></Generator>
|
||||||
|
</EmbeddedResource>
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
<DisableFastUpToDateCheck>True</DisableFastUpToDateCheck>
|
<DisableFastUpToDateCheck>True</DisableFastUpToDateCheck>
|
||||||
<TestGroupName>IISExpress.FunctionalTests</TestGroupName>
|
<TestGroupName>IISExpress.FunctionalTests</TestGroupName>
|
||||||
<SkipTests Condition=" '$(SkipIISExpressTests)' == 'true' ">true</SkipTests>
|
<SkipTests Condition=" '$(SkipIISExpressTests)' == 'true' ">true</SkipTests>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -23,13 +24,31 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="..\Common.FunctionalTests\**\*.cs" />
|
<Compile Include="..\Common.FunctionalTests\**\*.cs" />
|
||||||
|
<Compile Include="$(SharedSourceRoot)Http2cat\**\*.cs" LinkBase="Shared\Http2cat" />
|
||||||
|
<Compile Include="$(SharedSourceRoot)runtime\Http2\**\*.cs" LinkBase="Shared\Http2\" />
|
||||||
|
<Compile Include="$(SharedSourceRoot)runtime\IHttpHeadersHandler.cs" LinkBase="Shared\IHttpHeadersHandler.cs" />
|
||||||
|
<Compile Include="$(SharedSourceRoot)runtime\SR.cs" LinkBase="Shared\SR.cs" />
|
||||||
|
<Compile Include="$(SharedSourceRoot)ServerInfrastructure\**\*.cs" LinkBase="Shared\" />
|
||||||
|
<Compile Include="$(SharedSourceRoot)TaskToApm.cs" Link="Shared\TaskToApm.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="Microsoft.AspNetCore.Hosting" />
|
<Reference Include="Microsoft.AspNetCore.Hosting" />
|
||||||
|
<Reference Include="Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets" />
|
||||||
<Reference Include="Microsoft.Extensions.Logging" />
|
<Reference Include="Microsoft.Extensions.Logging" />
|
||||||
<Reference Include="System.Diagnostics.EventLog" />
|
<Reference Include="System.Diagnostics.EventLog" />
|
||||||
<Reference Include="System.Net.Http.WinHttpHandler" />
|
<Reference Include="System.Net.Http.WinHttpHandler" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="$(SharedSourceRoot)ServerInfrastructure\SharedStrings.resx" Link="Shared\SharedStrings.resx">
|
||||||
|
<ManifestResourceName>Microsoft.AspNetCore.Server.SharedStrings</ManifestResourceName>
|
||||||
|
<Generator></Generator>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="$(SharedSourceRoot)runtime\SR.resx" Link="Shared\runtime\SR.resx">
|
||||||
|
<ManifestResourceName>System.Net.Http.SR</ManifestResourceName>
|
||||||
|
<Generator></Generator>
|
||||||
|
</EmbeddedResource>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -1033,7 +1033,7 @@ namespace TestSite
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !FORWARDCOMPAT
|
#if !FORWARDCOMPAT
|
||||||
public Task ResponseTrailers_HTTP2_TrailersAvailable(HttpContext context)
|
public Task ResponseTrailers_HTTP2_TrailersAvailable(HttpContext context)
|
||||||
{
|
{
|
||||||
Assert.Equal("HTTP/2", context.Request.Protocol);
|
Assert.Equal("HTTP/2", context.Request.Protocol);
|
||||||
|
|
@ -1135,6 +1135,191 @@ namespace TestSite
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task AppException_BeforeResponseHeaders_500(HttpContext context)
|
||||||
|
{
|
||||||
|
throw new Exception("Application exception");
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task AppException_AfterHeaders_PriorOSVersions_ResetCancel(HttpContext httpContext)
|
||||||
|
{
|
||||||
|
await httpContext.Response.Body.FlushAsync();
|
||||||
|
throw new Exception("Application exception");
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task AppException_AfterHeaders_ResetInternalError(HttpContext httpContext)
|
||||||
|
{
|
||||||
|
await httpContext.Response.Body.FlushAsync();
|
||||||
|
throw new Exception("Application exception");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task Reset_PriorOSVersions_NotSupported(HttpContext httpContext)
|
||||||
|
{
|
||||||
|
Assert.Equal("HTTP/2", httpContext.Request.Protocol);
|
||||||
|
var feature = httpContext.Features.Get<IHttpResetFeature>();
|
||||||
|
Assert.Null(feature);
|
||||||
|
return httpContext.Response.WriteAsync("Hello World");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task Reset_Http1_NotSupported(HttpContext httpContext)
|
||||||
|
{
|
||||||
|
Assert.Equal("HTTP/1.1", httpContext.Request.Protocol);
|
||||||
|
var feature = httpContext.Features.Get<IHttpResetFeature>();
|
||||||
|
Assert.Null(feature);
|
||||||
|
return httpContext.Response.WriteAsync("Hello World");
|
||||||
|
}
|
||||||
|
|
||||||
|
private TaskCompletionSource<object> _resetBeforeResponseResetsCts = new TaskCompletionSource<object>();
|
||||||
|
public Task Reset_BeforeResponse_Resets(HttpContext httpContext)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Assert.Equal("HTTP/2", httpContext.Request.Protocol);
|
||||||
|
var feature = httpContext.Features.Get<IHttpResetFeature>();
|
||||||
|
Assert.NotNull(feature);
|
||||||
|
feature.Reset(1111); // Custom
|
||||||
|
_resetBeforeResponseResetsCts.SetResult(0);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_resetBeforeResponseResetsCts.SetException(ex);
|
||||||
|
}
|
||||||
|
return Task.FromResult(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Reset_BeforeResponse_Resets_Complete(HttpContext httpContext)
|
||||||
|
{
|
||||||
|
await _resetBeforeResponseResetsCts.Task;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TaskCompletionSource<object> _resetBeforeResponseZeroResetsCts = new TaskCompletionSource<object>();
|
||||||
|
public Task Reset_BeforeResponse_Zero_Resets(HttpContext httpContext)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Assert.Equal("HTTP/2", httpContext.Request.Protocol);
|
||||||
|
var feature = httpContext.Features.Get<IHttpResetFeature>();
|
||||||
|
Assert.NotNull(feature);
|
||||||
|
feature.Reset(0); // Zero should be an allowed errorCode
|
||||||
|
_resetBeforeResponseZeroResetsCts.SetResult(0);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_resetBeforeResponseZeroResetsCts.SetException(ex);
|
||||||
|
}
|
||||||
|
return Task.FromResult(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Reset_BeforeResponse_Resets_Zero_Complete(HttpContext httpContext)
|
||||||
|
{
|
||||||
|
await _resetBeforeResponseZeroResetsCts.Task;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TaskCompletionSource<object> _resetAfterResponseHeadersResetsCts = new TaskCompletionSource<object>();
|
||||||
|
|
||||||
|
public async Task Reset_AfterResponseHeaders_Resets(HttpContext httpContext)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Assert.Equal("HTTP/2", httpContext.Request.Protocol);
|
||||||
|
var feature = httpContext.Features.Get<IHttpResetFeature>();
|
||||||
|
Assert.NotNull(feature);
|
||||||
|
await httpContext.Response.Body.FlushAsync();
|
||||||
|
feature.Reset(1111); // Custom
|
||||||
|
_resetAfterResponseHeadersResetsCts.SetResult(0);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_resetAfterResponseHeadersResetsCts.SetException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public async Task Reset_AfterResponseHeaders_Resets_Complete(HttpContext httpContext)
|
||||||
|
{
|
||||||
|
await _resetAfterResponseHeadersResetsCts.Task;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TaskCompletionSource<object> _resetDuringResponseBodyResetsCts = new TaskCompletionSource<object>();
|
||||||
|
|
||||||
|
public async Task Reset_DuringResponseBody_Resets(HttpContext httpContext)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Assert.Equal("HTTP/2", httpContext.Request.Protocol);
|
||||||
|
var feature = httpContext.Features.Get<IHttpResetFeature>();
|
||||||
|
Assert.NotNull(feature);
|
||||||
|
await httpContext.Response.WriteAsync("Hello World");
|
||||||
|
await httpContext.Response.Body.FlushAsync();
|
||||||
|
feature.Reset(1111); // Custom
|
||||||
|
_resetDuringResponseBodyResetsCts.SetResult(0);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_resetDuringResponseBodyResetsCts.SetException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Reset_DuringResponseBody_Resets_Complete(HttpContext httpContext)
|
||||||
|
{
|
||||||
|
await _resetDuringResponseBodyResetsCts.Task;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TaskCompletionSource<object> _resetBeforeRequestBodyResetsCts = new TaskCompletionSource<object>();
|
||||||
|
|
||||||
|
public async Task Reset_BeforeRequestBody_Resets(HttpContext httpContext)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Assert.Equal("HTTP/2", httpContext.Request.Protocol);
|
||||||
|
var feature = httpContext.Features.Get<IHttpResetFeature>();
|
||||||
|
Assert.NotNull(feature);
|
||||||
|
var readTask = httpContext.Request.Body.ReadAsync(new byte[10], 0, 10);
|
||||||
|
|
||||||
|
feature.Reset(1111);
|
||||||
|
|
||||||
|
await Assert.ThrowsAsync<IOException>(() => readTask);
|
||||||
|
|
||||||
|
_resetBeforeRequestBodyResetsCts.SetResult(0);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_resetBeforeRequestBodyResetsCts.SetException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Reset_BeforeRequestBody_Resets_Complete(HttpContext httpContext)
|
||||||
|
{
|
||||||
|
await _resetBeforeRequestBodyResetsCts.Task;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TaskCompletionSource<object> _resetDuringRequestBodyResetsCts = new TaskCompletionSource<object>();
|
||||||
|
|
||||||
|
public async Task Reset_DuringRequestBody_Resets(HttpContext httpContext)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Assert.Equal("HTTP/2", httpContext.Request.Protocol);
|
||||||
|
var feature = httpContext.Features.Get<IHttpResetFeature>();
|
||||||
|
Assert.NotNull(feature);
|
||||||
|
|
||||||
|
var read = await httpContext.Request.Body.ReadAsync(new byte[10], 0, 10);
|
||||||
|
Assert.Equal(10, read);
|
||||||
|
|
||||||
|
var readTask = httpContext.Request.Body.ReadAsync(new byte[10], 0, 10);
|
||||||
|
feature.Reset(1111);
|
||||||
|
await Assert.ThrowsAsync<IOException>(() => readTask);
|
||||||
|
|
||||||
|
_resetDuringRequestBodyResetsCts.SetResult(0);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_resetDuringRequestBodyResetsCts.SetException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Reset_DuringRequestBody_Resets_Complete(HttpContext httpContext)
|
||||||
|
{
|
||||||
|
await _resetDuringRequestBodyResetsCts.Task;
|
||||||
|
}
|
||||||
|
|
||||||
internal static readonly HashSet<(string, StringValues, StringValues)> NullTrailers = new HashSet<(string, StringValues, StringValues)>()
|
internal static readonly HashSet<(string, StringValues, StringValues)> NullTrailers = new HashSet<(string, StringValues, StringValues)>()
|
||||||
{
|
{
|
||||||
("NullString", (string)null, (string)null),
|
("NullString", (string)null, (string)null),
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,29 @@
|
||||||
{
|
{
|
||||||
"solution": {
|
"solution": {
|
||||||
"path": "..\\..\\..\\AspNetCore.sln",
|
"path": "..\\..\\..\\AspNetCore.sln",
|
||||||
"projects" : [
|
"projects": [
|
||||||
"src\\Servers\\IIS\\IISIntegration\\src\\Microsoft.AspNetCore.Server.IISIntegration.csproj",
|
|
||||||
"src\\Servers\\IIS\\IIS\\test\\IISExpress.FunctionalTests\\IISExpress.FunctionalTests.csproj",
|
|
||||||
"src\\Servers\\IIS\\IIS\\samples\\NativeIISSample\\NativeIISSample.csproj",
|
|
||||||
"src\\Servers\\IIS\\IIS\\src\\Microsoft.AspNetCore.Server.IIS.csproj",
|
|
||||||
"src\\Servers\\IIS\\AspNetCoreModuleV2\\AspNetCore\\AspNetCore.vcxproj",
|
"src\\Servers\\IIS\\AspNetCoreModuleV2\\AspNetCore\\AspNetCore.vcxproj",
|
||||||
|
"src\\Servers\\IIS\\AspNetCoreModuleV2\\CommonLibTests\\CommonLibTests.vcxproj",
|
||||||
"src\\Servers\\IIS\\AspNetCoreModuleV2\\CommonLib\\CommonLib.vcxproj",
|
"src\\Servers\\IIS\\AspNetCoreModuleV2\\CommonLib\\CommonLib.vcxproj",
|
||||||
"src\\Servers\\IIS\\AspNetCoreModuleV2\\IISLib\\IISLib.vcxproj",
|
"src\\Servers\\IIS\\AspNetCoreModuleV2\\IISLib\\IISLib.vcxproj",
|
||||||
"src\\Servers\\IIS\\IIS\\benchmarks\\IIS.Performance\\IIS.Performance.csproj",
|
|
||||||
"src\\Servers\\IIS\\AspNetCoreModuleV2\\InProcessRequestHandler\\InProcessRequestHandler.vcxproj",
|
"src\\Servers\\IIS\\AspNetCoreModuleV2\\InProcessRequestHandler\\InProcessRequestHandler.vcxproj",
|
||||||
"src\\Servers\\IIS\\AspNetCoreModuleV2\\OutOfProcessRequestHandler\\OutOfProcessRequestHandler.vcxproj",
|
"src\\Servers\\IIS\\AspNetCoreModuleV2\\OutOfProcessRequestHandler\\OutOfProcessRequestHandler.vcxproj",
|
||||||
"src\\Servers\\IIS\\AspNetCoreModuleV2\\RequestHandlerLib\\RequestHandlerLib.vcxproj",
|
"src\\Servers\\IIS\\AspNetCoreModuleV2\\RequestHandlerLib\\RequestHandlerLib.vcxproj",
|
||||||
|
"src\\Servers\\IIS\\AspNetCoreModuleV2\\Symbols\\Microsoft.AspNetCore.ANCMSymbols.csproj",
|
||||||
|
"src\\Servers\\IIS\\AspNetCoreModuleV2\\gtest\\gtest.vcxproj",
|
||||||
|
"src\\Servers\\IIS\\IISIntegration\\samples\\IISSample\\IISSample.csproj",
|
||||||
|
"src\\Servers\\IIS\\IISIntegration\\src\\Microsoft.AspNetCore.Server.IISIntegration.csproj",
|
||||||
|
"src\\Servers\\IIS\\IISIntegration\\test\\Tests\\Microsoft.AspNetCore.Server.IISIntegration.Tests.csproj",
|
||||||
|
"src\\Servers\\IIS\\IIS\\benchmarks\\IIS.Performance\\IIS.Performance.csproj",
|
||||||
|
"src\\Servers\\IIS\\IIS\\samples\\NativeIISSample\\NativeIISSample.csproj",
|
||||||
|
"src\\Servers\\IIS\\IIS\\src\\Microsoft.AspNetCore.Server.IIS.csproj",
|
||||||
"src\\Servers\\IIS\\IIS\\test\\IIS.FunctionalTests\\IIS.FunctionalTests.csproj",
|
"src\\Servers\\IIS\\IIS\\test\\IIS.FunctionalTests\\IIS.FunctionalTests.csproj",
|
||||||
"src\\Servers\\IIS\\IIS\\test\\IIS.Tests\\IIS.Tests.csproj",
|
|
||||||
"src\\Servers\\IIS\\IIS\\test\\testassets\\IIS.Common.TestLib\\IIS.Common.TestLib.csproj",
|
|
||||||
"src\\Servers\\IIS\\IIS\\test\\IIS.NewHandler.FunctionalTests\\IIS.NewHandler.FunctionalTests.csproj",
|
"src\\Servers\\IIS\\IIS\\test\\IIS.NewHandler.FunctionalTests\\IIS.NewHandler.FunctionalTests.csproj",
|
||||||
"src\\Servers\\IIS\\IIS\\test\\IIS.NewShim.FunctionalTests\\IIS.NewShim.FunctionalTests.csproj",
|
"src\\Servers\\IIS\\IIS\\test\\IIS.NewShim.FunctionalTests\\IIS.NewShim.FunctionalTests.csproj",
|
||||||
"src\\Servers\\IIS\\IIS\\test\\testassets\\TestTasks\\TestTasks.csproj",
|
"src\\Servers\\IIS\\IIS\\test\\IIS.Tests\\IIS.Tests.csproj",
|
||||||
|
"src\\Servers\\IIS\\IIS\\test\\IISExpress.FunctionalTests\\IISExpress.FunctionalTests.csproj",
|
||||||
"src\\Servers\\IIS\\IIS\\test\\testassets\\InProcessWebSite\\InProcessWebSite.csproj",
|
"src\\Servers\\IIS\\IIS\\test\\testassets\\InProcessWebSite\\InProcessWebSite.csproj",
|
||||||
"src\\Servers\\IIS\\IISIntegration\\test\\Tests\\Microsoft.AspNetCore.Server.IISIntegration.Tests.csproj",
|
"src\\Servers\\IIS\\IntegrationTesting.IIS\\src\\Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj"
|
||||||
"src\\Servers\\IIS\\IntegrationTesting.IIS\\src\\Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj",
|
|
||||||
"src\\Servers\\IIS\\AspNetCoreModuleV2\\CommonLibTests\\CommonLibTests.vcxproj",
|
|
||||||
"src\\Servers\\IIS\\IISIntegration\\samples\\IISSample\\IISSample.csproj",
|
|
||||||
"src\\Servers\\IIS\\AspNetCoreModuleV2\\gtest\\gtest.vcxproj"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue