Remove all extensibility from the DefaultHttpContext (#6504)
- Seal all of the classes - Remove virtual methods - Delete pooled HttpContext code - Removed obsolete AuthenticationManager
This commit is contained in:
parent
74f1ccad0d
commit
a11c68ae35
|
|
@ -40,14 +40,6 @@ namespace Microsoft.AspNetCore.Http
|
|||
/// </summary>
|
||||
public abstract WebSocketManager WebSockets { get; }
|
||||
|
||||
/// <summary>
|
||||
/// This is obsolete and will be removed in a future version.
|
||||
/// The recommended alternative is to use Microsoft.AspNetCore.Authentication.AuthenticationHttpContextExtensions.
|
||||
/// See https://go.microsoft.com/fwlink/?linkid=845470.
|
||||
/// </summary>
|
||||
[Obsolete("This is obsolete and will be removed in a future version. The recommended alternative is to use Microsoft.AspNetCore.Authentication.AuthenticationHttpContextExtensions. See https://go.microsoft.com/fwlink/?linkid=845470.")]
|
||||
public abstract AuthenticationManager Authentication { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the user for this request.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -1,184 +0,0 @@
|
|||
// 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.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.Http.Features.Authentication;
|
||||
|
||||
namespace Microsoft.AspNetCore.Http.Authentication.Internal
|
||||
{
|
||||
[Obsolete("This is obsolete and will be removed in a future version. See https://go.microsoft.com/fwlink/?linkid=845470.")]
|
||||
public class DefaultAuthenticationManager : AuthenticationManager
|
||||
{
|
||||
// Lambda hoisted to static readonly field to improve inlining https://github.com/dotnet/roslyn/issues/13624
|
||||
private readonly static Func<IFeatureCollection, IHttpAuthenticationFeature> _newAuthenticationFeature = f => new HttpAuthenticationFeature();
|
||||
|
||||
private HttpContext _context;
|
||||
private FeatureReferences<IHttpAuthenticationFeature> _features;
|
||||
|
||||
public DefaultAuthenticationManager(HttpContext context)
|
||||
{
|
||||
Initialize(context);
|
||||
}
|
||||
|
||||
public virtual void Initialize(HttpContext context)
|
||||
{
|
||||
_context = context;
|
||||
_features = new FeatureReferences<IHttpAuthenticationFeature>(context.Features);
|
||||
}
|
||||
|
||||
public virtual void Uninitialize()
|
||||
{
|
||||
_features = default(FeatureReferences<IHttpAuthenticationFeature>);
|
||||
}
|
||||
|
||||
public override HttpContext HttpContext => _context;
|
||||
|
||||
private IHttpAuthenticationFeature HttpAuthenticationFeature =>
|
||||
_features.Fetch(ref _features.Cache, _newAuthenticationFeature);
|
||||
|
||||
public override IEnumerable<AuthenticationDescription> GetAuthenticationSchemes()
|
||||
{
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
var handler = HttpAuthenticationFeature.Handler;
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
if (handler == null)
|
||||
{
|
||||
return new AuthenticationDescription[0];
|
||||
}
|
||||
|
||||
var describeContext = new DescribeSchemesContext();
|
||||
handler.GetDescriptions(describeContext);
|
||||
return describeContext.Results.Select(description => new AuthenticationDescription(description));
|
||||
}
|
||||
|
||||
// Remove once callers have been switched to GetAuthenticateInfoAsync
|
||||
public override async Task AuthenticateAsync(AuthenticateContext context)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(context));
|
||||
}
|
||||
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
var handler = HttpAuthenticationFeature.Handler;
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
if (handler != null)
|
||||
{
|
||||
await handler.AuthenticateAsync(context);
|
||||
}
|
||||
|
||||
if (!context.Accepted)
|
||||
{
|
||||
throw new InvalidOperationException($"No authentication handler is configured to authenticate for the scheme: {context.AuthenticationScheme}");
|
||||
}
|
||||
}
|
||||
|
||||
public override async Task<AuthenticateInfo> GetAuthenticateInfoAsync(string authenticationScheme)
|
||||
{
|
||||
if (authenticationScheme == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(authenticationScheme));
|
||||
}
|
||||
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
var handler = HttpAuthenticationFeature.Handler;
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
var context = new AuthenticateContext(authenticationScheme);
|
||||
if (handler != null)
|
||||
{
|
||||
await handler.AuthenticateAsync(context);
|
||||
}
|
||||
|
||||
if (!context.Accepted)
|
||||
{
|
||||
throw new InvalidOperationException($"No authentication handler is configured to authenticate for the scheme: {context.AuthenticationScheme}");
|
||||
}
|
||||
|
||||
return new AuthenticateInfo
|
||||
{
|
||||
Principal = context.Principal,
|
||||
Properties = new AuthenticationProperties(context.Properties),
|
||||
Description = new AuthenticationDescription(context.Description)
|
||||
};
|
||||
}
|
||||
|
||||
public override async Task ChallengeAsync(string authenticationScheme, AuthenticationProperties properties, ChallengeBehavior behavior)
|
||||
{
|
||||
if (string.IsNullOrEmpty(authenticationScheme))
|
||||
{
|
||||
throw new ArgumentException(nameof(authenticationScheme));
|
||||
}
|
||||
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
var handler = HttpAuthenticationFeature.Handler;
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
|
||||
var challengeContext = new ChallengeContext(authenticationScheme, properties?.Items, behavior);
|
||||
if (handler != null)
|
||||
{
|
||||
await handler.ChallengeAsync(challengeContext);
|
||||
}
|
||||
|
||||
if (!challengeContext.Accepted)
|
||||
{
|
||||
throw new InvalidOperationException($"No authentication handler is configured to handle the scheme: {authenticationScheme}");
|
||||
}
|
||||
}
|
||||
|
||||
public override async Task SignInAsync(string authenticationScheme, ClaimsPrincipal principal, AuthenticationProperties properties)
|
||||
{
|
||||
if (string.IsNullOrEmpty(authenticationScheme))
|
||||
{
|
||||
throw new ArgumentException(nameof(authenticationScheme));
|
||||
}
|
||||
|
||||
if (principal == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(principal));
|
||||
}
|
||||
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
var handler = HttpAuthenticationFeature.Handler;
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
|
||||
var signInContext = new SignInContext(authenticationScheme, principal, properties?.Items);
|
||||
if (handler != null)
|
||||
{
|
||||
await handler.SignInAsync(signInContext);
|
||||
}
|
||||
|
||||
if (!signInContext.Accepted)
|
||||
{
|
||||
throw new InvalidOperationException($"No authentication handler is configured to handle the scheme: {authenticationScheme}");
|
||||
}
|
||||
}
|
||||
|
||||
public override async Task SignOutAsync(string authenticationScheme, AuthenticationProperties properties)
|
||||
{
|
||||
if (string.IsNullOrEmpty(authenticationScheme))
|
||||
{
|
||||
throw new ArgumentException(nameof(authenticationScheme));
|
||||
}
|
||||
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
var handler = HttpAuthenticationFeature.Handler;
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
|
||||
var signOutContext = new SignOutContext(authenticationScheme, properties?.Items);
|
||||
if (handler != null)
|
||||
{
|
||||
await handler.SignOutAsync(signOutContext);
|
||||
}
|
||||
|
||||
if (!signOutContext.Accepted)
|
||||
{
|
||||
throw new InvalidOperationException($"No authentication handler is configured to handle the scheme: {authenticationScheme}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,15 +5,13 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Security.Claims;
|
||||
using System.Threading;
|
||||
using Microsoft.AspNetCore.Http.Authentication;
|
||||
using Microsoft.AspNetCore.Http.Authentication.Internal;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.Http.Features.Authentication;
|
||||
using Microsoft.AspNetCore.Http.Internal;
|
||||
|
||||
namespace Microsoft.AspNetCore.Http
|
||||
{
|
||||
public class DefaultHttpContext : HttpContext
|
||||
public sealed class DefaultHttpContext : HttpContext
|
||||
{
|
||||
// Lambdas hoisted to static readonly fields to improve inlining https://github.com/dotnet/roslyn/issues/13624
|
||||
private readonly static Func<IFeatureCollection, IItemsFeature> _newItemsFeature = f => new ItemsFeature();
|
||||
|
|
@ -26,15 +24,11 @@ namespace Microsoft.AspNetCore.Http
|
|||
|
||||
private FeatureReferences<FeatureInterfaces> _features;
|
||||
|
||||
private HttpRequest _request;
|
||||
private HttpResponse _response;
|
||||
private readonly DefaultHttpRequest _request;
|
||||
private readonly DefaultHttpResponse _response;
|
||||
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
private AuthenticationManager _authenticationManager;
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
|
||||
private ConnectionInfo _connection;
|
||||
private WebSocketManager _websockets;
|
||||
private DefaultConnectionInfo _connection;
|
||||
private DefaultWebSocketManager _websockets;
|
||||
|
||||
public DefaultHttpContext()
|
||||
: this(new FeatureCollection())
|
||||
|
|
@ -45,46 +39,27 @@ namespace Microsoft.AspNetCore.Http
|
|||
|
||||
public DefaultHttpContext(IFeatureCollection features)
|
||||
{
|
||||
Initialize(features);
|
||||
_features = new FeatureReferences<FeatureInterfaces>(features);
|
||||
_request = new DefaultHttpRequest(this);
|
||||
_response = new DefaultHttpResponse(this);
|
||||
}
|
||||
|
||||
public virtual void Initialize(IFeatureCollection features)
|
||||
public void Initialize(IFeatureCollection features)
|
||||
{
|
||||
_features = new FeatureReferences<FeatureInterfaces>(features);
|
||||
_request = InitializeHttpRequest();
|
||||
_response = InitializeHttpResponse();
|
||||
_request.Initialize();
|
||||
_response.Initialize();
|
||||
_connection?.Initialize(features);
|
||||
_websockets?.Initialize(features);
|
||||
}
|
||||
|
||||
public virtual void Uninitialize()
|
||||
public void Uninitialize()
|
||||
{
|
||||
_features = default(FeatureReferences<FeatureInterfaces>);
|
||||
if (_request != null)
|
||||
{
|
||||
UninitializeHttpRequest(_request);
|
||||
_request = null;
|
||||
}
|
||||
if (_response != null)
|
||||
{
|
||||
UninitializeHttpResponse(_response);
|
||||
_response = null;
|
||||
}
|
||||
if (_authenticationManager != null)
|
||||
{
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
UninitializeAuthenticationManager(_authenticationManager);
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
_authenticationManager = null;
|
||||
}
|
||||
if (_connection != null)
|
||||
{
|
||||
UninitializeConnectionInfo(_connection);
|
||||
_connection = null;
|
||||
}
|
||||
if (_websockets != null)
|
||||
{
|
||||
UninitializeWebSocketManager(_websockets);
|
||||
_websockets = null;
|
||||
}
|
||||
_features = default;
|
||||
_request.Uninitialize();
|
||||
_response.Uninitialize();
|
||||
_connection?.Uninitialize();
|
||||
_websockets?.Uninitialize();
|
||||
}
|
||||
|
||||
private IItemsFeature ItemsFeature =>
|
||||
|
|
@ -115,17 +90,9 @@ namespace Microsoft.AspNetCore.Http
|
|||
|
||||
public override HttpResponse Response => _response;
|
||||
|
||||
public override ConnectionInfo Connection => _connection ?? (_connection = InitializeConnectionInfo());
|
||||
public override ConnectionInfo Connection => _connection ?? (_connection = new DefaultConnectionInfo(_features.Collection));
|
||||
|
||||
/// <summary>
|
||||
/// This is obsolete and will be removed in a future version.
|
||||
/// The recommended alternative is to use Microsoft.AspNetCore.Authentication.AuthenticationHttpContextExtensions.
|
||||
/// See https://go.microsoft.com/fwlink/?linkid=845470.
|
||||
/// </summary>
|
||||
[Obsolete("This is obsolete and will be removed in a future version. The recommended alternative is to use Microsoft.AspNetCore.Authentication.AuthenticationHttpContextExtensions. See https://go.microsoft.com/fwlink/?linkid=845470.")]
|
||||
public override AuthenticationManager Authentication => _authenticationManager ?? (_authenticationManager = InitializeAuthenticationManager());
|
||||
|
||||
public override WebSocketManager WebSockets => _websockets ?? (_websockets = InitializeWebSocketManager());
|
||||
public override WebSocketManager WebSockets => _websockets ?? (_websockets = new DefaultWebSocketManager(_features.Collection));
|
||||
|
||||
|
||||
public override ClaimsPrincipal User
|
||||
|
|
@ -186,30 +153,11 @@ namespace Microsoft.AspNetCore.Http
|
|||
}
|
||||
|
||||
|
||||
|
||||
public override void Abort()
|
||||
{
|
||||
LifetimeFeature.Abort();
|
||||
}
|
||||
|
||||
|
||||
protected virtual HttpRequest InitializeHttpRequest() => new DefaultHttpRequest(this);
|
||||
protected virtual void UninitializeHttpRequest(HttpRequest instance) { }
|
||||
|
||||
protected virtual HttpResponse InitializeHttpResponse() => new DefaultHttpResponse(this);
|
||||
protected virtual void UninitializeHttpResponse(HttpResponse instance) { }
|
||||
|
||||
protected virtual ConnectionInfo InitializeConnectionInfo() => new DefaultConnectionInfo(Features);
|
||||
protected virtual void UninitializeConnectionInfo(ConnectionInfo instance) { }
|
||||
|
||||
[Obsolete("This is obsolete and will be removed in a future version. See https://go.microsoft.com/fwlink/?linkid=845470.")]
|
||||
protected virtual AuthenticationManager InitializeAuthenticationManager() => new DefaultAuthenticationManager(this);
|
||||
[Obsolete("This is obsolete and will be removed in a future version. See https://go.microsoft.com/fwlink/?linkid=845470.")]
|
||||
protected virtual void UninitializeAuthenticationManager(AuthenticationManager instance) { }
|
||||
|
||||
protected virtual WebSocketManager InitializeWebSocketManager() => new DefaultWebSocketManager(Features);
|
||||
protected virtual void UninitializeWebSocketManager(WebSocketManager instance) { }
|
||||
|
||||
struct FeatureInterfaces
|
||||
{
|
||||
public IItemsFeature Items;
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ namespace Microsoft.AspNetCore.Http
|
|||
return container.HttpContext;
|
||||
}
|
||||
|
||||
return new ReusableHttpContext(featureCollection);
|
||||
return new DefaultHttpContext(featureCollection);
|
||||
}
|
||||
|
||||
public void Dispose(HttpContext httpContext)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ using Microsoft.AspNetCore.Http.Features;
|
|||
|
||||
namespace Microsoft.AspNetCore.Http.Internal
|
||||
{
|
||||
public class DefaultConnectionInfo : ConnectionInfo
|
||||
public sealed class DefaultConnectionInfo : ConnectionInfo
|
||||
{
|
||||
// Lambdas hoisted to static readonly fields to improve inlining https://github.com/dotnet/roslyn/issues/13624
|
||||
private readonly static Func<IFeatureCollection, IHttpConnectionFeature> _newHttpConnectionFeature = f => new HttpConnectionFeature();
|
||||
|
|
@ -23,14 +23,14 @@ namespace Microsoft.AspNetCore.Http.Internal
|
|||
Initialize(features);
|
||||
}
|
||||
|
||||
public virtual void Initialize( IFeatureCollection features)
|
||||
public void Initialize( IFeatureCollection features)
|
||||
{
|
||||
_features = new FeatureReferences<FeatureInterfaces>(features);
|
||||
}
|
||||
|
||||
public virtual void Uninitialize()
|
||||
public void Uninitialize()
|
||||
{
|
||||
_features = default(FeatureReferences<FeatureInterfaces>);
|
||||
_features = default;
|
||||
}
|
||||
|
||||
private IHttpConnectionFeature HttpConnectionFeature =>
|
||||
|
|
@ -76,7 +76,7 @@ namespace Microsoft.AspNetCore.Http.Internal
|
|||
set { TlsConnectionFeature.ClientCertificate = value; }
|
||||
}
|
||||
|
||||
public override Task<X509Certificate2> GetClientCertificateAsync(CancellationToken cancellationToken = new CancellationToken())
|
||||
public override Task<X509Certificate2> GetClientCertificateAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
return TlsConnectionFeature.GetClientCertificateAsync(cancellationToken);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ using Microsoft.Net.Http.Headers;
|
|||
|
||||
namespace Microsoft.AspNetCore.Http.Internal
|
||||
{
|
||||
public class DefaultHttpRequest : HttpRequest
|
||||
public sealed class DefaultHttpRequest : HttpRequest
|
||||
{
|
||||
// Lambdas hoisted to static readonly fields to improve inlining https://github.com/dotnet/roslyn/issues/13624
|
||||
private readonly static Func<IFeatureCollection, IHttpRequestFeature> _nullRequestFeature = f => null;
|
||||
|
|
@ -22,24 +22,23 @@ namespace Microsoft.AspNetCore.Http.Internal
|
|||
private readonly static Func<IFeatureCollection, IRouteValuesFeature> _newRouteValuesFeature = f => new RouteValuesFeature();
|
||||
private readonly static Func<HttpContext, IRequestBodyPipeFeature> _newRequestBodyPipeFeature = context => new RequestBodyPipeFeature(context);
|
||||
|
||||
private HttpContext _context;
|
||||
private readonly DefaultHttpContext _context;
|
||||
private FeatureReferences<FeatureInterfaces> _features;
|
||||
|
||||
public DefaultHttpRequest(HttpContext context)
|
||||
{
|
||||
Initialize(context);
|
||||
}
|
||||
|
||||
public virtual void Initialize(HttpContext context)
|
||||
public DefaultHttpRequest(DefaultHttpContext context)
|
||||
{
|
||||
_context = context;
|
||||
_features = new FeatureReferences<FeatureInterfaces>(context.Features);
|
||||
_features = new FeatureReferences<FeatureInterfaces>(_context.Features);
|
||||
}
|
||||
|
||||
public virtual void Uninitialize()
|
||||
public void Initialize()
|
||||
{
|
||||
_context = null;
|
||||
_features = default(FeatureReferences<FeatureInterfaces>);
|
||||
_features = new FeatureReferences<FeatureInterfaces>(_context.Features);
|
||||
}
|
||||
|
||||
public void Uninitialize()
|
||||
{
|
||||
_features = default;
|
||||
}
|
||||
|
||||
public override HttpContext HttpContext => _context;
|
||||
|
|
|
|||
|
|
@ -10,31 +10,30 @@ using Microsoft.Net.Http.Headers;
|
|||
|
||||
namespace Microsoft.AspNetCore.Http.Internal
|
||||
{
|
||||
public class DefaultHttpResponse : HttpResponse
|
||||
public sealed class DefaultHttpResponse : HttpResponse
|
||||
{
|
||||
// Lambdas hoisted to static readonly fields to improve inlining https://github.com/dotnet/roslyn/issues/13624
|
||||
private readonly static Func<IFeatureCollection, IHttpResponseFeature> _nullResponseFeature = f => null;
|
||||
private readonly static Func<IFeatureCollection, IResponseCookiesFeature> _newResponseCookiesFeature = f => new ResponseCookiesFeature(f);
|
||||
private readonly static Func<HttpContext, IResponseBodyPipeFeature> _newResponseBodyPipeFeature = context => new ResponseBodyPipeFeature(context);
|
||||
|
||||
private HttpContext _context;
|
||||
private readonly DefaultHttpContext _context;
|
||||
private FeatureReferences<FeatureInterfaces> _features;
|
||||
|
||||
public DefaultHttpResponse(HttpContext context)
|
||||
{
|
||||
Initialize(context);
|
||||
}
|
||||
|
||||
public virtual void Initialize(HttpContext context)
|
||||
public DefaultHttpResponse(DefaultHttpContext context)
|
||||
{
|
||||
_context = context;
|
||||
_features = new FeatureReferences<FeatureInterfaces>(context.Features);
|
||||
_features = new FeatureReferences<FeatureInterfaces>(_context.Features);
|
||||
}
|
||||
|
||||
public virtual void Uninitialize()
|
||||
public void Initialize()
|
||||
{
|
||||
_context = null;
|
||||
_features = default(FeatureReferences<FeatureInterfaces>);
|
||||
_features = new FeatureReferences<FeatureInterfaces>(_context.Features);
|
||||
}
|
||||
|
||||
public void Uninitialize()
|
||||
{
|
||||
_features = default;
|
||||
}
|
||||
|
||||
private IHttpResponseFeature HttpResponseFeature =>
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ using Microsoft.Net.Http.Headers;
|
|||
|
||||
namespace Microsoft.AspNetCore.Http.Internal
|
||||
{
|
||||
public class DefaultWebSocketManager : WebSocketManager
|
||||
public sealed class DefaultWebSocketManager : WebSocketManager
|
||||
{
|
||||
// Lambdas hoisted to static readonly fields to improve inlining https://github.com/dotnet/roslyn/issues/13624
|
||||
private readonly static Func<IFeatureCollection, IHttpRequestFeature> _nullRequestFeature = f => null;
|
||||
|
|
@ -23,14 +23,14 @@ namespace Microsoft.AspNetCore.Http.Internal
|
|||
Initialize(features);
|
||||
}
|
||||
|
||||
public virtual void Initialize(IFeatureCollection features)
|
||||
public void Initialize(IFeatureCollection features)
|
||||
{
|
||||
_features = new FeatureReferences<FeatureInterfaces>(features);
|
||||
}
|
||||
|
||||
public virtual void Uninitialize()
|
||||
public void Uninitialize()
|
||||
{
|
||||
_features = default(FeatureReferences<FeatureInterfaces>);
|
||||
_features = default;
|
||||
}
|
||||
|
||||
private IHttpRequestFeature HttpRequestFeature =>
|
||||
|
|
|
|||
|
|
@ -1,89 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
|
||||
namespace Microsoft.AspNetCore.Http.Internal
|
||||
{
|
||||
public sealed class ReusableConnectionInfo : ConnectionInfo
|
||||
{
|
||||
// Lambdas hoisted to static readonly fields to improve inlining https://github.com/dotnet/roslyn/issues/13624
|
||||
private readonly static Func<IFeatureCollection, IHttpConnectionFeature> _newHttpConnectionFeature = f => new HttpConnectionFeature();
|
||||
private readonly static Func<IFeatureCollection, ITlsConnectionFeature> _newTlsConnectionFeature = f => new TlsConnectionFeature();
|
||||
|
||||
private FeatureReferences<FeatureInterfaces> _features;
|
||||
|
||||
public ReusableConnectionInfo(IFeatureCollection features)
|
||||
{
|
||||
Initialize(features);
|
||||
}
|
||||
|
||||
public void Initialize(IFeatureCollection features)
|
||||
{
|
||||
_features = new FeatureReferences<FeatureInterfaces>(features);
|
||||
}
|
||||
|
||||
public void Uninitialize()
|
||||
{
|
||||
_features = default(FeatureReferences<FeatureInterfaces>);
|
||||
}
|
||||
|
||||
private IHttpConnectionFeature HttpConnectionFeature =>
|
||||
_features.Fetch(ref _features.Cache.Connection, _newHttpConnectionFeature);
|
||||
|
||||
private ITlsConnectionFeature TlsConnectionFeature =>
|
||||
_features.Fetch(ref _features.Cache.TlsConnection, _newTlsConnectionFeature);
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Id
|
||||
{
|
||||
get { return HttpConnectionFeature.ConnectionId; }
|
||||
set { HttpConnectionFeature.ConnectionId = value; }
|
||||
}
|
||||
|
||||
public override IPAddress RemoteIpAddress
|
||||
{
|
||||
get { return HttpConnectionFeature.RemoteIpAddress; }
|
||||
set { HttpConnectionFeature.RemoteIpAddress = value; }
|
||||
}
|
||||
|
||||
public override int RemotePort
|
||||
{
|
||||
get { return HttpConnectionFeature.RemotePort; }
|
||||
set { HttpConnectionFeature.RemotePort = value; }
|
||||
}
|
||||
|
||||
public override IPAddress LocalIpAddress
|
||||
{
|
||||
get { return HttpConnectionFeature.LocalIpAddress; }
|
||||
set { HttpConnectionFeature.LocalIpAddress = value; }
|
||||
}
|
||||
|
||||
public override int LocalPort
|
||||
{
|
||||
get { return HttpConnectionFeature.LocalPort; }
|
||||
set { HttpConnectionFeature.LocalPort = value; }
|
||||
}
|
||||
|
||||
public override X509Certificate2 ClientCertificate
|
||||
{
|
||||
get { return TlsConnectionFeature.ClientCertificate; }
|
||||
set { TlsConnectionFeature.ClientCertificate = value; }
|
||||
}
|
||||
|
||||
public override Task<X509Certificate2> GetClientCertificateAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
return TlsConnectionFeature.GetClientCertificateAsync(cancellationToken);
|
||||
}
|
||||
|
||||
struct FeatureInterfaces
|
||||
{
|
||||
public IHttpConnectionFeature Connection;
|
||||
public ITlsConnectionFeature TlsConnection;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,165 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using Microsoft.AspNetCore.Http.Authentication;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.Http.Features.Authentication;
|
||||
|
||||
namespace Microsoft.AspNetCore.Http.Internal
|
||||
{
|
||||
public sealed class ReusableHttpContext : HttpContext
|
||||
{
|
||||
// Lambdas hoisted to static readonly fields to improve inlining https://github.com/dotnet/roslyn/issues/13624
|
||||
private readonly static Func<IFeatureCollection, IItemsFeature> _newItemsFeature = f => new ItemsFeature();
|
||||
private readonly static Func<IFeatureCollection, IServiceProvidersFeature> _newServiceProvidersFeature = f => new ServiceProvidersFeature();
|
||||
private readonly static Func<IFeatureCollection, IHttpAuthenticationFeature> _newHttpAuthenticationFeature = f => new HttpAuthenticationFeature();
|
||||
private readonly static Func<IFeatureCollection, IHttpRequestLifetimeFeature> _newHttpRequestLifetimeFeature = f => new HttpRequestLifetimeFeature();
|
||||
private readonly static Func<IFeatureCollection, ISessionFeature> _newSessionFeature = f => new DefaultSessionFeature();
|
||||
private readonly static Func<IFeatureCollection, ISessionFeature> _nullSessionFeature = f => null;
|
||||
private readonly static Func<IFeatureCollection, IHttpRequestIdentifierFeature> _newHttpRequestIdentifierFeature = f => new HttpRequestIdentifierFeature();
|
||||
|
||||
private FeatureReferences<FeatureInterfaces> _features;
|
||||
|
||||
private ReusableHttpRequest _request;
|
||||
private ReusableHttpResponse _response;
|
||||
|
||||
private ReusableConnectionInfo _connection;
|
||||
private ReusableWebSocketManager _websockets;
|
||||
|
||||
public ReusableHttpContext(IFeatureCollection features)
|
||||
{
|
||||
_features = new FeatureReferences<FeatureInterfaces>(features);
|
||||
_request = new ReusableHttpRequest(this);
|
||||
_response = new ReusableHttpResponse(this);
|
||||
}
|
||||
|
||||
public void Initialize(IFeatureCollection features)
|
||||
{
|
||||
_features = new FeatureReferences<FeatureInterfaces>(features);
|
||||
_request.Initialize(this);
|
||||
_response.Initialize(this);
|
||||
_connection?.Initialize(features);
|
||||
_websockets?.Initialize(features);
|
||||
}
|
||||
|
||||
public void Uninitialize()
|
||||
{
|
||||
_features = default;
|
||||
|
||||
_request.Uninitialize();
|
||||
_response.Uninitialize();
|
||||
_connection?.Uninitialize();
|
||||
_websockets?.Uninitialize();
|
||||
}
|
||||
|
||||
private IItemsFeature ItemsFeature =>
|
||||
_features.Fetch(ref _features.Cache.Items, _newItemsFeature);
|
||||
|
||||
private IServiceProvidersFeature ServiceProvidersFeature =>
|
||||
_features.Fetch(ref _features.Cache.ServiceProviders, _newServiceProvidersFeature);
|
||||
|
||||
private IHttpAuthenticationFeature HttpAuthenticationFeature =>
|
||||
_features.Fetch(ref _features.Cache.Authentication, _newHttpAuthenticationFeature);
|
||||
|
||||
private IHttpRequestLifetimeFeature LifetimeFeature =>
|
||||
_features.Fetch(ref _features.Cache.Lifetime, _newHttpRequestLifetimeFeature);
|
||||
|
||||
private ISessionFeature SessionFeature =>
|
||||
_features.Fetch(ref _features.Cache.Session, _newSessionFeature);
|
||||
|
||||
private ISessionFeature SessionFeatureOrNull =>
|
||||
_features.Fetch(ref _features.Cache.Session, _nullSessionFeature);
|
||||
|
||||
|
||||
private IHttpRequestIdentifierFeature RequestIdentifierFeature =>
|
||||
_features.Fetch(ref _features.Cache.RequestIdentifier, _newHttpRequestIdentifierFeature);
|
||||
|
||||
public override IFeatureCollection Features => _features.Collection;
|
||||
|
||||
public override HttpRequest Request => _request;
|
||||
|
||||
public override HttpResponse Response => _response;
|
||||
|
||||
public override ConnectionInfo Connection => _connection ?? (_connection = new ReusableConnectionInfo(_features.Collection));
|
||||
|
||||
[Obsolete("This is obsolete and will be removed in a future version. The recommended alternative is to use Microsoft.AspNetCore.Authentication.AuthenticationHttpContextExtensions. See https://go.microsoft.com/fwlink/?linkid=845470.")]
|
||||
public override AuthenticationManager Authentication => throw new NotSupportedException();
|
||||
|
||||
public override WebSocketManager WebSockets => _websockets ?? (_websockets = new ReusableWebSocketManager(_features.Collection));
|
||||
|
||||
|
||||
public override ClaimsPrincipal User
|
||||
{
|
||||
get
|
||||
{
|
||||
var user = HttpAuthenticationFeature.User;
|
||||
if (user == null)
|
||||
{
|
||||
user = new ClaimsPrincipal(new ClaimsIdentity());
|
||||
HttpAuthenticationFeature.User = user;
|
||||
}
|
||||
return user;
|
||||
}
|
||||
set { HttpAuthenticationFeature.User = value; }
|
||||
}
|
||||
|
||||
public override IDictionary<object, object> Items
|
||||
{
|
||||
get { return ItemsFeature.Items; }
|
||||
set { ItemsFeature.Items = value; }
|
||||
}
|
||||
|
||||
public override IServiceProvider RequestServices
|
||||
{
|
||||
get { return ServiceProvidersFeature.RequestServices; }
|
||||
set { ServiceProvidersFeature.RequestServices = value; }
|
||||
}
|
||||
|
||||
public override CancellationToken RequestAborted
|
||||
{
|
||||
get { return LifetimeFeature.RequestAborted; }
|
||||
set { LifetimeFeature.RequestAborted = value; }
|
||||
}
|
||||
|
||||
public override string TraceIdentifier
|
||||
{
|
||||
get { return RequestIdentifierFeature.TraceIdentifier; }
|
||||
set { RequestIdentifierFeature.TraceIdentifier = value; }
|
||||
}
|
||||
|
||||
public override ISession Session
|
||||
{
|
||||
get
|
||||
{
|
||||
var feature = SessionFeatureOrNull;
|
||||
if (feature == null)
|
||||
{
|
||||
throw new InvalidOperationException("Session has not been configured for this application " +
|
||||
"or request.");
|
||||
}
|
||||
return feature.Session;
|
||||
}
|
||||
set
|
||||
{
|
||||
SessionFeature.Session = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Abort()
|
||||
{
|
||||
LifetimeFeature.Abort();
|
||||
}
|
||||
|
||||
struct FeatureInterfaces
|
||||
{
|
||||
public IItemsFeature Items;
|
||||
public IServiceProvidersFeature ServiceProviders;
|
||||
public IHttpAuthenticationFeature Authentication;
|
||||
public IHttpRequestLifetimeFeature Lifetime;
|
||||
public ISessionFeature Session;
|
||||
public IHttpRequestIdentifierFeature RequestIdentifier;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,186 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Pipelines;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace Microsoft.AspNetCore.Http.Internal
|
||||
{
|
||||
public sealed class ReusableHttpRequest : HttpRequest
|
||||
{
|
||||
// Lambdas hoisted to static readonly fields to improve inlining https://github.com/dotnet/roslyn/issues/13624
|
||||
private readonly static Func<IFeatureCollection, IHttpRequestFeature> _nullRequestFeature = f => null;
|
||||
private readonly static Func<IFeatureCollection, IQueryFeature> _newQueryFeature = f => new QueryFeature(f);
|
||||
private readonly static Func<HttpRequest, IFormFeature> _newFormFeature = r => new FormFeature(r);
|
||||
private readonly static Func<IFeatureCollection, IRequestCookiesFeature> _newRequestCookiesFeature = f => new RequestCookiesFeature(f);
|
||||
private readonly static Func<IFeatureCollection, IRouteValuesFeature> _newRouteValuesFeature = f => new RouteValuesFeature();
|
||||
private readonly static Func<HttpContext, IRequestBodyPipeFeature> _newRequestBodyPipeFeature = context => new RequestBodyPipeFeature(context);
|
||||
|
||||
|
||||
private HttpContext _context;
|
||||
private FeatureReferences<FeatureInterfaces> _features;
|
||||
|
||||
public ReusableHttpRequest(HttpContext context)
|
||||
{
|
||||
Initialize(context);
|
||||
}
|
||||
|
||||
public void Initialize(HttpContext context)
|
||||
{
|
||||
_context = context;
|
||||
_features = new FeatureReferences<FeatureInterfaces>(context.Features);
|
||||
}
|
||||
|
||||
public void Uninitialize()
|
||||
{
|
||||
_context = null;
|
||||
_features = default;
|
||||
}
|
||||
|
||||
public override HttpContext HttpContext => _context;
|
||||
|
||||
private IHttpRequestFeature HttpRequestFeature =>
|
||||
_features.Fetch(ref _features.Cache.Request, _nullRequestFeature);
|
||||
|
||||
private IQueryFeature QueryFeature =>
|
||||
_features.Fetch(ref _features.Cache.Query, _newQueryFeature);
|
||||
|
||||
private IFormFeature FormFeature =>
|
||||
_features.Fetch(ref _features.Cache.Form, this, _newFormFeature);
|
||||
|
||||
private IRequestCookiesFeature RequestCookiesFeature =>
|
||||
_features.Fetch(ref _features.Cache.Cookies, _newRequestCookiesFeature);
|
||||
|
||||
private IRouteValuesFeature RouteValuesFeature =>
|
||||
_features.Fetch(ref _features.Cache.RouteValues, _newRouteValuesFeature);
|
||||
|
||||
private IRequestBodyPipeFeature RequestBodyPipeFeature =>
|
||||
_features.Fetch(ref _features.Cache.BodyPipe, this.HttpContext, _newRequestBodyPipeFeature);
|
||||
|
||||
public override PathString PathBase
|
||||
{
|
||||
get { return new PathString(HttpRequestFeature.PathBase); }
|
||||
set { HttpRequestFeature.PathBase = value.Value; }
|
||||
}
|
||||
|
||||
public override PathString Path
|
||||
{
|
||||
get { return new PathString(HttpRequestFeature.Path); }
|
||||
set { HttpRequestFeature.Path = value.Value; }
|
||||
}
|
||||
|
||||
public override QueryString QueryString
|
||||
{
|
||||
get { return new QueryString(HttpRequestFeature.QueryString); }
|
||||
set { HttpRequestFeature.QueryString = value.Value; }
|
||||
}
|
||||
|
||||
public override long? ContentLength
|
||||
{
|
||||
get { return Headers.ContentLength; }
|
||||
set { Headers.ContentLength = value; }
|
||||
}
|
||||
|
||||
public override Stream Body
|
||||
{
|
||||
get { return HttpRequestFeature.Body; }
|
||||
set { HttpRequestFeature.Body = value; }
|
||||
}
|
||||
|
||||
public override string Method
|
||||
{
|
||||
get { return HttpRequestFeature.Method; }
|
||||
set { HttpRequestFeature.Method = value; }
|
||||
}
|
||||
|
||||
public override string Scheme
|
||||
{
|
||||
get { return HttpRequestFeature.Scheme; }
|
||||
set { HttpRequestFeature.Scheme = value; }
|
||||
}
|
||||
|
||||
public override bool IsHttps
|
||||
{
|
||||
get { return string.Equals(Constants.Https, Scheme, StringComparison.OrdinalIgnoreCase); }
|
||||
set { Scheme = value ? Constants.Https : Constants.Http; }
|
||||
}
|
||||
|
||||
public override HostString Host
|
||||
{
|
||||
get { return HostString.FromUriComponent(Headers["Host"]); }
|
||||
set { Headers["Host"] = value.ToUriComponent(); }
|
||||
}
|
||||
|
||||
public override IQueryCollection Query
|
||||
{
|
||||
get { return QueryFeature.Query; }
|
||||
set { QueryFeature.Query = value; }
|
||||
}
|
||||
|
||||
public override string Protocol
|
||||
{
|
||||
get { return HttpRequestFeature.Protocol; }
|
||||
set { HttpRequestFeature.Protocol = value; }
|
||||
}
|
||||
|
||||
public override IHeaderDictionary Headers
|
||||
{
|
||||
get { return HttpRequestFeature.Headers; }
|
||||
}
|
||||
|
||||
public override IRequestCookieCollection Cookies
|
||||
{
|
||||
get { return RequestCookiesFeature.Cookies; }
|
||||
set { RequestCookiesFeature.Cookies = value; }
|
||||
}
|
||||
|
||||
public override string ContentType
|
||||
{
|
||||
get { return Headers[HeaderNames.ContentType]; }
|
||||
set { Headers[HeaderNames.ContentType] = value; }
|
||||
}
|
||||
|
||||
public override bool HasFormContentType
|
||||
{
|
||||
get { return FormFeature.HasFormContentType; }
|
||||
}
|
||||
|
||||
public override IFormCollection Form
|
||||
{
|
||||
get { return FormFeature.ReadForm(); }
|
||||
set { FormFeature.Form = value; }
|
||||
}
|
||||
|
||||
public override Task<IFormCollection> ReadFormAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return FormFeature.ReadFormAsync(cancellationToken);
|
||||
}
|
||||
|
||||
public override RouteValueDictionary RouteValues
|
||||
{
|
||||
get { return RouteValuesFeature.RouteValues; }
|
||||
set { RouteValuesFeature.RouteValues = value; }
|
||||
}
|
||||
|
||||
public override PipeReader BodyPipe
|
||||
{
|
||||
get { return RequestBodyPipeFeature.RequestBodyPipe; }
|
||||
set { RequestBodyPipeFeature.RequestBodyPipe = value; }
|
||||
}
|
||||
|
||||
struct FeatureInterfaces
|
||||
{
|
||||
public IHttpRequestFeature Request;
|
||||
public IQueryFeature Query;
|
||||
public IFormFeature Form;
|
||||
public IRequestCookiesFeature Cookies;
|
||||
public IRouteValuesFeature RouteValues;
|
||||
public IRequestBodyPipeFeature BodyPipe;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,148 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Pipelines;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace Microsoft.AspNetCore.Http.Internal
|
||||
{
|
||||
public sealed class ReusableHttpResponse : HttpResponse
|
||||
{
|
||||
// Lambdas hoisted to static readonly fields to improve inlining https://github.com/dotnet/roslyn/issues/13624
|
||||
private readonly static Func<IFeatureCollection, IHttpResponseFeature> _nullResponseFeature = f => null;
|
||||
private readonly static Func<IFeatureCollection, IResponseCookiesFeature> _newResponseCookiesFeature = f => new ResponseCookiesFeature(f);
|
||||
private readonly static Func<HttpContext, IResponseBodyPipeFeature> _newResponseBodyPipeFeature = context => new ResponseBodyPipeFeature(context);
|
||||
|
||||
private HttpContext _context;
|
||||
private FeatureReferences<FeatureInterfaces> _features;
|
||||
|
||||
public ReusableHttpResponse(HttpContext context)
|
||||
{
|
||||
Initialize(context);
|
||||
}
|
||||
|
||||
public void Initialize(HttpContext context)
|
||||
{
|
||||
_context = context;
|
||||
_features = new FeatureReferences<FeatureInterfaces>(context.Features);
|
||||
}
|
||||
|
||||
public void Uninitialize()
|
||||
{
|
||||
_context = null;
|
||||
_features = default;
|
||||
}
|
||||
|
||||
private IHttpResponseFeature HttpResponseFeature =>
|
||||
_features.Fetch(ref _features.Cache.Response, _nullResponseFeature);
|
||||
|
||||
private IResponseCookiesFeature ResponseCookiesFeature =>
|
||||
_features.Fetch(ref _features.Cache.Cookies, _newResponseCookiesFeature);
|
||||
private IResponseBodyPipeFeature ResponseBodyPipeFeature =>
|
||||
_features.Fetch(ref _features.Cache.BodyPipe, this.HttpContext, _newResponseBodyPipeFeature);
|
||||
|
||||
public override HttpContext HttpContext { get { return _context; } }
|
||||
|
||||
public override int StatusCode
|
||||
{
|
||||
get { return HttpResponseFeature.StatusCode; }
|
||||
set { HttpResponseFeature.StatusCode = value; }
|
||||
}
|
||||
|
||||
public override IHeaderDictionary Headers
|
||||
{
|
||||
get { return HttpResponseFeature.Headers; }
|
||||
}
|
||||
|
||||
public override Stream Body
|
||||
{
|
||||
get { return HttpResponseFeature.Body; }
|
||||
set { HttpResponseFeature.Body = value; }
|
||||
}
|
||||
|
||||
public override long? ContentLength
|
||||
{
|
||||
get { return Headers.ContentLength; }
|
||||
set { Headers.ContentLength = value; }
|
||||
}
|
||||
|
||||
public override string ContentType
|
||||
{
|
||||
get
|
||||
{
|
||||
return Headers[HeaderNames.ContentType];
|
||||
}
|
||||
set
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
HttpResponseFeature.Headers.Remove(HeaderNames.ContentType);
|
||||
}
|
||||
else
|
||||
{
|
||||
HttpResponseFeature.Headers[HeaderNames.ContentType] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override IResponseCookies Cookies
|
||||
{
|
||||
get { return ResponseCookiesFeature.Cookies; }
|
||||
}
|
||||
|
||||
public override PipeWriter BodyPipe
|
||||
{
|
||||
get { return ResponseBodyPipeFeature.ResponseBodyPipe; }
|
||||
set { ResponseBodyPipeFeature.ResponseBodyPipe = value; }
|
||||
}
|
||||
|
||||
public override bool HasStarted
|
||||
{
|
||||
get { return HttpResponseFeature.HasStarted; }
|
||||
}
|
||||
|
||||
public override void OnStarting(Func<object, Task> callback, object state)
|
||||
{
|
||||
if (callback == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(callback));
|
||||
}
|
||||
|
||||
HttpResponseFeature.OnStarting(callback, state);
|
||||
}
|
||||
|
||||
public override void OnCompleted(Func<object, Task> callback, object state)
|
||||
{
|
||||
if (callback == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(callback));
|
||||
}
|
||||
|
||||
HttpResponseFeature.OnCompleted(callback, state);
|
||||
}
|
||||
|
||||
public override void Redirect(string location, bool permanent)
|
||||
{
|
||||
if (permanent)
|
||||
{
|
||||
HttpResponseFeature.StatusCode = 301;
|
||||
}
|
||||
else
|
||||
{
|
||||
HttpResponseFeature.StatusCode = 302;
|
||||
}
|
||||
|
||||
Headers[HeaderNames.Location] = location;
|
||||
}
|
||||
|
||||
struct FeatureInterfaces
|
||||
{
|
||||
public IHttpResponseFeature Response;
|
||||
public IResponseCookiesFeature Cookies;
|
||||
public IResponseBodyPipeFeature BodyPipe;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.WebSockets;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace Microsoft.AspNetCore.Http.Internal
|
||||
{
|
||||
public sealed class ReusableWebSocketManager : WebSocketManager
|
||||
{
|
||||
// Lambdas hoisted to static readonly fields to improve inlining https://github.com/dotnet/roslyn/issues/13624
|
||||
private readonly static Func<IFeatureCollection, IHttpRequestFeature> _nullRequestFeature = f => null;
|
||||
private readonly static Func<IFeatureCollection, IHttpWebSocketFeature> _nullWebSocketFeature = f => null;
|
||||
|
||||
private FeatureReferences<FeatureInterfaces> _features;
|
||||
|
||||
public ReusableWebSocketManager(IFeatureCollection features)
|
||||
{
|
||||
Initialize(features);
|
||||
}
|
||||
|
||||
public void Initialize(IFeatureCollection features)
|
||||
{
|
||||
_features = new FeatureReferences<FeatureInterfaces>(features);
|
||||
}
|
||||
|
||||
public void Uninitialize()
|
||||
{
|
||||
_features = default;
|
||||
}
|
||||
|
||||
private IHttpRequestFeature HttpRequestFeature =>
|
||||
_features.Fetch(ref _features.Cache.Request, _nullRequestFeature);
|
||||
|
||||
private IHttpWebSocketFeature WebSocketFeature =>
|
||||
_features.Fetch(ref _features.Cache.WebSockets, _nullWebSocketFeature);
|
||||
|
||||
public override bool IsWebSocketRequest
|
||||
{
|
||||
get
|
||||
{
|
||||
return WebSocketFeature != null && WebSocketFeature.IsWebSocketRequest;
|
||||
}
|
||||
}
|
||||
|
||||
public override IList<string> WebSocketRequestedProtocols
|
||||
{
|
||||
get
|
||||
{
|
||||
return ParsingHelpers.GetHeaderSplit(HttpRequestFeature.Headers, HeaderNames.WebSocketSubProtocols);
|
||||
}
|
||||
}
|
||||
|
||||
public override Task<WebSocket> AcceptWebSocketAsync(string subProtocol)
|
||||
{
|
||||
if (WebSocketFeature == null)
|
||||
{
|
||||
throw new NotSupportedException("WebSockets are not supported");
|
||||
}
|
||||
return WebSocketFeature.AcceptAsync(new WebSocketAcceptContext() { SubProtocol = subProtocol });
|
||||
}
|
||||
|
||||
struct FeatureInterfaces
|
||||
{
|
||||
public IHttpRequestFeature Request;
|
||||
public IHttpWebSocketFeature WebSockets;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,104 +0,0 @@
|
|||
// 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.
|
||||
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
using System;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http.Features.Authentication;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Http.Authentication.Internal
|
||||
{
|
||||
public class DefaultAuthenticationManagerTests
|
||||
{
|
||||
|
||||
[Fact]
|
||||
public async Task AuthenticateWithNoAuthMiddlewareThrows()
|
||||
{
|
||||
var context = CreateContext();
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(async () => await context.Authentication.AuthenticateAsync("Foo"));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("Automatic")]
|
||||
[InlineData("Foo")]
|
||||
public async Task ChallengeWithNoAuthMiddlewareMayThrow(string scheme)
|
||||
{
|
||||
var context = CreateContext();
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(() => context.Authentication.ChallengeAsync(scheme));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SignInWithNoAuthMiddlewareThrows()
|
||||
{
|
||||
var context = CreateContext();
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(() => context.Authentication.SignInAsync("Foo", new ClaimsPrincipal()));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SignOutWithNoAuthMiddlewareMayThrow()
|
||||
{
|
||||
var context = CreateContext();
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(() => context.Authentication.SignOutAsync("Foo"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SignInOutIn()
|
||||
{
|
||||
var context = CreateContext();
|
||||
var handler = new AuthHandler();
|
||||
context.Features.Set<IHttpAuthenticationFeature>(new HttpAuthenticationFeature() { Handler = handler });
|
||||
var user = new ClaimsPrincipal();
|
||||
await context.Authentication.SignInAsync("ignored", user);
|
||||
Assert.True(handler.SignedIn);
|
||||
await context.Authentication.SignOutAsync("ignored");
|
||||
Assert.False(handler.SignedIn);
|
||||
await context.Authentication.SignInAsync("ignored", user);
|
||||
Assert.True(handler.SignedIn);
|
||||
await context.Authentication.SignOutAsync("ignored", new AuthenticationProperties() { RedirectUri = "~/logout" });
|
||||
Assert.False(handler.SignedIn);
|
||||
}
|
||||
|
||||
private class AuthHandler : IAuthenticationHandler
|
||||
{
|
||||
public bool SignedIn { get; set; }
|
||||
|
||||
public Task AuthenticateAsync(AuthenticateContext context)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task ChallengeAsync(ChallengeContext context)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void GetDescriptions(DescribeSchemesContext context)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task SignInAsync(SignInContext context)
|
||||
{
|
||||
SignedIn = true;
|
||||
context.Accept();
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public Task SignOutAsync(SignOutContext context)
|
||||
{
|
||||
SignedIn = false;
|
||||
context.Accept();
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
}
|
||||
|
||||
private HttpContext CreateContext()
|
||||
{
|
||||
var context = new DefaultHttpContext();
|
||||
return context;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
|
|
@ -193,9 +193,6 @@ namespace System.IO.Pipelines.Tests
|
|||
TestCachedFeaturesAreNull(context, features);
|
||||
TestCachedFeaturesAreNull(context.Request, features);
|
||||
TestCachedFeaturesAreNull(context.Response, features);
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
TestCachedFeaturesAreNull(context.Authentication, features);
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
TestCachedFeaturesAreNull(context.Connection, features);
|
||||
TestCachedFeaturesAreNull(context.WebSockets, features);
|
||||
}
|
||||
|
|
@ -224,9 +221,6 @@ namespace System.IO.Pipelines.Tests
|
|||
TestCachedFeaturesAreSet(context, features);
|
||||
TestCachedFeaturesAreSet(context.Request, features);
|
||||
TestCachedFeaturesAreSet(context.Response, features);
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
TestCachedFeaturesAreSet(context.Authentication, features);
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
TestCachedFeaturesAreSet(context.Connection, features);
|
||||
TestCachedFeaturesAreSet(context.WebSockets, features);
|
||||
}
|
||||
|
|
@ -350,4 +344,4 @@ namespace System.IO.Pipelines.Tests
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,54 +0,0 @@
|
|||
// 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.
|
||||
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.Http.Internal;
|
||||
|
||||
namespace SampleApp
|
||||
{
|
||||
public class PooledHttpContext : DefaultHttpContext
|
||||
{
|
||||
DefaultHttpRequest _pooledHttpRequest;
|
||||
DefaultHttpResponse _pooledHttpResponse;
|
||||
|
||||
public PooledHttpContext(IFeatureCollection featureCollection) :
|
||||
base(featureCollection)
|
||||
{
|
||||
}
|
||||
|
||||
protected override HttpRequest InitializeHttpRequest()
|
||||
{
|
||||
if (_pooledHttpRequest != null)
|
||||
{
|
||||
_pooledHttpRequest.Initialize(this);
|
||||
return _pooledHttpRequest;
|
||||
}
|
||||
|
||||
return new DefaultHttpRequest(this);
|
||||
}
|
||||
|
||||
protected override void UninitializeHttpRequest(HttpRequest instance)
|
||||
{
|
||||
_pooledHttpRequest = instance as DefaultHttpRequest;
|
||||
_pooledHttpRequest?.Uninitialize();
|
||||
}
|
||||
|
||||
protected override HttpResponse InitializeHttpResponse()
|
||||
{
|
||||
if (_pooledHttpResponse != null)
|
||||
{
|
||||
_pooledHttpResponse.Initialize(this);
|
||||
return _pooledHttpResponse;
|
||||
}
|
||||
|
||||
return new DefaultHttpResponse(this);
|
||||
}
|
||||
|
||||
protected override void UninitializeHttpResponse(HttpResponse instance)
|
||||
{
|
||||
_pooledHttpResponse = instance as DefaultHttpResponse;
|
||||
_pooledHttpResponse?.Uninitialize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
// 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.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.Extensions.ObjectPool;
|
||||
|
||||
namespace SampleApp
|
||||
{
|
||||
public class PooledHttpContextFactory : IHttpContextFactory
|
||||
{
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private readonly Stack<PooledHttpContext> _pool = new Stack<PooledHttpContext>();
|
||||
|
||||
public PooledHttpContextFactory(ObjectPoolProvider poolProvider)
|
||||
: this(poolProvider, httpContextAccessor: null)
|
||||
{
|
||||
}
|
||||
|
||||
public PooledHttpContextFactory(ObjectPoolProvider poolProvider, IHttpContextAccessor httpContextAccessor)
|
||||
{
|
||||
if (poolProvider == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(poolProvider));
|
||||
}
|
||||
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
}
|
||||
|
||||
public HttpContext Create(IFeatureCollection featureCollection)
|
||||
{
|
||||
if (featureCollection == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(featureCollection));
|
||||
}
|
||||
|
||||
PooledHttpContext httpContext = null;
|
||||
lock (_pool)
|
||||
{
|
||||
if (_pool.Count != 0)
|
||||
{
|
||||
httpContext = _pool.Pop();
|
||||
}
|
||||
}
|
||||
|
||||
if (httpContext == null)
|
||||
{
|
||||
httpContext = new PooledHttpContext(featureCollection);
|
||||
}
|
||||
else
|
||||
{
|
||||
httpContext.Initialize(featureCollection);
|
||||
}
|
||||
|
||||
if (_httpContextAccessor != null)
|
||||
{
|
||||
_httpContextAccessor.HttpContext = httpContext;
|
||||
}
|
||||
return httpContext;
|
||||
}
|
||||
|
||||
public void Dispose(HttpContext httpContext)
|
||||
{
|
||||
if (_httpContextAccessor != null)
|
||||
{
|
||||
_httpContextAccessor.HttpContext = null;
|
||||
}
|
||||
|
||||
var pooled = httpContext as PooledHttpContext;
|
||||
if (pooled != null)
|
||||
{
|
||||
pooled.Uninitialize();
|
||||
lock (_pool)
|
||||
{
|
||||
_pool.Push(pooled);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -64,7 +64,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
private long _responseBytesWritten;
|
||||
|
||||
private readonly HttpConnectionContext _context;
|
||||
private ReusableHttpContext _httpContext;
|
||||
private DefaultHttpContext _httpContext;
|
||||
|
||||
protected string _methodText = null;
|
||||
private string _scheme = null;
|
||||
|
|
@ -283,7 +283,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
{
|
||||
if (_httpContext is null)
|
||||
{
|
||||
_httpContext = new ReusableHttpContext(this);
|
||||
_httpContext = new DefaultHttpContext(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue