Skip to content

Use TimeProvider to set HttpContext.Timestamp #408

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,13 @@ public RemoteAppAuthenticationAuthHandler(IRemoteAppAuthenticationService authSe
IEnumerable<IRemoteAppAuthenticationResultProcessor> resultProcessors,
IOptionsMonitor<RemoteAppAuthenticationClientOptions> options,
ILoggerFactory loggerFactory,
UrlEncoder encoder,
ISystemClock clock)
UrlEncoder encoder
#if NET8_0_OR_GREATER
) : base(options, loggerFactory, encoder)
#else
, ISystemClock clock)
: base(options, loggerFactory, encoder, clock)
#endif
{
_logger = loggerFactory.CreateLogger<RemoteAppAuthenticationAuthHandler>();
_authService = authService;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Net.Http;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;

namespace Microsoft.AspNetCore.SystemWebAdapters.Authentication;

Expand Down Expand Up @@ -44,7 +45,7 @@ public async Task<RemoteAppAuthenticationResult> CreateRemoteAppAuthenticationRe
{
if (forwardAllResponseHeaders || options.ResponseHeadersToForward.Contains(responseHeader.Key))
{
ret.ResponseHeaders.Add(responseHeader.Key, responseHeader.Value.ToArray());
ret.ResponseHeaders.AppendList(responseHeader.Key, responseHeader.Value.ToList());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public Task ProcessAsync(RemoteAppAuthenticationResult result, HttpContext conte
}
}
result.ResponseHeaders.Remove(LocationHeaderName);
result.ResponseHeaders.Add(LocationHeaderName, processedRedirectLocations.ToArray());
result.ResponseHeaders.AppendList(LocationHeaderName, processedRedirectLocations);
}

return Task.CompletedTask;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
<TargetFrameworks>net6.0;net7.0;net8.0</TargetFrameworks>
<IsPackable>true</IsPackable>
<EnablePackageValidation>true</EnablePackageValidation>
<RootNamespace>Microsoft.AspNetCore.SystemWebAdapters</RootNamespace>
Expand All @@ -16,6 +16,9 @@
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net6.0' OR '$(TargetFramework)' == 'net7.0' ">
<PackageReference Include="Microsoft.Bcl.TimeProvider" Version="8.0.0-rc.1.23419.4" />
</ItemGroup>
<ItemGroup>
<Using Include="Microsoft.AspNetCore.Http.HttpContext" Alias="HttpContextCore" />
<Using Include="Microsoft.AspNetCore.Http.HttpResponse" Alias="HttpResponseCore" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.SystemWebAdapters.SessionState.Serialization;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
Expand Down Expand Up @@ -130,7 +131,7 @@ private static void PropagateHeaders(HttpResponseMessage responseMessage, HttpCo
{
if (context?.Response is not null && responseMessage.Headers.TryGetValues(cookieName, out var cookieValues))
{
context.Response.Headers.Add(cookieName, cookieValues.ToArray());
context.Response.Headers.AppendList(cookieName, cookieValues.ToArray());
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;

Expand All @@ -9,14 +10,26 @@ namespace Microsoft.AspNetCore.SystemWebAdapters;
internal class SetHttpContextTimestampMiddleware
{
private readonly RequestDelegate _next;
private readonly TimeProvider _timeProvider;

public SetHttpContextTimestampMiddleware(RequestDelegate next) => _next = next;
public SetHttpContextTimestampMiddleware(TimeProvider timeProvider, RequestDelegate next)
{
_timeProvider = timeProvider;
_next = next;
}

public Task InvokeAsync(HttpContext context)
{
// Ensure adapter is created to force timestamp to be set
_ = context.GetAdapter();
context.Features.Set<TimestampFeature>(new(_timeProvider));

return _next(context);
}

private sealed class TimestampFeature : ITimestampFeature
{
public TimestampFeature(TimeProvider timeProvider)
=> Timestamp = timeProvider.GetLocalNow();

public DateTimeOffset Timestamp { get; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.SystemWebAdapters;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;

namespace Microsoft.Extensions.DependencyInjection;
Expand All @@ -17,6 +18,7 @@ public static class SystemWebAdaptersExtensions
public static ISystemWebAdapterBuilder AddSystemWebAdapters(this IServiceCollection services)
{
services.AddHttpContextAccessor();
services.TryAddSingleton(TimeProvider.System);
services.AddSingleton<Cache>();
services.AddSingleton<IBrowserCapabilitiesFactory, BrowserCapabilitiesFactory>();
services.AddTransient<IStartupFilter, HttpContextStartupFilter>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#if NET6_0_OR_GREATER
using System;

namespace Microsoft.AspNetCore.SystemWebAdapters;

internal interface ITimestampFeature
{
DateTimeOffset Timestamp { get; }
}
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ internal HttpContext() { }
public System.Web.HttpResponse Response { get { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");} }
public System.Web.HttpServerUtility Server { get { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");} }
public System.Web.SessionState.HttpSessionState Session { get { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");} }
public System.DateTime Timestamp { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");} }
public System.DateTime Timestamp { get { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");} }
public System.Web.TraceContext Trace { get { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");} }
public System.Security.Principal.IPrincipal User { get { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");} set { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");} }
public void AddError(System.Exception ex) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.AspNetCore.SystemWebAdapters/HttpContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public IPrincipal User

public HttpSessionState? Session => _context.Features.Get<HttpSessionState>();

public DateTime Timestamp { get; } = DateTime.UtcNow.ToLocalTime();
public DateTime Timestamp => _context.Features.GetRequired<ITimestampFeature>().Timestamp.DateTime;

public void RewritePath(string path) => RewritePath(path, true);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0</TargetFrameworks>
<TargetFrameworks>net6.0;net8.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Autofac.Extras.Moq" Version="6.0.0" />
Expand Down