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
This commit is contained in:
Sourabh Shirhatti 2019-09-11 14:41:52 -07:00 committed by GitHub
parent 0079423514
commit 04f37e59d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 59 additions and 7 deletions

View File

@ -52,6 +52,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
public long? MaxConnections { get { throw null; } set { } } public long? MaxConnections { get { throw null; } set { } }
public long? MaxRequestBodySize { get { throw null; } set { } } public long? MaxRequestBodySize { get { throw null; } set { } }
public long RequestQueueLimit { 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 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.TimeoutManager Timeouts { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
public Microsoft.AspNetCore.Server.HttpSys.UrlPrefixCollection UrlPrefixes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } public Microsoft.AspNetCore.Server.HttpSys.UrlPrefixCollection UrlPrefixes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }

View File

@ -79,7 +79,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
_urlGroup = new UrlGroup(_serverSession, Logger); _urlGroup = new UrlGroup(_serverSession, Logger);
_requestQueue = new RequestQueue(_urlGroup, Logger); _requestQueue = new RequestQueue(_urlGroup, options.RequestQueueName, Logger);
_disconnectListener = new DisconnectListener(_requestQueue, Logger); _disconnectListener = new DisconnectListener(_requestQueue, Logger);
} }

View File

@ -9,6 +9,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
{ {
public class HttpSysOptions public class HttpSysOptions
{ {
private const uint MaximumRequestQueueNameLength = 260;
private const Http503VerbosityLevel DefaultRejectionVerbosityLevel = Http503VerbosityLevel.Basic; // Http.sys default. private const Http503VerbosityLevel DefaultRejectionVerbosityLevel = Http503VerbosityLevel.Basic; // Http.sys default.
private const long DefaultRequestQueueLength = 1000; // Http.sys default. private const long DefaultRequestQueueLength = 1000; // Http.sys default.
internal static readonly int DefaultMaxAccepts = 5 * Environment.ProcessorCount; internal static readonly int DefaultMaxAccepts = 5 * Environment.ProcessorCount;
@ -23,11 +24,30 @@ namespace Microsoft.AspNetCore.Server.HttpSys
private RequestQueue _requestQueue; private RequestQueue _requestQueue;
private UrlGroup _urlGroup; private UrlGroup _urlGroup;
private long? _maxRequestBodySize = DefaultMaxRequestBodySize; private long? _maxRequestBodySize = DefaultMaxRequestBodySize;
private string _requestQueueName;
public HttpSysOptions() public HttpSysOptions()
{ {
} }
/// <summary>
/// The name of the Http.Sys request queue
/// </summary>
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;
}
}
/// <summary> /// <summary>
/// The maximum number of concurrent accepts. /// The maximum number of concurrent accepts.
/// </summary> /// </summary>

View File

@ -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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
@ -18,14 +18,14 @@ namespace Microsoft.AspNetCore.Server.HttpSys
private readonly ILogger _logger; private readonly ILogger _logger;
private bool _disposed; private bool _disposed;
internal RequestQueue(UrlGroup urlGroup, ILogger logger) internal RequestQueue(UrlGroup urlGroup, string requestQueueName, ILogger logger)
{ {
_urlGroup = urlGroup; _urlGroup = urlGroup;
_logger = logger; _logger = logger;
HttpRequestQueueV2Handle requestQueueHandle = null; HttpRequestQueueV2Handle requestQueueHandle = null;
var statusCode = HttpApi.HttpCreateRequestQueue( var statusCode = HttpApi.HttpCreateRequestQueue(
HttpApi.Version, null, null, 0, out requestQueueHandle); HttpApi.Version, requestQueueName, null, 0, out requestQueueHandle);
if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS) if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS)
{ {

View File

@ -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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Linq; using System.Linq;

View File

@ -3,6 +3,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Net; using System.Net;
using System.Net.Http; 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] [ConditionalFact]
public async Task Server_SendHelloWorld_Success() public async Task Server_SendHelloWorld_Success()
{ {

View File

@ -122,6 +122,13 @@ namespace Microsoft.AspNetCore.Server.HttpSys
internal static MessagePump CreatePump() internal static MessagePump CreatePump()
=> new MessagePump(Options.Create(new HttpSysOptions()), new LoggerFactory(), new AuthenticationSchemeProvider(Options.Create(new AuthenticationOptions()))); => new MessagePump(Options.Create(new HttpSysOptions()), new LoggerFactory(), new AuthenticationSchemeProvider(Options.Create(new AuthenticationOptions())));
internal static MessagePump CreatePump(Action<HttpSysOptions> 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<HttpSysOptions> configureOptions, RequestDelegate app) internal static IServer CreateDynamicHttpServer(string basePath, out string root, out string baseAddress, Action<HttpSysOptions> configureOptions, RequestDelegate app)
{ {
lock (PortLock) lock (PortLock)
@ -134,9 +141,8 @@ namespace Microsoft.AspNetCore.Server.HttpSys
root = prefix.Scheme + "://" + prefix.Host + ":" + prefix.Port; root = prefix.Scheme + "://" + prefix.Host + ":" + prefix.Port;
baseAddress = prefix.ToString(); baseAddress = prefix.ToString();
var server = CreatePump(); var server = CreatePump(configureOptions);
server.Features.Get<IServerAddressesFeature>().Addresses.Add(baseAddress); server.Features.Get<IServerAddressesFeature>().Addresses.Add(baseAddress);
configureOptions(server.Listener.Options);
try try
{ {
server.StartAsync(new DummyApplication(app), CancellationToken.None).Wait(); server.StartAsync(new DummyApplication(app), CancellationToken.None).Wait();