Skip to content

Commit 56d0f2a

Browse files
authored
Remove async state machines from middlewares when they do nothing (#34581)
1 parent 728bae2 commit 56d0f2a

File tree

9 files changed

+126
-111
lines changed

9 files changed

+126
-111
lines changed

src/Http/Http.Abstractions/src/Extensions/MapMiddleware.cs

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public MapMiddleware(RequestDelegate next, MapOptions options)
4646
/// </summary>
4747
/// <param name="context">The <see cref="HttpContext"/> for the current request.</param>
4848
/// <returns>A task that represents the execution of this middleware.</returns>
49-
public async Task Invoke(HttpContext context)
49+
public Task Invoke(HttpContext context)
5050
{
5151
if (context == null)
5252
{
@@ -55,32 +55,32 @@ public async Task Invoke(HttpContext context)
5555

5656
if (context.Request.Path.StartsWithSegments(_options.PathMatch, out var matchedPath, out var remainingPath))
5757
{
58-
var path = context.Request.Path;
59-
var pathBase = context.Request.PathBase;
60-
6158
if (!_options.PreserveMatchedPathSegment)
6259
{
63-
// Update the path
64-
context.Request.PathBase = pathBase.Add(matchedPath);
65-
context.Request.Path = remainingPath;
60+
return InvokeCore(context, matchedPath, remainingPath);
6661
}
62+
return _options.Branch!(context);
63+
}
64+
return _next(context);
65+
}
6766

68-
try
69-
{
70-
await _options.Branch!(context);
71-
}
72-
finally
73-
{
74-
if (!_options.PreserveMatchedPathSegment)
75-
{
76-
context.Request.PathBase = pathBase;
77-
context.Request.Path = path;
78-
}
79-
}
67+
private async Task InvokeCore(HttpContext context, string matchedPath, string remainingPath)
68+
{
69+
var path = context.Request.Path;
70+
var pathBase = context.Request.PathBase;
71+
72+
// Update the path
73+
context.Request.PathBase = pathBase.Add(matchedPath);
74+
context.Request.Path = remainingPath;
75+
76+
try
77+
{
78+
await _options.Branch!(context);
8079
}
81-
else
80+
finally
8281
{
83-
await _next(context);
82+
context.Request.PathBase = pathBase;
83+
context.Request.Path = path;
8484
}
8585
}
8686
}

src/Http/Http.Abstractions/src/Extensions/MapWhenMiddleware.cs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public MapWhenMiddleware(RequestDelegate next, MapWhenOptions options)
5151
/// </summary>
5252
/// <param name="context">The <see cref="HttpContext"/> for the current request.</param>
5353
/// <returns>A task that represents the execution of this middleware.</returns>
54-
public async Task Invoke(HttpContext context)
54+
public Task Invoke(HttpContext context)
5555
{
5656
if (context == null)
5757
{
@@ -60,12 +60,9 @@ public async Task Invoke(HttpContext context)
6060

6161
if (_options.Predicate!(context))
6262
{
63-
await _options.Branch!(context);
64-
}
65-
else
66-
{
67-
await _next(context);
63+
return _options.Branch!(context);
6864
}
65+
return _next(context);
6966
}
7067
}
7168
}

src/Http/Http.Abstractions/src/Extensions/UsePathBaseMiddleware.cs

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) .NET Foundation. All rights reserved.
1+
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System;
@@ -41,37 +41,36 @@ public UsePathBaseMiddleware(RequestDelegate next, PathString pathBase)
4141
/// </summary>
4242
/// <param name="context">The <see cref="HttpContext"/> for the current request.</param>
4343
/// <returns>A task that represents the execution of this middleware.</returns>
44-
public async Task Invoke(HttpContext context)
44+
public Task Invoke(HttpContext context)
4545
{
4646
if (context == null)
4747
{
4848
throw new ArgumentNullException(nameof(context));
4949
}
5050

51-
PathString matchedPath;
52-
PathString remainingPath;
53-
54-
if (context.Request.Path.StartsWithSegments(_pathBase, out matchedPath, out remainingPath))
51+
if (context.Request.Path.StartsWithSegments(_pathBase, out var matchedPath, out var remainingPath))
5552
{
56-
var originalPath = context.Request.Path;
57-
var originalPathBase = context.Request.PathBase;
58-
context.Request.Path = remainingPath;
59-
context.Request.PathBase = originalPathBase.Add(matchedPath);
60-
61-
try
62-
{
63-
await _next(context);
64-
}
65-
finally
66-
{
67-
context.Request.Path = originalPath;
68-
context.Request.PathBase = originalPathBase;
69-
}
53+
return InvokeCore(context, matchedPath, remainingPath);
7054
}
71-
else
55+
return _next(context);
56+
}
57+
58+
private async Task InvokeCore(HttpContext context, string matchedPath, string remainingPath)
59+
{
60+
var originalPath = context.Request.Path;
61+
var originalPathBase = context.Request.PathBase;
62+
context.Request.Path = remainingPath;
63+
context.Request.PathBase = originalPathBase.Add(matchedPath);
64+
65+
try
7266
{
7367
await _next(context);
7468
}
69+
finally
70+
{
71+
context.Request.Path = originalPath;
72+
context.Request.PathBase = originalPathBase;
73+
}
7574
}
7675
}
77-
}
76+
}

src/Middleware/Diagnostics.EntityFrameworkCore/src/MigrationsEndPointMiddleware.cs

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public MigrationsEndPointMiddleware(
5959
/// </summary>
6060
/// <param name="context">The context for the current request.</param>
6161
/// <returns>A task that represents the asynchronous operation.</returns>
62-
public virtual async Task Invoke(HttpContext context)
62+
public virtual Task Invoke(HttpContext context)
6363
{
6464
if (context == null)
6565
{
@@ -68,39 +68,41 @@ public virtual async Task Invoke(HttpContext context)
6868

6969
if (context.Request.Path.Equals(_options.Path))
7070
{
71-
_logger.RequestPathMatched(context.Request.Path);
71+
return InvokeCore(context);
72+
}
73+
return _next(context);
74+
}
7275

73-
var db = await GetDbContext(context, _logger);
76+
private async Task InvokeCore(HttpContext context)
77+
{
78+
_logger.RequestPathMatched(context.Request.Path);
7479

75-
if (db != null)
80+
var db = await GetDbContext(context, _logger);
81+
82+
if (db != null)
83+
{
84+
var dbName = db.GetType().FullName!;
85+
try
7686
{
77-
var dbName = db.GetType().FullName!;
78-
try
79-
{
80-
_logger.ApplyingMigrations(dbName);
87+
_logger.ApplyingMigrations(dbName);
8188

82-
await db.Database.MigrateAsync();
89+
await db.Database.MigrateAsync();
8390

84-
context.Response.StatusCode = (int)HttpStatusCode.NoContent;
85-
context.Response.Headers.Add("Pragma", new[] { "no-cache" });
86-
context.Response.Headers.Add("Cache-Control", new[] { "no-cache,no-store" });
91+
context.Response.StatusCode = (int)HttpStatusCode.NoContent;
92+
context.Response.Headers.Add("Pragma", new[] { "no-cache" });
93+
context.Response.Headers.Add("Cache-Control", new[] { "no-cache,no-store" });
8794

88-
_logger.MigrationsApplied(dbName);
89-
}
90-
catch (Exception ex)
91-
{
92-
var message = Strings.FormatMigrationsEndPointMiddleware_Exception(dbName) + ex;
95+
_logger.MigrationsApplied(dbName);
96+
}
97+
catch (Exception ex)
98+
{
99+
var message = Strings.FormatMigrationsEndPointMiddleware_Exception(dbName) + ex;
93100

94-
_logger.MigrationsEndPointMiddlewareException(dbName, ex);
101+
_logger.MigrationsEndPointMiddlewareException(dbName, ex);
95102

96-
throw new InvalidOperationException(message, ex);
97-
}
103+
throw new InvalidOperationException(message, ex);
98104
}
99105
}
100-
else
101-
{
102-
await _next(context);
103-
}
104106
}
105107

106108
private static async Task<DbContext?> GetDbContext(HttpContext context, ILogger logger)

src/Middleware/HttpOverrides/src/HttpMethodOverrideMiddleware.cs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,20 +41,15 @@ public HttpMethodOverrideMiddleware(RequestDelegate next, IOptions<HttpMethodOve
4141
/// Executes the middleware.
4242
/// </summary>
4343
/// <param name="context">The <see cref="HttpContext"/> for the current request.</param>
44-
public async Task Invoke(HttpContext context)
44+
public Task Invoke(HttpContext context)
4545
{
4646
if (HttpMethods.IsPost(context.Request.Method))
4747
{
4848
if (_options.FormFieldName != null)
4949
{
5050
if (context.Request.HasFormContentType)
5151
{
52-
var form = await context.Request.ReadFormAsync();
53-
var methodType = form[_options.FormFieldName];
54-
if (!string.IsNullOrEmpty(methodType))
55-
{
56-
context.Request.Method = methodType;
57-
}
52+
return InvokeCore(context);
5853
}
5954
}
6055
else
@@ -66,6 +61,17 @@ public async Task Invoke(HttpContext context)
6661
}
6762
}
6863
}
64+
return _next(context);
65+
}
66+
67+
private async Task InvokeCore(HttpContext context)
68+
{
69+
var form = await context.Request.ReadFormAsync();
70+
var methodType = form[_options.FormFieldName!];
71+
if (!string.IsNullOrEmpty(methodType))
72+
{
73+
context.Request.Method = methodType;
74+
}
6975
await _next(context);
7076
}
7177
}

src/Middleware/ResponseCompression/src/ResponseCompressionMiddleware.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,17 @@ public ResponseCompressionMiddleware(RequestDelegate next, IResponseCompressionP
4444
/// </summary>
4545
/// <param name="context">The <see cref="HttpContext"/>.</param>
4646
/// <returns>A task that represents the execution of this middleware.</returns>
47-
public async Task Invoke(HttpContext context)
47+
public Task Invoke(HttpContext context)
4848
{
4949
if (!_provider.CheckRequestAcceptsCompression(context))
5050
{
51-
await _next(context);
52-
return;
51+
return _next(context);
5352
}
53+
return InvokeCore(context);
54+
}
5455

56+
private async Task InvokeCore(HttpContext context)
57+
{
5558
var originalBodyFeature = context.Features.Get<IHttpResponseBodyFeature>();
5659
var originalCompressionFeature = context.Features.Get<IHttpsCompressionFeature>();
5760

src/Middleware/Spa/SpaProxy/src/SpaProxyMiddleware.cs

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -45,29 +45,31 @@ public SpaProxyMiddleware(
4545
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
4646
}
4747

48-
public async Task Invoke(HttpContext context)
48+
public Task Invoke(HttpContext context)
4949
{
5050
if (context.Request.Path.Equals(new Uri(_options.Value.ServerUrl).LocalPath))
5151
{
52-
context.Response.Headers[HeaderNames.CacheControl] = "no-cache, no-store, must-revalidate, max-age=0";
53-
if (!await _spaProxyLaunchManager.IsSpaProxyRunning(context.RequestAborted))
54-
{
55-
_spaProxyLaunchManager.StartInBackground(_hostLifetime.ApplicationStopping);
56-
_logger.LogInformation("SPA proxy is not ready. Returning temporary landing page.");
57-
context.Response.ContentType = "text/html";
52+
return InvokeCore(context);
53+
}
54+
return _next(context);
55+
}
56+
57+
private async Task InvokeCore(HttpContext context)
58+
{
59+
context.Response.Headers[HeaderNames.CacheControl] = "no-cache, no-store, must-revalidate, max-age=0";
60+
if (!await _spaProxyLaunchManager.IsSpaProxyRunning(context.RequestAborted))
61+
{
62+
_spaProxyLaunchManager.StartInBackground(_hostLifetime.ApplicationStopping);
63+
_logger.LogInformation("SPA proxy is not ready. Returning temporary landing page.");
64+
context.Response.ContentType = "text/html";
5865

59-
await using var writer = new StreamWriter(context.Response.Body, Encoding.UTF8);
60-
await writer.WriteAsync(GenerateSpaLaunchPage(_options.Value));
61-
}
62-
else
63-
{
64-
_logger.LogInformation($"SPA proxy is ready. Redirecting to {_options.Value.ServerUrl}.");
65-
context.Response.Redirect(_options.Value.ServerUrl);
66-
}
66+
await using var writer = new StreamWriter(context.Response.Body, Encoding.UTF8);
67+
await writer.WriteAsync(GenerateSpaLaunchPage(_options.Value));
6768
}
6869
else
6970
{
70-
await _next(context);
71+
_logger.LogInformation($"SPA proxy is ready. Redirecting to {_options.Value.ServerUrl}.");
72+
context.Response.Redirect(_options.Value.ServerUrl);
7173
}
7274

7375
string GenerateSpaLaunchPage(SpaDevelopmentServerOptions options)

src/Middleware/Spa/SpaServices.Extensions/src/Proxying/ConditionalProxyMiddleware.cs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,22 @@ public ConditionalProxyMiddleware(
4343
_applicationStoppingToken = applicationLifetime.ApplicationStopping;
4444
}
4545

46-
public async Task Invoke(HttpContext context)
46+
public Task Invoke(HttpContext context)
4747
{
4848
if (context.Request.Path.StartsWithSegments(_pathPrefix) || _pathPrefixIsRoot)
4949
{
50-
var didProxyRequest = await SpaProxy.PerformProxyRequest(
51-
context, _httpClient, _baseUriTask, _applicationStoppingToken, proxy404s: false);
52-
if (didProxyRequest)
53-
{
54-
return;
55-
}
50+
return InvokeCore(context);
51+
}
52+
return _next.Invoke(context);
53+
}
54+
55+
private async Task InvokeCore(HttpContext context)
56+
{
57+
var didProxyRequest = await SpaProxy.PerformProxyRequest(
58+
context, _httpClient, _baseUriTask, _applicationStoppingToken, proxy404s: false);
59+
if (didProxyRequest)
60+
{
61+
return;
5662
}
5763

5864
// Not a request we can proxy

0 commit comments

Comments
 (0)