HttpSys GoAway (#14522)

This commit is contained in:
Chris Ross 2019-10-01 16:05:22 -07:00 committed by Andrew Stanton-Nurse
parent 12cba32a11
commit 5df258ae5b
5 changed files with 41 additions and 3 deletions

View File

@ -1,10 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework>
<OutputType>Exe</OutputType>
<ServerGarbageCollection>true</ServerGarbageCollection>
</PropertyGroup>
<PropertyGroup>
<!--Imitate IIS Express so we can use it's cert bindings-->
<PackageTags>214124cd-d05b-4309-9af9-9caa44b2b74a</PackageTags>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.AspNetCore.Server.HttpSys" />

View File

@ -37,6 +37,8 @@ namespace SelfHostServer
.UseHttpSys(options =>
{
options.UrlPrefixes.Add("http://localhost:5000");
// This is a pre-configured IIS express port. See the PackageTags in the csproj.
options.UrlPrefixes.Add("https://localhost:44319");
options.Authentication.Schemes = AuthenticationSchemes.None;
options.Authentication.AllowAnonymous = true;
})

View File

@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.Extensions.Internal;
namespace Microsoft.AspNetCore.Server.HttpSys
{

View File

@ -4,7 +4,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
@ -18,6 +17,9 @@ namespace Microsoft.AspNetCore.Server.HttpSys
{
internal sealed class Response
{
// Support is assumed until we get an error and turn it off.
private static bool SupportsGoAway = true;
private ResponseState _responseState;
private string _reasonPhrase;
private ResponseBody _nativeStream;
@ -314,6 +316,31 @@ namespace Microsoft.AspNetCore.Server.HttpSys
asyncResult == null ? SafeNativeOverlapped.Zero : asyncResult.NativeOverlapped,
IntPtr.Zero);
// GoAway is only supported on later versions. Retry.
if (statusCode == ErrorCodes.ERROR_INVALID_PARAMETER
&& (flags & HttpApiTypes.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_GOAWAY) != 0)
{
flags &= ~HttpApiTypes.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_GOAWAY;
statusCode =
HttpApi.HttpSendHttpResponse(
RequestContext.Server.RequestQueue.Handle,
Request.RequestId,
(uint)flags,
pResponse,
&cachePolicy,
&bytesSent,
IntPtr.Zero,
0,
asyncResult == null ? SafeNativeOverlapped.Zero : asyncResult.NativeOverlapped,
IntPtr.Zero);
// Succeeded without GoAway, disable them.
if (statusCode != ErrorCodes.ERROR_INVALID_PARAMETER)
{
SupportsGoAway = false;
}
}
if (asyncResult != null &&
statusCode == ErrorCodes.ERROR_SUCCESS &&
HttpSysListener.SkipIOCPCallbackOnSuccess)
@ -417,6 +444,10 @@ namespace Microsoft.AspNetCore.Server.HttpSys
Headers.Append(HttpKnownHeaderNames.Connection, Constants.Close);
}
flags = HttpApiTypes.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_DISCONNECT;
if (responseCloseSet && requestVersion >= Constants.V2 && SupportsGoAway)
{
flags |= HttpApiTypes.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_GOAWAY;
}
}
Headers.IsReadOnly = true;

View File

@ -602,6 +602,7 @@ namespace Microsoft.AspNetCore.HttpSys.Internal
HTTP_INITIALIZE_SERVER = 0x00000001,
HTTP_INITIALIZE_CBT = 0x00000004,
HTTP_SEND_RESPONSE_FLAG_OPAQUE = 0x00000040,
HTTP_SEND_RESPONSE_FLAG_GOAWAY = 0x00000100,
}
[Flags]