From 77b7453f8673450dc3c890064051e523a0c8a0e4 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Wed, 12 May 2021 21:17:25 -0700 Subject: [PATCH 1/3] Improve IIS read IO performance - Increase the IIS default pause threshold to 1MB by default. This matches kestrel. Today IIS only allows for 65K of slack for incoming request bodies. This affects the maximum size of the read possible when doing large uploads. - Left the setting internal for now with the intent of exposing a public API in the future. --- src/Servers/IIS/IIS/src/Core/IISHttpContext.cs | 7 ++++--- src/Servers/IIS/IIS/src/IISServerOptions.cs | 5 +++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Servers/IIS/IIS/src/Core/IISHttpContext.cs b/src/Servers/IIS/IIS/src/Core/IISHttpContext.cs index 2d57e8b72ec2..24cbd4fbbe96 100644 --- a/src/Servers/IIS/IIS/src/Core/IISHttpContext.cs +++ b/src/Servers/IIS/IIS/src/Core/IISHttpContext.cs @@ -33,9 +33,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core internal abstract partial class IISHttpContext : NativeRequestContext, IThreadPoolWorkItem, IDisposable { private const int MinAllocBufferSize = 2048; - private const int PauseWriterThreshold = 65536; - private const int ResumeWriterTheshold = PauseWriterThreshold / 2; - + protected readonly NativeSafeHandle _requestNativeHandle; private readonly IISServerOptions _options; @@ -93,6 +91,9 @@ internal unsafe IISHttpContext( ((IHttpBodyControlFeature)this).AllowSynchronousIO = _options.AllowSynchronousIO; } + private int PauseWriterThreshold => _options.MaxRequestBodyBufferSize; + private int ResumeWriterTheshold => PauseWriterThreshold / 2; + public Version HttpVersion { get; set; } = default!; public string Scheme { get; set; } = default!; public string Method { get; set; } = default!; diff --git a/src/Servers/IIS/IIS/src/IISServerOptions.cs b/src/Servers/IIS/IIS/src/IISServerOptions.cs index fa72f96ddd7f..2adc93a37e47 100644 --- a/src/Servers/IIS/IIS/src/IISServerOptions.cs +++ b/src/Servers/IIS/IIS/src/IISServerOptions.cs @@ -39,6 +39,11 @@ public class IISServerOptions /// internal bool ForwardWindowsAuthentication { get; set; } = true; + /// + /// Gets or sets the maximum unconsumed incoming bytes the server will buffer for incoming request body. + /// + internal int MaxRequestBodyBufferSize { get; set; } = 1024 * 1024; // Matches kestrel (sorta) + internal string[] ServerAddresses { get; set; } = default!; // Set by configuration. // Matches the default maxAllowedContentLength in IIS (~28.6 MB) From 9508d3d61390323d4b004dea69285fc3ce93f26c Mon Sep 17 00:00:00 2001 From: David Fowler Date: Thu, 13 May 2021 22:58:07 -0700 Subject: [PATCH 2/3] Added public API for configuring the max body buffer --- src/Servers/IIS/IIS/src/IISServerOptions.cs | 13 ++++++++----- src/Servers/IIS/IIS/src/PublicAPI.Unshipped.txt | 2 ++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/Servers/IIS/IIS/src/IISServerOptions.cs b/src/Servers/IIS/IIS/src/IISServerOptions.cs index 2adc93a37e47..d50afd9960a4 100644 --- a/src/Servers/IIS/IIS/src/IISServerOptions.cs +++ b/src/Servers/IIS/IIS/src/IISServerOptions.cs @@ -34,15 +34,18 @@ public class IISServerOptions public string? AuthenticationDisplayName { get; set; } /// - /// Used to indicate if the authentication handler should be registered. This is only done if ANCM indicates - /// IIS has a non-anonymous authentication enabled, or for back compat with ANCMs that did not provide this information. + /// Gets or sets the maximum unconsumed incoming bytes the server will buffer for incoming request body. /// - internal bool ForwardWindowsAuthentication { get; set; } = true; + /// + /// Defaults to 1 MB. + /// + public int MaxRequestBodyBufferSize { get; set; } = 1024 * 1024; // Matches kestrel (sorta) /// - /// Gets or sets the maximum unconsumed incoming bytes the server will buffer for incoming request body. + /// Used to indicate if the authentication handler should be registered. This is only done if ANCM indicates + /// IIS has a non-anonymous authentication enabled, or for back compat with ANCMs that did not provide this information. /// - internal int MaxRequestBodyBufferSize { get; set; } = 1024 * 1024; // Matches kestrel (sorta) + internal bool ForwardWindowsAuthentication { get; set; } = true; internal string[] ServerAddresses { get; set; } = default!; // Set by configuration. diff --git a/src/Servers/IIS/IIS/src/PublicAPI.Unshipped.txt b/src/Servers/IIS/IIS/src/PublicAPI.Unshipped.txt index eb63ae5f62e0..cd2ce53f372d 100644 --- a/src/Servers/IIS/IIS/src/PublicAPI.Unshipped.txt +++ b/src/Servers/IIS/IIS/src/PublicAPI.Unshipped.txt @@ -13,6 +13,8 @@ *REMOVED*~override Microsoft.AspNetCore.Server.IIS.Core.WriteOnlyStream.ReadAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task *REMOVED*~static Microsoft.AspNetCore.Hosting.WebHostBuilderIISExtensions.UseIIS(this Microsoft.AspNetCore.Hosting.IWebHostBuilder hostBuilder) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder *REMOVED*~static Microsoft.AspNetCore.Server.IIS.HttpContextExtensions.GetIISServerVariable(this Microsoft.AspNetCore.Http.HttpContext context, string variableName) -> string +Microsoft.AspNetCore.Builder.IISServerOptions.MaxRequestBodyBufferSize.get -> int +Microsoft.AspNetCore.Builder.IISServerOptions.MaxRequestBodyBufferSize.set -> void Microsoft.AspNetCore.Http.Features.IServerVariablesFeature.this[string! variableName].get -> string? (forwarded, contained in Microsoft.AspNetCore.Http.Features) Microsoft.AspNetCore.Builder.IISServerOptions.AuthenticationDisplayName.get -> string? Microsoft.AspNetCore.Builder.IISServerOptions.AuthenticationDisplayName.set -> void From 6b3cdd4c4bcd4fc2d5b218b336477329b9c90fbe Mon Sep 17 00:00:00 2001 From: David Fowler Date: Mon, 17 May 2021 11:01:16 -0700 Subject: [PATCH 3/3] Update src/Servers/IIS/IIS/src/IISServerOptions.cs Co-authored-by: Pranav K --- src/Servers/IIS/IIS/src/IISServerOptions.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Servers/IIS/IIS/src/IISServerOptions.cs b/src/Servers/IIS/IIS/src/IISServerOptions.cs index d50afd9960a4..44932aabe2ed 100644 --- a/src/Servers/IIS/IIS/src/IISServerOptions.cs +++ b/src/Servers/IIS/IIS/src/IISServerOptions.cs @@ -36,9 +36,9 @@ public class IISServerOptions /// /// Gets or sets the maximum unconsumed incoming bytes the server will buffer for incoming request body. /// - /// + /// /// Defaults to 1 MB. - /// + /// public int MaxRequestBodyBufferSize { get; set; } = 1024 * 1024; // Matches kestrel (sorta) ///