From 04f37e59d54af63cdd1d2d196f0f4970e7b8818a Mon Sep 17 00:00:00 2001 From: Sourabh Shirhatti Date: Wed, 11 Sep 2019 14:41:52 -0700 Subject: [PATCH] Add queue name to HttpSysOptions (#13846) * Check for MAX_PATH * Update ref assemblies * Add test to check queue name * PR feedback * Bad rebase + PR comments Resolves #13461 --- ...AspNetCore.Server.HttpSys.netcoreapp3.0.cs | 1 + src/Servers/HttpSys/src/HttpSysListener.cs | 2 +- src/Servers/HttpSys/src/HttpSysOptions.cs | 20 +++++++++++++++ .../HttpSys/src/NativeInterop/RequestQueue.cs | 6 ++--- .../test/FunctionalTests/MessagePumpTests.cs | 2 +- .../test/FunctionalTests/ServerTests.cs | 25 +++++++++++++++++++ .../HttpSys/test/FunctionalTests/Utilities.cs | 10 ++++++-- 7 files changed, 59 insertions(+), 7 deletions(-) diff --git a/src/Servers/HttpSys/ref/Microsoft.AspNetCore.Server.HttpSys.netcoreapp3.0.cs b/src/Servers/HttpSys/ref/Microsoft.AspNetCore.Server.HttpSys.netcoreapp3.0.cs index 96907a8602..bccbdc2248 100644 --- a/src/Servers/HttpSys/ref/Microsoft.AspNetCore.Server.HttpSys.netcoreapp3.0.cs +++ b/src/Servers/HttpSys/ref/Microsoft.AspNetCore.Server.HttpSys.netcoreapp3.0.cs @@ -52,6 +52,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys public long? MaxConnections { get { throw null; } set { } } public long? MaxRequestBodySize { get { throw null; } set { } } public long RequestQueueLimit { get { throw null; } set { } } + public string RequestQueueName { get { throw null; } set { } } public bool ThrowWriteExceptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } public Microsoft.AspNetCore.Server.HttpSys.TimeoutManager Timeouts { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } public Microsoft.AspNetCore.Server.HttpSys.UrlPrefixCollection UrlPrefixes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } diff --git a/src/Servers/HttpSys/src/HttpSysListener.cs b/src/Servers/HttpSys/src/HttpSysListener.cs index a1ad7493d8..e8d56eb9bd 100644 --- a/src/Servers/HttpSys/src/HttpSysListener.cs +++ b/src/Servers/HttpSys/src/HttpSysListener.cs @@ -79,7 +79,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys _urlGroup = new UrlGroup(_serverSession, Logger); - _requestQueue = new RequestQueue(_urlGroup, Logger); + _requestQueue = new RequestQueue(_urlGroup, options.RequestQueueName, Logger); _disconnectListener = new DisconnectListener(_requestQueue, Logger); } diff --git a/src/Servers/HttpSys/src/HttpSysOptions.cs b/src/Servers/HttpSys/src/HttpSysOptions.cs index 82453398a8..7a2f75d8fc 100644 --- a/src/Servers/HttpSys/src/HttpSysOptions.cs +++ b/src/Servers/HttpSys/src/HttpSysOptions.cs @@ -9,6 +9,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys { public class HttpSysOptions { + private const uint MaximumRequestQueueNameLength = 260; private const Http503VerbosityLevel DefaultRejectionVerbosityLevel = Http503VerbosityLevel.Basic; // Http.sys default. private const long DefaultRequestQueueLength = 1000; // Http.sys default. internal static readonly int DefaultMaxAccepts = 5 * Environment.ProcessorCount; @@ -23,11 +24,30 @@ namespace Microsoft.AspNetCore.Server.HttpSys private RequestQueue _requestQueue; private UrlGroup _urlGroup; private long? _maxRequestBodySize = DefaultMaxRequestBodySize; + private string _requestQueueName; public HttpSysOptions() { } + /// + /// The name of the Http.Sys request queue + /// + public string RequestQueueName + { + get => _requestQueueName; + set + { + if (value.Length > MaximumRequestQueueNameLength) + { + throw new ArgumentOutOfRangeException(nameof(value), + value, + $"The request queue name should be fewer than {MaximumRequestQueueNameLength} characters in length"); + } + _requestQueueName = value; + } + } + /// /// The maximum number of concurrent accepts. /// diff --git a/src/Servers/HttpSys/src/NativeInterop/RequestQueue.cs b/src/Servers/HttpSys/src/NativeInterop/RequestQueue.cs index 1d3546f91b..84f107e48d 100644 --- a/src/Servers/HttpSys/src/NativeInterop/RequestQueue.cs +++ b/src/Servers/HttpSys/src/NativeInterop/RequestQueue.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -18,14 +18,14 @@ namespace Microsoft.AspNetCore.Server.HttpSys private readonly ILogger _logger; private bool _disposed; - internal RequestQueue(UrlGroup urlGroup, ILogger logger) + internal RequestQueue(UrlGroup urlGroup, string requestQueueName, ILogger logger) { _urlGroup = urlGroup; _logger = logger; HttpRequestQueueV2Handle requestQueueHandle = null; var statusCode = HttpApi.HttpCreateRequestQueue( - HttpApi.Version, null, null, 0, out requestQueueHandle); + HttpApi.Version, requestQueueName, null, 0, out requestQueueHandle); if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS) { diff --git a/src/Servers/HttpSys/test/FunctionalTests/MessagePumpTests.cs b/src/Servers/HttpSys/test/FunctionalTests/MessagePumpTests.cs index bbd47f3e19..250ff9c9be 100644 --- a/src/Servers/HttpSys/test/FunctionalTests/MessagePumpTests.cs +++ b/src/Servers/HttpSys/test/FunctionalTests/MessagePumpTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Linq; diff --git a/src/Servers/HttpSys/test/FunctionalTests/ServerTests.cs b/src/Servers/HttpSys/test/FunctionalTests/ServerTests.cs index bc096b7b20..2bab8a1bf5 100644 --- a/src/Servers/HttpSys/test/FunctionalTests/ServerTests.cs +++ b/src/Servers/HttpSys/test/FunctionalTests/ServerTests.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Net; using System.Net.Http; @@ -32,6 +33,30 @@ namespace Microsoft.AspNetCore.Server.HttpSys } } + [ConditionalFact] + public async Task Server_SetQueueName_Success() + { + string address; + var queueName = Guid.NewGuid().ToString(); + using (Utilities.CreateHttpServer(out address, httpContext => + { + return Task.FromResult(0); + }, options => + { + options.RequestQueueName = queueName; + })) + { + var psi = new ProcessStartInfo("netsh", "http show servicestate view=requestq") + { + RedirectStandardOutput = true + }; + using var process = Process.Start(psi); + process.Start(); + var netshOutput = await process.StandardOutput.ReadToEndAsync(); + Assert.Contains(queueName, netshOutput); + } + } + [ConditionalFact] public async Task Server_SendHelloWorld_Success() { diff --git a/src/Servers/HttpSys/test/FunctionalTests/Utilities.cs b/src/Servers/HttpSys/test/FunctionalTests/Utilities.cs index 24869a8b80..8ba9e7b39a 100644 --- a/src/Servers/HttpSys/test/FunctionalTests/Utilities.cs +++ b/src/Servers/HttpSys/test/FunctionalTests/Utilities.cs @@ -122,6 +122,13 @@ namespace Microsoft.AspNetCore.Server.HttpSys internal static MessagePump CreatePump() => new MessagePump(Options.Create(new HttpSysOptions()), new LoggerFactory(), new AuthenticationSchemeProvider(Options.Create(new AuthenticationOptions()))); + internal static MessagePump CreatePump(Action configureOptions) + { + var options = new HttpSysOptions(); + configureOptions(options); + return new MessagePump(Options.Create(options), new LoggerFactory(), new AuthenticationSchemeProvider(Options.Create(new AuthenticationOptions()))); + } + internal static IServer CreateDynamicHttpServer(string basePath, out string root, out string baseAddress, Action configureOptions, RequestDelegate app) { lock (PortLock) @@ -134,9 +141,8 @@ namespace Microsoft.AspNetCore.Server.HttpSys root = prefix.Scheme + "://" + prefix.Host + ":" + prefix.Port; baseAddress = prefix.ToString(); - var server = CreatePump(); + var server = CreatePump(configureOptions); server.Features.Get().Addresses.Add(baseAddress); - configureOptions(server.Listener.Options); try { server.StartAsync(new DummyApplication(app), CancellationToken.None).Wait();