diff --git a/src/Middleware/Session/Session.slnf b/src/Middleware/Session/Session.slnf new file mode 100644 index 0000000000..9879434470 --- /dev/null +++ b/src/Middleware/Session/Session.slnf @@ -0,0 +1,42 @@ +{ + "solution": { + "path": "..\\Middleware.sln", + "projects": [ + "..\\DataProtection\\Abstractions\\src\\Microsoft.AspNetCore.DataProtection.Abstractions.csproj", + "..\\DataProtection\\Cryptography.Internal\\src\\Microsoft.AspNetCore.Cryptography.Internal.csproj", + "..\\DataProtection\\DataProtection\\src\\Microsoft.AspNetCore.DataProtection.csproj", + "..\\DefaultBuilder\\src\\Microsoft.AspNetCore.csproj", + "..\\Hosting\\Abstractions\\src\\Microsoft.AspNetCore.Hosting.Abstractions.csproj", + "..\\Hosting\\Hosting\\src\\Microsoft.AspNetCore.Hosting.csproj", + "..\\Hosting\\Server.Abstractions\\src\\Microsoft.AspNetCore.Hosting.Server.Abstractions.csproj", + "..\\Hosting\\Server.IntegrationTesting\\src\\Microsoft.AspNetCore.Server.IntegrationTesting.csproj", + "..\\Hosting\\TestHost\\src\\Microsoft.AspNetCore.TestHost.csproj", + "..\\Http\\Authentication.Abstractions\\src\\Microsoft.AspNetCore.Authentication.Abstractions.csproj", + "..\\Http\\Authentication.Core\\src\\Microsoft.AspNetCore.Authentication.Core.csproj", + "..\\Http\\Http.Abstractions\\src\\Microsoft.AspNetCore.Http.Abstractions.csproj", + "..\\Http\\Http.Extensions\\src\\Microsoft.AspNetCore.Http.Extensions.csproj", + "..\\Http\\Http.Features\\src\\Microsoft.AspNetCore.Http.Features.csproj", + "..\\Http\\Metadata\\src\\Microsoft.AspNetCore.Metadata.csproj", + "..\\Http\\Routing.Abstractions\\src\\Microsoft.AspNetCore.Routing.Abstractions.csproj", + "..\\Http\\WebUtilities\\src\\Microsoft.AspNetCore.WebUtilities.csproj", + "..\\Security\\Authorization\\Core\\src\\Microsoft.AspNetCore.Authorization.csproj", + "..\\Servers\\Connections.Abstractions\\src\\Microsoft.AspNetCore.Connections.Abstractions.csproj", + "..\\Servers\\HttpSys\\src\\Microsoft.AspNetCore.Server.HttpSys.csproj", + "..\\Servers\\IIS\\IISIntegration\\src\\Microsoft.AspNetCore.Server.IISIntegration.csproj", + "..\\Servers\\IIS\\IIS\\src\\Microsoft.AspNetCore.Server.IIS.csproj", + "..\\Servers\\Kestrel\\Core\\src\\Microsoft.AspNetCore.Server.Kestrel.Core.csproj", + "..\\Servers\\Kestrel\\Kestrel\\src\\Microsoft.AspNetCore.Server.Kestrel.csproj", + "..\\Servers\\Kestrel\\Transport.Sockets\\src\\Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.csproj", + "..\\http\\Headers\\src\\Microsoft.Net.Http.Headers.csproj", + "..\\http\\Routing\\src\\Microsoft.AspNetCore.Routing.csproj", + "..\\http\\http\\src\\Microsoft.AspNetCore.Http.csproj", + "Diagnostics.Abstractions\\src\\Microsoft.AspNetCore.Diagnostics.Abstractions.csproj", + "Diagnostics\\src\\Microsoft.AspNetCore.Diagnostics.csproj", + "HostFiltering\\src\\Microsoft.AspNetCore.HostFiltering.csproj", + "HttpOverrides\\src\\Microsoft.AspNetCore.HttpOverrides.csproj", + "Session\\samples\\SessionSample.csproj", + "Session\\src\\Microsoft.AspNetCore.Session.csproj", + "Session\\test\\Microsoft.AspNetCore.Session.Tests.csproj" + ] + } +} \ No newline at end of file diff --git a/src/Middleware/Session/src/SessionMiddleware.cs b/src/Middleware/Session/src/SessionMiddleware.cs index 796bdbde79..8d632c08f9 100644 --- a/src/Middleware/Session/src/SessionMiddleware.cs +++ b/src/Middleware/Session/src/SessionMiddleware.cs @@ -115,7 +115,7 @@ namespace Microsoft.AspNetCore.Session { try { - await feature.Session.CommitAsync(context.RequestAborted); + await feature.Session.CommitAsync(); } catch (OperationCanceledException) { diff --git a/src/Middleware/Session/test/SessionTests.cs b/src/Middleware/Session/test/SessionTests.cs index f98a018bc5..1b0a55e447 100644 --- a/src/Middleware/Session/test/SessionTests.cs +++ b/src/Middleware/Session/test/SessionTests.cs @@ -855,7 +855,6 @@ namespace Microsoft.AspNetCore.Session var token = cts.Token; cts.Cancel(); await Assert.ThrowsAsync(() => context.Session.CommitAsync(token)); - context.RequestAborted = token; }); }) .ConfigureServices(services => @@ -875,12 +874,73 @@ namespace Microsoft.AspNetCore.Session response.EnsureSuccessStatusCode(); } - Assert.Empty(sink.Writes.Where(message => message.LoggerName.Equals(typeof(DistributedSession).FullName, StringComparison.Ordinal))); + // The session is automatically committed on unwind even after the manual commit was canceled. + var sessionLogMessages = sink.Writes.Where(message => message.LoggerName.Equals(typeof(DistributedSession).FullName, StringComparison.Ordinal)).ToList(); - var sessionMiddlewareLogs = sink.Writes.Where(message => message.LoggerName.Equals(typeof(SessionMiddleware).FullName, StringComparison.Ordinal)).ToList(); + Assert.Contains("Session started", sessionLogMessages[0].State.ToString()); + Assert.Equal(LogLevel.Information, sessionLogMessages[0].LogLevel); - Assert.Contains("Committing the session was canceled.", sessionMiddlewareLogs[0].State.ToString()); - Assert.Equal(LogLevel.Information, sessionMiddlewareLogs[0].LogLevel); + Assert.Contains("Session stored", sessionLogMessages[1].State.ToString()); + Assert.Equal(LogLevel.Debug, sessionLogMessages[1].LogLevel); + + Assert.Empty(sink.Writes.Where(message => message.LoggerName.Equals(typeof(SessionMiddleware).FullName, StringComparison.Ordinal))); + } + + [Fact] + public async Task RequestAbortedIgnored() + { + var sink = new TestSink( + writeContext => + { + return writeContext.LoggerName.Equals(typeof(SessionMiddleware).FullName) + || writeContext.LoggerName.Equals(typeof(DistributedSession).FullName); + }, + beginScopeContext => + { + return beginScopeContext.LoggerName.Equals(typeof(SessionMiddleware).FullName) + || beginScopeContext.LoggerName.Equals(typeof(DistributedSession).FullName); + }); + var loggerFactory = new TestLoggerFactory(sink, enabled: true); + var builder = new WebHostBuilder() + .Configure(app => + { + app.UseSession(); + app.Run(context => + { + context.Session.SetInt32("key", 0); + var cts = new CancellationTokenSource(); + var token = cts.Token; + cts.Cancel(); + context.RequestAborted = token; + return Task.CompletedTask; + }); + }) + .ConfigureServices(services => + { + services.AddSingleton(typeof(ILoggerFactory), loggerFactory); + services.AddSingleton(new UnreliableCache(new MemoryCache(new MemoryCacheOptions())) + { + DelaySetAsync = true + }); + services.AddSession(); + }); + + using (var server = new TestServer(builder)) + { + var client = server.CreateClient(); + var response = await client.GetAsync(string.Empty); + response.EnsureSuccessStatusCode(); + } + + var sessionLogMessages = sink.Writes.Where(message => message.LoggerName.Equals(typeof(DistributedSession).FullName, StringComparison.Ordinal)).ToList(); + + Assert.Contains("Session started", sessionLogMessages[0].State.ToString()); + Assert.Equal(LogLevel.Information, sessionLogMessages[0].LogLevel); + + Assert.Contains("Session stored", sessionLogMessages[1].State.ToString()); + Assert.Equal(LogLevel.Debug, sessionLogMessages[1].LogLevel); + + Assert.Empty(sink.Writes.Where(message => message.LoggerName.Equals(typeof(SessionMiddleware).FullName, StringComparison.Ordinal))); } [Fact]