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();
|
||||
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
|
||||
|
|
|
|||
|
|
@ -33,7 +33,8 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
|
|||
ITlsConnectionFeature,
|
||||
IHttpBodyControlFeature,
|
||||
IHttpMaxRequestBodySizeFeature,
|
||||
IHttpResponseTrailersFeature
|
||||
IHttpResponseTrailersFeature,
|
||||
IHttpResetFeature
|
||||
{
|
||||
// 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.
|
||||
|
|
@ -394,6 +395,33 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
|
|||
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()
|
||||
{
|
||||
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 IHttpMaxRequestBodySizeFeature = typeof(global::Microsoft.AspNetCore.Http.Features.IHttpMaxRequestBodySizeFeature);
|
||||
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 _currentIHttpResponseFeature;
|
||||
|
|
@ -50,6 +51,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
|
|||
private object _currentIServerVariablesFeature;
|
||||
private object _currentIHttpMaxRequestBodySizeFeature;
|
||||
private object _currentIHttpResponseTrailersFeature;
|
||||
private object _currentIHttpResetFeature;
|
||||
|
||||
private void Initialize()
|
||||
{
|
||||
|
|
@ -66,6 +68,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
|
|||
_currentIHttpMaxRequestBodySizeFeature = this;
|
||||
_currentITlsConnectionFeature = this;
|
||||
_currentIHttpResponseTrailersFeature = GetResponseTrailersFeature();
|
||||
_currentIHttpResetFeature = GetResetFeature();
|
||||
}
|
||||
|
||||
internal object FastFeatureGet(Type key)
|
||||
|
|
@ -154,6 +157,10 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
|
|||
{
|
||||
return _currentIHttpResponseTrailersFeature;
|
||||
}
|
||||
if (key == IHttpResetFeature)
|
||||
{
|
||||
return _currentIHttpResetFeature;
|
||||
}
|
||||
|
||||
return ExtraFeatureGet(key);
|
||||
}
|
||||
|
|
@ -260,6 +267,10 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
|
|||
{
|
||||
_currentIHttpResponseTrailersFeature = feature;
|
||||
}
|
||||
if (key == IHttpResetFeature)
|
||||
{
|
||||
_currentIHttpResetFeature = feature;
|
||||
}
|
||||
if (key == IISHttpContextType)
|
||||
{
|
||||
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);
|
||||
}
|
||||
if (_currentIHttpResetFeature != null)
|
||||
{
|
||||
yield return new KeyValuePair<Type, object>(IHttpResponseTrailersFeature, _currentIHttpResetFeature as global::Microsoft.AspNetCore.Http.Features.IHttpResetFeature);
|
||||
}
|
||||
|
||||
if (MaybeExtra != null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -59,6 +59,13 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
|
|||
// 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)
|
||||
{
|
||||
await FireOnCompleted();
|
||||
|
|
|
|||
|
|
@ -146,6 +146,9 @@ namespace Microsoft.AspNetCore.Server.IIS
|
|||
[DllImport(AspNetCoreModuleDll)]
|
||||
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)]
|
||||
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));
|
||||
}
|
||||
|
||||
internal static unsafe void HttpResetStream(IntPtr pInProcessHandler, ulong errorCode)
|
||||
{
|
||||
Validate(http_reset_stream(pInProcessHandler, errorCode));
|
||||
}
|
||||
|
||||
internal static unsafe bool HttpSupportTrailer(IntPtr pInProcessHandler)
|
||||
{
|
||||
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>
|
||||
<DisableFastUpToDateCheck>True</DisableFastUpToDateCheck>
|
||||
<SkipTests Condition=" '$(SkipIISTests)' == 'true' ">true</SkipTests>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="../FunctionalTest.props" />
|
||||
|
|
@ -19,13 +20,30 @@
|
|||
<ItemGroup>
|
||||
<Compile Include="..\Common.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>
|
||||
<Reference Include="Microsoft.AspNetCore.Hosting" />
|
||||
<Reference Include="Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets" />
|
||||
<Reference Include="Microsoft.Extensions.Logging" />
|
||||
<Reference Include="System.Diagnostics.EventLog" />
|
||||
<Reference Include="System.Net.Http.WinHttpHandler" />
|
||||
</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>
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
<TestGroupName>IISNewHandler.FunctionalTests</TestGroupName>
|
||||
<DisableFastUpToDateCheck>True</DisableFastUpToDateCheck>
|
||||
<SkipTests Condition=" '$(SkipIISNewHandlerTests)' == 'true' ">true</SkipTests>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="../FunctionalTest.props" />
|
||||
|
|
@ -12,6 +13,12 @@
|
|||
<ItemGroup>
|
||||
<Compile Include="..\Common.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>
|
||||
|
|
@ -30,10 +37,22 @@
|
|||
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.AspNetCore.Hosting" />
|
||||
<Reference Include="Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets" />
|
||||
<Reference Include="Microsoft.Extensions.Logging" />
|
||||
<Reference Include="System.Diagnostics.EventLog" />
|
||||
<Reference Include="System.Net.WebSockets.WebSocketProtocol" />
|
||||
<Reference Include="System.Net.Http.WinHttpHandler" />
|
||||
</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>
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
<TestGroupName>IISNewShim.FunctionalTests</TestGroupName>
|
||||
<DisableFastUpToDateCheck>True</DisableFastUpToDateCheck>
|
||||
<SkipTests Condition=" '$(SkipIISNewShimTests)' == 'true' ">true</SkipTests>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="../FunctionalTest.props" />
|
||||
|
|
@ -21,13 +22,30 @@
|
|||
<ItemGroup>
|
||||
<Compile Include="..\Common.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>
|
||||
<Reference Include="Microsoft.AspNetCore.Hosting" />
|
||||
<Reference Include="Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets" />
|
||||
<Reference Include="Microsoft.Extensions.Logging" />
|
||||
<Reference Include="System.Diagnostics.EventLog" />
|
||||
<Reference Include="System.Net.Http.WinHttpHandler" />
|
||||
</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>
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
<DisableFastUpToDateCheck>True</DisableFastUpToDateCheck>
|
||||
<TestGroupName>IISExpress.FunctionalTests</TestGroupName>
|
||||
<SkipTests Condition=" '$(SkipIISExpressTests)' == 'true' ">true</SkipTests>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
|
|
@ -23,13 +24,31 @@
|
|||
|
||||
<ItemGroup>
|
||||
<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>
|
||||
<Reference Include="Microsoft.AspNetCore.Hosting" />
|
||||
<Reference Include="Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets" />
|
||||
<Reference Include="Microsoft.Extensions.Logging" />
|
||||
<Reference Include="System.Diagnostics.EventLog" />
|
||||
<Reference Include="System.Net.Http.WinHttpHandler" />
|
||||
</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>
|
||||
|
|
|
|||
|
|
@ -1033,7 +1033,7 @@ namespace TestSite
|
|||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
#if !FORWARDCOMPAT
|
||||
#if !FORWARDCOMPAT
|
||||
public Task ResponseTrailers_HTTP2_TrailersAvailable(HttpContext context)
|
||||
{
|
||||
Assert.Equal("HTTP/2", context.Request.Protocol);
|
||||
|
|
@ -1135,6 +1135,191 @@ namespace TestSite
|
|||
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)>()
|
||||
{
|
||||
("NullString", (string)null, (string)null),
|
||||
|
|
|
|||
|
|
@ -1,30 +1,29 @@
|
|||
{
|
||||
{
|
||||
"solution": {
|
||||
"path": "..\\..\\..\\AspNetCore.sln",
|
||||
"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",
|
||||
"projects": [
|
||||
"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\\IISLib\\IISLib.vcxproj",
|
||||
"src\\Servers\\IIS\\IIS\\benchmarks\\IIS.Performance\\IIS.Performance.csproj",
|
||||
"src\\Servers\\IIS\\AspNetCoreModuleV2\\InProcessRequestHandler\\InProcessRequestHandler.vcxproj",
|
||||
"src\\Servers\\IIS\\AspNetCoreModuleV2\\OutOfProcessRequestHandler\\OutOfProcessRequestHandler.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.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.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\\IISIntegration\\test\\Tests\\Microsoft.AspNetCore.Server.IISIntegration.Tests.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"
|
||||
"src\\Servers\\IIS\\IntegrationTesting.IIS\\src\\Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue