diff --git a/src/Servers/HttpSys/samples/SelfHostServer/SelfHostServer.csproj b/src/Servers/HttpSys/samples/SelfHostServer/SelfHostServer.csproj index cf4b7f8a960e..35450964c9ef 100644 --- a/src/Servers/HttpSys/samples/SelfHostServer/SelfHostServer.csproj +++ b/src/Servers/HttpSys/samples/SelfHostServer/SelfHostServer.csproj @@ -1,10 +1,15 @@ - + $(DefaultNetCoreTargetFramework) Exe true + + + + 214124cd-d05b-4309-9af9-9caa44b2b74a + diff --git a/src/Servers/HttpSys/samples/SelfHostServer/Startup.cs b/src/Servers/HttpSys/samples/SelfHostServer/Startup.cs index 52b65bd248c0..42f6d11f81e5 100644 --- a/src/Servers/HttpSys/samples/SelfHostServer/Startup.cs +++ b/src/Servers/HttpSys/samples/SelfHostServer/Startup.cs @@ -37,6 +37,8 @@ public static void Main(string[] args) .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; }) diff --git a/src/Servers/HttpSys/src/NativeInterop/ComNetOS.cs b/src/Servers/HttpSys/src/NativeInterop/ComNetOS.cs index 12d1381baeb7..f2b693c1d150 100644 --- a/src/Servers/HttpSys/src/NativeInterop/ComNetOS.cs +++ b/src/Servers/HttpSys/src/NativeInterop/ComNetOS.cs @@ -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 { diff --git a/src/Servers/HttpSys/src/RequestProcessing/Response.cs b/src/Servers/HttpSys/src/RequestProcessing/Response.cs index b31dc4809ef5..5f29763d2ff5 100644 --- a/src/Servers/HttpSys/src/RequestProcessing/Response.cs +++ b/src/Servers/HttpSys/src/RequestProcessing/Response.cs @@ -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 @@ internal unsafe uint SendHeaders(HttpApiTypes.HTTP_DATA_CHUNK[] dataChunks, 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 @@ internal HttpApiTypes.HTTP_FLAGS ComputeHeaders(long writeCount, bool endOfReque 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; diff --git a/src/Shared/HttpSys/NativeInterop/HttpApiTypes.cs b/src/Shared/HttpSys/NativeInterop/HttpApiTypes.cs index 324426c60dbc..80a06607cbad 100644 --- a/src/Shared/HttpSys/NativeInterop/HttpApiTypes.cs +++ b/src/Shared/HttpSys/NativeInterop/HttpApiTypes.cs @@ -602,6 +602,7 @@ internal enum HTTP_FLAGS : uint HTTP_INITIALIZE_SERVER = 0x00000001, HTTP_INITIALIZE_CBT = 0x00000004, HTTP_SEND_RESPONSE_FLAG_OPAQUE = 0x00000040, + HTTP_SEND_RESPONSE_FLAG_GOAWAY = 0x00000100, } [Flags]