diff --git a/src/Http/Http.Features/src/IResponseCookies.cs b/src/Http/Http.Features/src/IResponseCookies.cs index 9c8c3b42bab9..b41153d131a0 100644 --- a/src/Http/Http.Features/src/IResponseCookies.cs +++ b/src/Http/Http.Features/src/IResponseCookies.cs @@ -1,6 +1,11 @@ // 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. +#if NET6_0_OR_GREATER +using System; +using System.Collections.Generic; +#endif + namespace Microsoft.AspNetCore.Http { /// @@ -23,6 +28,21 @@ public interface IResponseCookies /// included in the new cookie setting. void Append(string key, string value, CookieOptions options); +#if NET6_0_OR_GREATER + /// + /// Add elements of specified collection as cookies. + /// + /// Key value pair collections whose elements will be added as cookies. + /// included in new cookie settings. + void Append(ReadOnlySpan> keyValuePairs, CookieOptions options) + { + foreach (var keyValuePair in keyValuePairs) + { + Append(keyValuePair.Key, keyValuePair.Value, options); + } + } +#endif + /// /// Sets an expired cookie. /// diff --git a/src/Http/Http.Features/src/Microsoft.AspNetCore.Http.Features.csproj b/src/Http/Http.Features/src/Microsoft.AspNetCore.Http.Features.csproj index 29f075d6dc70..7aad17f6cd07 100644 --- a/src/Http/Http.Features/src/Microsoft.AspNetCore.Http.Features.csproj +++ b/src/Http/Http.Features/src/Microsoft.AspNetCore.Http.Features.csproj @@ -1,4 +1,4 @@ - + ASP.NET Core HTTP feature interface definitions. @@ -10,10 +10,14 @@ enable - + + + + + diff --git a/src/Http/Http.Features/src/PublicAPI.Shipped.txt b/src/Http/Http.Features/src/PublicAPI/net461/PublicAPI.Shipped.txt similarity index 100% rename from src/Http/Http.Features/src/PublicAPI.Shipped.txt rename to src/Http/Http.Features/src/PublicAPI/net461/PublicAPI.Shipped.txt diff --git a/src/Http/Http.Features/src/PublicAPI.Unshipped.txt b/src/Http/Http.Features/src/PublicAPI/net461/PublicAPI.Unshipped.txt similarity index 97% rename from src/Http/Http.Features/src/PublicAPI.Unshipped.txt rename to src/Http/Http.Features/src/PublicAPI/net461/PublicAPI.Unshipped.txt index 5b914c27b50f..4cc6095ff65a 100644 --- a/src/Http/Http.Features/src/PublicAPI.Unshipped.txt +++ b/src/Http/Http.Features/src/PublicAPI/net461/PublicAPI.Unshipped.txt @@ -14,4 +14,4 @@ Microsoft.AspNetCore.Http.Features.IFeatureCollection.Get() -> TFeatur Microsoft.AspNetCore.Http.Features.IFeatureCollection.Set(TFeature? instance) -> void Microsoft.AspNetCore.Http.Features.IServerVariablesFeature.this[string! variableName].get -> string? Microsoft.AspNetCore.Http.ISession.TryGetValue(string! key, out byte[]? value) -> bool -Microsoft.AspNetCore.Http.Features.FeatureCollection.FeatureCollection(int initialCapacity) -> void \ No newline at end of file +Microsoft.AspNetCore.Http.Features.FeatureCollection.FeatureCollection(int initialCapacity) -> void diff --git a/src/Http/Http.Features/src/PublicAPI/net6.0/PublicAPI.Shipped.txt b/src/Http/Http.Features/src/PublicAPI/net6.0/PublicAPI.Shipped.txt new file mode 100644 index 000000000000..f97bf2426e2e --- /dev/null +++ b/src/Http/Http.Features/src/PublicAPI/net6.0/PublicAPI.Shipped.txt @@ -0,0 +1,247 @@ +#nullable enable +Microsoft.AspNetCore.Http.CookieOptions +Microsoft.AspNetCore.Http.CookieOptions.CookieOptions() -> void +Microsoft.AspNetCore.Http.CookieOptions.Domain.get -> string? +Microsoft.AspNetCore.Http.CookieOptions.Domain.set -> void +Microsoft.AspNetCore.Http.CookieOptions.Expires.get -> System.DateTimeOffset? +Microsoft.AspNetCore.Http.CookieOptions.Expires.set -> void +Microsoft.AspNetCore.Http.CookieOptions.HttpOnly.get -> bool +Microsoft.AspNetCore.Http.CookieOptions.HttpOnly.set -> void +Microsoft.AspNetCore.Http.CookieOptions.IsEssential.get -> bool +Microsoft.AspNetCore.Http.CookieOptions.IsEssential.set -> void +Microsoft.AspNetCore.Http.CookieOptions.MaxAge.get -> System.TimeSpan? +Microsoft.AspNetCore.Http.CookieOptions.MaxAge.set -> void +Microsoft.AspNetCore.Http.CookieOptions.Path.get -> string? +Microsoft.AspNetCore.Http.CookieOptions.Path.set -> void +Microsoft.AspNetCore.Http.CookieOptions.SameSite.get -> Microsoft.AspNetCore.Http.SameSiteMode +Microsoft.AspNetCore.Http.CookieOptions.SameSite.set -> void +Microsoft.AspNetCore.Http.CookieOptions.Secure.get -> bool +Microsoft.AspNetCore.Http.CookieOptions.Secure.set -> void +Microsoft.AspNetCore.Http.Features.Authentication.IHttpAuthenticationFeature +Microsoft.AspNetCore.Http.Features.Authentication.IHttpAuthenticationFeature.User.get -> System.Security.Claims.ClaimsPrincipal? +Microsoft.AspNetCore.Http.Features.Authentication.IHttpAuthenticationFeature.User.set -> void +Microsoft.AspNetCore.Http.Features.FeatureCollection +Microsoft.AspNetCore.Http.Features.FeatureCollection.FeatureCollection() -> void +Microsoft.AspNetCore.Http.Features.FeatureCollection.FeatureCollection(Microsoft.AspNetCore.Http.Features.IFeatureCollection! defaults) -> void +Microsoft.AspNetCore.Http.Features.FeatureCollection.Get() -> TFeature? +Microsoft.AspNetCore.Http.Features.FeatureCollection.GetEnumerator() -> System.Collections.Generic.IEnumerator>! +Microsoft.AspNetCore.Http.Features.FeatureCollection.IsReadOnly.get -> bool +Microsoft.AspNetCore.Http.Features.FeatureCollection.Set(TFeature instance) -> void +Microsoft.AspNetCore.Http.Features.FeatureCollection.this[System.Type! key].get -> object? +Microsoft.AspNetCore.Http.Features.FeatureCollection.this[System.Type! key].set -> void +Microsoft.AspNetCore.Http.Features.FeatureReference +Microsoft.AspNetCore.Http.Features.FeatureReference.Fetch(Microsoft.AspNetCore.Http.Features.IFeatureCollection! features) -> T? +Microsoft.AspNetCore.Http.Features.FeatureReference.Update(Microsoft.AspNetCore.Http.Features.IFeatureCollection! features, T feature) -> T +Microsoft.AspNetCore.Http.Features.FeatureReferences +Microsoft.AspNetCore.Http.Features.FeatureReferences.Cache -> TCache? +Microsoft.AspNetCore.Http.Features.FeatureReferences.Collection.get -> Microsoft.AspNetCore.Http.Features.IFeatureCollection! +Microsoft.AspNetCore.Http.Features.FeatureReferences.FeatureReferences(Microsoft.AspNetCore.Http.Features.IFeatureCollection! collection) -> void +Microsoft.AspNetCore.Http.Features.FeatureReferences.Fetch(ref TFeature? cached, TState state, System.Func! factory) -> TFeature? +Microsoft.AspNetCore.Http.Features.FeatureReferences.Fetch(ref TFeature? cached, System.Func! factory) -> TFeature? +Microsoft.AspNetCore.Http.Features.FeatureReferences.Initalize(Microsoft.AspNetCore.Http.Features.IFeatureCollection! collection) -> void +Microsoft.AspNetCore.Http.Features.FeatureReferences.Initalize(Microsoft.AspNetCore.Http.Features.IFeatureCollection! collection, int revision) -> void +Microsoft.AspNetCore.Http.Features.FeatureReferences.Revision.get -> int +Microsoft.AspNetCore.Http.Features.HttpsCompressionMode +Microsoft.AspNetCore.Http.Features.HttpsCompressionMode.Compress = 2 -> Microsoft.AspNetCore.Http.Features.HttpsCompressionMode +Microsoft.AspNetCore.Http.Features.HttpsCompressionMode.Default = 0 -> Microsoft.AspNetCore.Http.Features.HttpsCompressionMode +Microsoft.AspNetCore.Http.Features.HttpsCompressionMode.DoNotCompress = 1 -> Microsoft.AspNetCore.Http.Features.HttpsCompressionMode +Microsoft.AspNetCore.Http.Features.IFeatureCollection +Microsoft.AspNetCore.Http.Features.IFeatureCollection.Get() -> TFeature +Microsoft.AspNetCore.Http.Features.IFeatureCollection.IsReadOnly.get -> bool +Microsoft.AspNetCore.Http.Features.IFeatureCollection.Revision.get -> int +Microsoft.AspNetCore.Http.Features.IFeatureCollection.Set(TFeature instance) -> void +Microsoft.AspNetCore.Http.Features.IFeatureCollection.this[System.Type! key].get -> object? +Microsoft.AspNetCore.Http.Features.IFeatureCollection.this[System.Type! key].set -> void +Microsoft.AspNetCore.Http.Features.IFormFeature +Microsoft.AspNetCore.Http.Features.IFormFeature.Form.get -> Microsoft.AspNetCore.Http.IFormCollection? +Microsoft.AspNetCore.Http.Features.IFormFeature.Form.set -> void +Microsoft.AspNetCore.Http.Features.IFormFeature.HasFormContentType.get -> bool +Microsoft.AspNetCore.Http.Features.IFormFeature.ReadForm() -> Microsoft.AspNetCore.Http.IFormCollection! +Microsoft.AspNetCore.Http.Features.IFormFeature.ReadFormAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task! +Microsoft.AspNetCore.Http.Features.IHttpBodyControlFeature +Microsoft.AspNetCore.Http.Features.IHttpBodyControlFeature.AllowSynchronousIO.get -> bool +Microsoft.AspNetCore.Http.Features.IHttpBodyControlFeature.AllowSynchronousIO.set -> void +Microsoft.AspNetCore.Http.Features.IHttpBufferingFeature +Microsoft.AspNetCore.Http.Features.IHttpBufferingFeature.DisableRequestBuffering() -> void +Microsoft.AspNetCore.Http.Features.IHttpBufferingFeature.DisableResponseBuffering() -> void +Microsoft.AspNetCore.Http.Features.IHttpConnectionFeature +Microsoft.AspNetCore.Http.Features.IHttpConnectionFeature.ConnectionId.get -> string! +Microsoft.AspNetCore.Http.Features.IHttpConnectionFeature.ConnectionId.set -> void +Microsoft.AspNetCore.Http.Features.IHttpConnectionFeature.LocalIpAddress.get -> System.Net.IPAddress? +Microsoft.AspNetCore.Http.Features.IHttpConnectionFeature.LocalIpAddress.set -> void +Microsoft.AspNetCore.Http.Features.IHttpConnectionFeature.LocalPort.get -> int +Microsoft.AspNetCore.Http.Features.IHttpConnectionFeature.LocalPort.set -> void +Microsoft.AspNetCore.Http.Features.IHttpConnectionFeature.RemoteIpAddress.get -> System.Net.IPAddress? +Microsoft.AspNetCore.Http.Features.IHttpConnectionFeature.RemoteIpAddress.set -> void +Microsoft.AspNetCore.Http.Features.IHttpConnectionFeature.RemotePort.get -> int +Microsoft.AspNetCore.Http.Features.IHttpConnectionFeature.RemotePort.set -> void +Microsoft.AspNetCore.Http.Features.IHttpMaxRequestBodySizeFeature +Microsoft.AspNetCore.Http.Features.IHttpMaxRequestBodySizeFeature.IsReadOnly.get -> bool +Microsoft.AspNetCore.Http.Features.IHttpMaxRequestBodySizeFeature.MaxRequestBodySize.get -> long? +Microsoft.AspNetCore.Http.Features.IHttpMaxRequestBodySizeFeature.MaxRequestBodySize.set -> void +Microsoft.AspNetCore.Http.Features.IHttpRequestBodyDetectionFeature +Microsoft.AspNetCore.Http.Features.IHttpRequestBodyDetectionFeature.CanHaveBody.get -> bool +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature.Body.get -> System.IO.Stream! +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature.Body.set -> void +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature.Headers.get -> Microsoft.AspNetCore.Http.IHeaderDictionary! +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature.Headers.set -> void +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature.Method.get -> string! +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature.Method.set -> void +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature.Path.get -> string! +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature.Path.set -> void +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature.PathBase.get -> string! +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature.PathBase.set -> void +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature.Protocol.get -> string! +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature.Protocol.set -> void +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature.QueryString.get -> string! +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature.QueryString.set -> void +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature.RawTarget.get -> string! +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature.RawTarget.set -> void +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature.Scheme.get -> string! +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature.Scheme.set -> void +Microsoft.AspNetCore.Http.Features.IHttpRequestIdentifierFeature +Microsoft.AspNetCore.Http.Features.IHttpRequestIdentifierFeature.TraceIdentifier.get -> string! +Microsoft.AspNetCore.Http.Features.IHttpRequestIdentifierFeature.TraceIdentifier.set -> void +Microsoft.AspNetCore.Http.Features.IHttpRequestLifetimeFeature +Microsoft.AspNetCore.Http.Features.IHttpRequestLifetimeFeature.Abort() -> void +Microsoft.AspNetCore.Http.Features.IHttpRequestLifetimeFeature.RequestAborted.get -> System.Threading.CancellationToken +Microsoft.AspNetCore.Http.Features.IHttpRequestLifetimeFeature.RequestAborted.set -> void +Microsoft.AspNetCore.Http.Features.IHttpRequestTrailersFeature +Microsoft.AspNetCore.Http.Features.IHttpRequestTrailersFeature.Available.get -> bool +Microsoft.AspNetCore.Http.Features.IHttpRequestTrailersFeature.Trailers.get -> Microsoft.AspNetCore.Http.IHeaderDictionary! +Microsoft.AspNetCore.Http.Features.IHttpResetFeature +Microsoft.AspNetCore.Http.Features.IHttpResetFeature.Reset(int errorCode) -> void +Microsoft.AspNetCore.Http.Features.IHttpResponseBodyFeature +Microsoft.AspNetCore.Http.Features.IHttpResponseBodyFeature.CompleteAsync() -> System.Threading.Tasks.Task! +Microsoft.AspNetCore.Http.Features.IHttpResponseBodyFeature.DisableBuffering() -> void +Microsoft.AspNetCore.Http.Features.IHttpResponseBodyFeature.SendFileAsync(string! path, long offset, long? count, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task! +Microsoft.AspNetCore.Http.Features.IHttpResponseBodyFeature.StartAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task! +Microsoft.AspNetCore.Http.Features.IHttpResponseBodyFeature.Stream.get -> System.IO.Stream! +Microsoft.AspNetCore.Http.Features.IHttpResponseBodyFeature.Writer.get -> System.IO.Pipelines.PipeWriter! +Microsoft.AspNetCore.Http.Features.IHttpResponseFeature +Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.Body.get -> System.IO.Stream! +Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.Body.set -> void +Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.HasStarted.get -> bool +Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.Headers.get -> Microsoft.AspNetCore.Http.IHeaderDictionary! +Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.Headers.set -> void +Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.OnCompleted(System.Func! callback, object! state) -> void +Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.OnStarting(System.Func! callback, object! state) -> void +Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.ReasonPhrase.get -> string? +Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.ReasonPhrase.set -> void +Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.StatusCode.get -> int +Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.StatusCode.set -> void +Microsoft.AspNetCore.Http.Features.IHttpResponseTrailersFeature +Microsoft.AspNetCore.Http.Features.IHttpResponseTrailersFeature.Trailers.get -> Microsoft.AspNetCore.Http.IHeaderDictionary! +Microsoft.AspNetCore.Http.Features.IHttpResponseTrailersFeature.Trailers.set -> void +Microsoft.AspNetCore.Http.Features.IHttpSendFileFeature +Microsoft.AspNetCore.Http.Features.IHttpSendFileFeature.SendFileAsync(string! path, long offset, long? count, System.Threading.CancellationToken cancellation) -> System.Threading.Tasks.Task! +Microsoft.AspNetCore.Http.Features.IHttpUpgradeFeature +Microsoft.AspNetCore.Http.Features.IHttpUpgradeFeature.IsUpgradableRequest.get -> bool +Microsoft.AspNetCore.Http.Features.IHttpUpgradeFeature.UpgradeAsync() -> System.Threading.Tasks.Task! +Microsoft.AspNetCore.Http.Features.IHttpWebSocketFeature +Microsoft.AspNetCore.Http.Features.IHttpWebSocketFeature.AcceptAsync(Microsoft.AspNetCore.Http.WebSocketAcceptContext! context) -> System.Threading.Tasks.Task! +Microsoft.AspNetCore.Http.Features.IHttpWebSocketFeature.IsWebSocketRequest.get -> bool +Microsoft.AspNetCore.Http.Features.IHttpsCompressionFeature +Microsoft.AspNetCore.Http.Features.IHttpsCompressionFeature.Mode.get -> Microsoft.AspNetCore.Http.Features.HttpsCompressionMode +Microsoft.AspNetCore.Http.Features.IHttpsCompressionFeature.Mode.set -> void +Microsoft.AspNetCore.Http.Features.IItemsFeature +Microsoft.AspNetCore.Http.Features.IItemsFeature.Items.get -> System.Collections.Generic.IDictionary! +Microsoft.AspNetCore.Http.Features.IItemsFeature.Items.set -> void +Microsoft.AspNetCore.Http.Features.IQueryFeature +Microsoft.AspNetCore.Http.Features.IQueryFeature.Query.get -> Microsoft.AspNetCore.Http.IQueryCollection! +Microsoft.AspNetCore.Http.Features.IQueryFeature.Query.set -> void +Microsoft.AspNetCore.Http.Features.IRequestBodyPipeFeature +Microsoft.AspNetCore.Http.Features.IRequestBodyPipeFeature.Reader.get -> System.IO.Pipelines.PipeReader! +Microsoft.AspNetCore.Http.Features.IRequestCookiesFeature +Microsoft.AspNetCore.Http.Features.IRequestCookiesFeature.Cookies.get -> Microsoft.AspNetCore.Http.IRequestCookieCollection! +Microsoft.AspNetCore.Http.Features.IRequestCookiesFeature.Cookies.set -> void +Microsoft.AspNetCore.Http.Features.IResponseCookiesFeature +Microsoft.AspNetCore.Http.Features.IResponseCookiesFeature.Cookies.get -> Microsoft.AspNetCore.Http.IResponseCookies! +Microsoft.AspNetCore.Http.Features.IServerVariablesFeature +Microsoft.AspNetCore.Http.Features.IServerVariablesFeature.this[string! variableName].get -> string! +Microsoft.AspNetCore.Http.Features.IServerVariablesFeature.this[string! variableName].set -> void +Microsoft.AspNetCore.Http.Features.IServiceProvidersFeature +Microsoft.AspNetCore.Http.Features.IServiceProvidersFeature.RequestServices.get -> System.IServiceProvider! +Microsoft.AspNetCore.Http.Features.IServiceProvidersFeature.RequestServices.set -> void +Microsoft.AspNetCore.Http.Features.ISessionFeature +Microsoft.AspNetCore.Http.Features.ISessionFeature.Session.get -> Microsoft.AspNetCore.Http.ISession! +Microsoft.AspNetCore.Http.Features.ISessionFeature.Session.set -> void +Microsoft.AspNetCore.Http.Features.ITlsConnectionFeature +Microsoft.AspNetCore.Http.Features.ITlsConnectionFeature.ClientCertificate.get -> System.Security.Cryptography.X509Certificates.X509Certificate2? +Microsoft.AspNetCore.Http.Features.ITlsConnectionFeature.ClientCertificate.set -> void +Microsoft.AspNetCore.Http.Features.ITlsConnectionFeature.GetClientCertificateAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task! +Microsoft.AspNetCore.Http.Features.ITlsTokenBindingFeature +Microsoft.AspNetCore.Http.Features.ITlsTokenBindingFeature.GetProvidedTokenBindingId() -> byte[]! +Microsoft.AspNetCore.Http.Features.ITlsTokenBindingFeature.GetReferredTokenBindingId() -> byte[]! +Microsoft.AspNetCore.Http.Features.ITrackingConsentFeature +Microsoft.AspNetCore.Http.Features.ITrackingConsentFeature.CanTrack.get -> bool +Microsoft.AspNetCore.Http.Features.ITrackingConsentFeature.CreateConsentCookie() -> string! +Microsoft.AspNetCore.Http.Features.ITrackingConsentFeature.GrantConsent() -> void +Microsoft.AspNetCore.Http.Features.ITrackingConsentFeature.HasConsent.get -> bool +Microsoft.AspNetCore.Http.Features.ITrackingConsentFeature.IsConsentNeeded.get -> bool +Microsoft.AspNetCore.Http.Features.ITrackingConsentFeature.WithdrawConsent() -> void +Microsoft.AspNetCore.Http.IFormCollection +Microsoft.AspNetCore.Http.IFormCollection.ContainsKey(string! key) -> bool +Microsoft.AspNetCore.Http.IFormCollection.Count.get -> int +Microsoft.AspNetCore.Http.IFormCollection.Files.get -> Microsoft.AspNetCore.Http.IFormFileCollection! +Microsoft.AspNetCore.Http.IFormCollection.Keys.get -> System.Collections.Generic.ICollection! +Microsoft.AspNetCore.Http.IFormCollection.TryGetValue(string! key, out Microsoft.Extensions.Primitives.StringValues value) -> bool +Microsoft.AspNetCore.Http.IFormCollection.this[string! key].get -> Microsoft.Extensions.Primitives.StringValues +Microsoft.AspNetCore.Http.IFormFile +Microsoft.AspNetCore.Http.IFormFile.ContentDisposition.get -> string! +Microsoft.AspNetCore.Http.IFormFile.ContentType.get -> string! +Microsoft.AspNetCore.Http.IFormFile.CopyTo(System.IO.Stream! target) -> void +Microsoft.AspNetCore.Http.IFormFile.CopyToAsync(System.IO.Stream! target, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task! +Microsoft.AspNetCore.Http.IFormFile.FileName.get -> string! +Microsoft.AspNetCore.Http.IFormFile.Headers.get -> Microsoft.AspNetCore.Http.IHeaderDictionary! +Microsoft.AspNetCore.Http.IFormFile.Length.get -> long +Microsoft.AspNetCore.Http.IFormFile.Name.get -> string! +Microsoft.AspNetCore.Http.IFormFile.OpenReadStream() -> System.IO.Stream! +Microsoft.AspNetCore.Http.IFormFileCollection +Microsoft.AspNetCore.Http.IFormFileCollection.GetFile(string! name) -> Microsoft.AspNetCore.Http.IFormFile? +Microsoft.AspNetCore.Http.IFormFileCollection.GetFiles(string! name) -> System.Collections.Generic.IReadOnlyList! +Microsoft.AspNetCore.Http.IFormFileCollection.this[string! name].get -> Microsoft.AspNetCore.Http.IFormFile? +Microsoft.AspNetCore.Http.IHeaderDictionary +Microsoft.AspNetCore.Http.IHeaderDictionary.ContentLength.get -> long? +Microsoft.AspNetCore.Http.IHeaderDictionary.ContentLength.set -> void +Microsoft.AspNetCore.Http.IHeaderDictionary.this[string! key].get -> Microsoft.Extensions.Primitives.StringValues +Microsoft.AspNetCore.Http.IHeaderDictionary.this[string! key].set -> void +Microsoft.AspNetCore.Http.IQueryCollection +Microsoft.AspNetCore.Http.IQueryCollection.ContainsKey(string! key) -> bool +Microsoft.AspNetCore.Http.IQueryCollection.Count.get -> int +Microsoft.AspNetCore.Http.IQueryCollection.Keys.get -> System.Collections.Generic.ICollection! +Microsoft.AspNetCore.Http.IQueryCollection.TryGetValue(string! key, out Microsoft.Extensions.Primitives.StringValues value) -> bool +Microsoft.AspNetCore.Http.IQueryCollection.this[string! key].get -> Microsoft.Extensions.Primitives.StringValues +Microsoft.AspNetCore.Http.IRequestCookieCollection +Microsoft.AspNetCore.Http.IRequestCookieCollection.ContainsKey(string! key) -> bool +Microsoft.AspNetCore.Http.IRequestCookieCollection.Count.get -> int +Microsoft.AspNetCore.Http.IRequestCookieCollection.Keys.get -> System.Collections.Generic.ICollection! +Microsoft.AspNetCore.Http.IRequestCookieCollection.TryGetValue(string! key, out string? value) -> bool +Microsoft.AspNetCore.Http.IRequestCookieCollection.this[string! key].get -> string? +Microsoft.AspNetCore.Http.IResponseCookies +Microsoft.AspNetCore.Http.IResponseCookies.Append(string! key, string! value) -> void +Microsoft.AspNetCore.Http.IResponseCookies.Append(string! key, string! value, Microsoft.AspNetCore.Http.CookieOptions! options) -> void +Microsoft.AspNetCore.Http.IResponseCookies.Delete(string! key) -> void +Microsoft.AspNetCore.Http.IResponseCookies.Delete(string! key, Microsoft.AspNetCore.Http.CookieOptions! options) -> void +Microsoft.AspNetCore.Http.ISession +Microsoft.AspNetCore.Http.ISession.Clear() -> void +Microsoft.AspNetCore.Http.ISession.CommitAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task! +Microsoft.AspNetCore.Http.ISession.Id.get -> string! +Microsoft.AspNetCore.Http.ISession.IsAvailable.get -> bool +Microsoft.AspNetCore.Http.ISession.Keys.get -> System.Collections.Generic.IEnumerable! +Microsoft.AspNetCore.Http.ISession.LoadAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task! +Microsoft.AspNetCore.Http.ISession.Remove(string! key) -> void +Microsoft.AspNetCore.Http.ISession.Set(string! key, byte[]! value) -> void +Microsoft.AspNetCore.Http.ISession.TryGetValue(string! key, out byte[]! value) -> bool +Microsoft.AspNetCore.Http.SameSiteMode +Microsoft.AspNetCore.Http.SameSiteMode.Lax = 1 -> Microsoft.AspNetCore.Http.SameSiteMode +Microsoft.AspNetCore.Http.SameSiteMode.None = 0 -> Microsoft.AspNetCore.Http.SameSiteMode +Microsoft.AspNetCore.Http.SameSiteMode.Strict = 2 -> Microsoft.AspNetCore.Http.SameSiteMode +Microsoft.AspNetCore.Http.SameSiteMode.Unspecified = -1 -> Microsoft.AspNetCore.Http.SameSiteMode +Microsoft.AspNetCore.Http.WebSocketAcceptContext +Microsoft.AspNetCore.Http.WebSocketAcceptContext.WebSocketAcceptContext() -> void +static readonly Microsoft.AspNetCore.Http.Features.FeatureReference.Default -> Microsoft.AspNetCore.Http.Features.FeatureReference +virtual Microsoft.AspNetCore.Http.Features.FeatureCollection.Revision.get -> int +virtual Microsoft.AspNetCore.Http.WebSocketAcceptContext.SubProtocol.get -> string? +virtual Microsoft.AspNetCore.Http.WebSocketAcceptContext.SubProtocol.set -> void diff --git a/src/Http/Http.Features/src/PublicAPI/net6.0/PublicAPI.Unshipped.txt b/src/Http/Http.Features/src/PublicAPI/net6.0/PublicAPI.Unshipped.txt new file mode 100644 index 000000000000..1298da03ad35 --- /dev/null +++ b/src/Http/Http.Features/src/PublicAPI/net6.0/PublicAPI.Unshipped.txt @@ -0,0 +1,18 @@ +#nullable enable +*REMOVED*Microsoft.AspNetCore.Http.Features.FeatureCollection.Set(TFeature instance) -> void +*REMOVED*Microsoft.AspNetCore.Http.Features.IFeatureCollection.Get() -> TFeature +*REMOVED*Microsoft.AspNetCore.Http.Features.IFeatureCollection.Set(TFeature instance) -> void +*REMOVED*Microsoft.AspNetCore.Http.Features.IHttpBufferingFeature +*REMOVED*Microsoft.AspNetCore.Http.Features.IHttpBufferingFeature.DisableRequestBuffering() -> void +*REMOVED*Microsoft.AspNetCore.Http.Features.IHttpBufferingFeature.DisableResponseBuffering() -> void +*REMOVED*Microsoft.AspNetCore.Http.Features.IHttpSendFileFeature +*REMOVED*Microsoft.AspNetCore.Http.Features.IHttpSendFileFeature.SendFileAsync(string! path, long offset, long? count, System.Threading.CancellationToken cancellation) -> System.Threading.Tasks.Task! +*REMOVED*Microsoft.AspNetCore.Http.Features.IServerVariablesFeature.this[string! variableName].get -> string! +*REMOVED*Microsoft.AspNetCore.Http.ISession.TryGetValue(string! key, out byte[]! value) -> bool +Microsoft.AspNetCore.Http.Features.FeatureCollection.Set(TFeature? instance) -> void +Microsoft.AspNetCore.Http.Features.IFeatureCollection.Get() -> TFeature? +Microsoft.AspNetCore.Http.Features.IFeatureCollection.Set(TFeature? instance) -> void +Microsoft.AspNetCore.Http.Features.IServerVariablesFeature.this[string! variableName].get -> string? +Microsoft.AspNetCore.Http.ISession.TryGetValue(string! key, out byte[]? value) -> bool +Microsoft.AspNetCore.Http.Features.FeatureCollection.FeatureCollection(int initialCapacity) -> void +Microsoft.AspNetCore.Http.IResponseCookies.Append(System.ReadOnlySpan> keyValuePairs, Microsoft.AspNetCore.Http.CookieOptions! options) -> void diff --git a/src/Http/Http.Features/src/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt b/src/Http/Http.Features/src/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt new file mode 100644 index 000000000000..f97bf2426e2e --- /dev/null +++ b/src/Http/Http.Features/src/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt @@ -0,0 +1,247 @@ +#nullable enable +Microsoft.AspNetCore.Http.CookieOptions +Microsoft.AspNetCore.Http.CookieOptions.CookieOptions() -> void +Microsoft.AspNetCore.Http.CookieOptions.Domain.get -> string? +Microsoft.AspNetCore.Http.CookieOptions.Domain.set -> void +Microsoft.AspNetCore.Http.CookieOptions.Expires.get -> System.DateTimeOffset? +Microsoft.AspNetCore.Http.CookieOptions.Expires.set -> void +Microsoft.AspNetCore.Http.CookieOptions.HttpOnly.get -> bool +Microsoft.AspNetCore.Http.CookieOptions.HttpOnly.set -> void +Microsoft.AspNetCore.Http.CookieOptions.IsEssential.get -> bool +Microsoft.AspNetCore.Http.CookieOptions.IsEssential.set -> void +Microsoft.AspNetCore.Http.CookieOptions.MaxAge.get -> System.TimeSpan? +Microsoft.AspNetCore.Http.CookieOptions.MaxAge.set -> void +Microsoft.AspNetCore.Http.CookieOptions.Path.get -> string? +Microsoft.AspNetCore.Http.CookieOptions.Path.set -> void +Microsoft.AspNetCore.Http.CookieOptions.SameSite.get -> Microsoft.AspNetCore.Http.SameSiteMode +Microsoft.AspNetCore.Http.CookieOptions.SameSite.set -> void +Microsoft.AspNetCore.Http.CookieOptions.Secure.get -> bool +Microsoft.AspNetCore.Http.CookieOptions.Secure.set -> void +Microsoft.AspNetCore.Http.Features.Authentication.IHttpAuthenticationFeature +Microsoft.AspNetCore.Http.Features.Authentication.IHttpAuthenticationFeature.User.get -> System.Security.Claims.ClaimsPrincipal? +Microsoft.AspNetCore.Http.Features.Authentication.IHttpAuthenticationFeature.User.set -> void +Microsoft.AspNetCore.Http.Features.FeatureCollection +Microsoft.AspNetCore.Http.Features.FeatureCollection.FeatureCollection() -> void +Microsoft.AspNetCore.Http.Features.FeatureCollection.FeatureCollection(Microsoft.AspNetCore.Http.Features.IFeatureCollection! defaults) -> void +Microsoft.AspNetCore.Http.Features.FeatureCollection.Get() -> TFeature? +Microsoft.AspNetCore.Http.Features.FeatureCollection.GetEnumerator() -> System.Collections.Generic.IEnumerator>! +Microsoft.AspNetCore.Http.Features.FeatureCollection.IsReadOnly.get -> bool +Microsoft.AspNetCore.Http.Features.FeatureCollection.Set(TFeature instance) -> void +Microsoft.AspNetCore.Http.Features.FeatureCollection.this[System.Type! key].get -> object? +Microsoft.AspNetCore.Http.Features.FeatureCollection.this[System.Type! key].set -> void +Microsoft.AspNetCore.Http.Features.FeatureReference +Microsoft.AspNetCore.Http.Features.FeatureReference.Fetch(Microsoft.AspNetCore.Http.Features.IFeatureCollection! features) -> T? +Microsoft.AspNetCore.Http.Features.FeatureReference.Update(Microsoft.AspNetCore.Http.Features.IFeatureCollection! features, T feature) -> T +Microsoft.AspNetCore.Http.Features.FeatureReferences +Microsoft.AspNetCore.Http.Features.FeatureReferences.Cache -> TCache? +Microsoft.AspNetCore.Http.Features.FeatureReferences.Collection.get -> Microsoft.AspNetCore.Http.Features.IFeatureCollection! +Microsoft.AspNetCore.Http.Features.FeatureReferences.FeatureReferences(Microsoft.AspNetCore.Http.Features.IFeatureCollection! collection) -> void +Microsoft.AspNetCore.Http.Features.FeatureReferences.Fetch(ref TFeature? cached, TState state, System.Func! factory) -> TFeature? +Microsoft.AspNetCore.Http.Features.FeatureReferences.Fetch(ref TFeature? cached, System.Func! factory) -> TFeature? +Microsoft.AspNetCore.Http.Features.FeatureReferences.Initalize(Microsoft.AspNetCore.Http.Features.IFeatureCollection! collection) -> void +Microsoft.AspNetCore.Http.Features.FeatureReferences.Initalize(Microsoft.AspNetCore.Http.Features.IFeatureCollection! collection, int revision) -> void +Microsoft.AspNetCore.Http.Features.FeatureReferences.Revision.get -> int +Microsoft.AspNetCore.Http.Features.HttpsCompressionMode +Microsoft.AspNetCore.Http.Features.HttpsCompressionMode.Compress = 2 -> Microsoft.AspNetCore.Http.Features.HttpsCompressionMode +Microsoft.AspNetCore.Http.Features.HttpsCompressionMode.Default = 0 -> Microsoft.AspNetCore.Http.Features.HttpsCompressionMode +Microsoft.AspNetCore.Http.Features.HttpsCompressionMode.DoNotCompress = 1 -> Microsoft.AspNetCore.Http.Features.HttpsCompressionMode +Microsoft.AspNetCore.Http.Features.IFeatureCollection +Microsoft.AspNetCore.Http.Features.IFeatureCollection.Get() -> TFeature +Microsoft.AspNetCore.Http.Features.IFeatureCollection.IsReadOnly.get -> bool +Microsoft.AspNetCore.Http.Features.IFeatureCollection.Revision.get -> int +Microsoft.AspNetCore.Http.Features.IFeatureCollection.Set(TFeature instance) -> void +Microsoft.AspNetCore.Http.Features.IFeatureCollection.this[System.Type! key].get -> object? +Microsoft.AspNetCore.Http.Features.IFeatureCollection.this[System.Type! key].set -> void +Microsoft.AspNetCore.Http.Features.IFormFeature +Microsoft.AspNetCore.Http.Features.IFormFeature.Form.get -> Microsoft.AspNetCore.Http.IFormCollection? +Microsoft.AspNetCore.Http.Features.IFormFeature.Form.set -> void +Microsoft.AspNetCore.Http.Features.IFormFeature.HasFormContentType.get -> bool +Microsoft.AspNetCore.Http.Features.IFormFeature.ReadForm() -> Microsoft.AspNetCore.Http.IFormCollection! +Microsoft.AspNetCore.Http.Features.IFormFeature.ReadFormAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task! +Microsoft.AspNetCore.Http.Features.IHttpBodyControlFeature +Microsoft.AspNetCore.Http.Features.IHttpBodyControlFeature.AllowSynchronousIO.get -> bool +Microsoft.AspNetCore.Http.Features.IHttpBodyControlFeature.AllowSynchronousIO.set -> void +Microsoft.AspNetCore.Http.Features.IHttpBufferingFeature +Microsoft.AspNetCore.Http.Features.IHttpBufferingFeature.DisableRequestBuffering() -> void +Microsoft.AspNetCore.Http.Features.IHttpBufferingFeature.DisableResponseBuffering() -> void +Microsoft.AspNetCore.Http.Features.IHttpConnectionFeature +Microsoft.AspNetCore.Http.Features.IHttpConnectionFeature.ConnectionId.get -> string! +Microsoft.AspNetCore.Http.Features.IHttpConnectionFeature.ConnectionId.set -> void +Microsoft.AspNetCore.Http.Features.IHttpConnectionFeature.LocalIpAddress.get -> System.Net.IPAddress? +Microsoft.AspNetCore.Http.Features.IHttpConnectionFeature.LocalIpAddress.set -> void +Microsoft.AspNetCore.Http.Features.IHttpConnectionFeature.LocalPort.get -> int +Microsoft.AspNetCore.Http.Features.IHttpConnectionFeature.LocalPort.set -> void +Microsoft.AspNetCore.Http.Features.IHttpConnectionFeature.RemoteIpAddress.get -> System.Net.IPAddress? +Microsoft.AspNetCore.Http.Features.IHttpConnectionFeature.RemoteIpAddress.set -> void +Microsoft.AspNetCore.Http.Features.IHttpConnectionFeature.RemotePort.get -> int +Microsoft.AspNetCore.Http.Features.IHttpConnectionFeature.RemotePort.set -> void +Microsoft.AspNetCore.Http.Features.IHttpMaxRequestBodySizeFeature +Microsoft.AspNetCore.Http.Features.IHttpMaxRequestBodySizeFeature.IsReadOnly.get -> bool +Microsoft.AspNetCore.Http.Features.IHttpMaxRequestBodySizeFeature.MaxRequestBodySize.get -> long? +Microsoft.AspNetCore.Http.Features.IHttpMaxRequestBodySizeFeature.MaxRequestBodySize.set -> void +Microsoft.AspNetCore.Http.Features.IHttpRequestBodyDetectionFeature +Microsoft.AspNetCore.Http.Features.IHttpRequestBodyDetectionFeature.CanHaveBody.get -> bool +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature.Body.get -> System.IO.Stream! +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature.Body.set -> void +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature.Headers.get -> Microsoft.AspNetCore.Http.IHeaderDictionary! +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature.Headers.set -> void +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature.Method.get -> string! +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature.Method.set -> void +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature.Path.get -> string! +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature.Path.set -> void +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature.PathBase.get -> string! +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature.PathBase.set -> void +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature.Protocol.get -> string! +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature.Protocol.set -> void +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature.QueryString.get -> string! +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature.QueryString.set -> void +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature.RawTarget.get -> string! +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature.RawTarget.set -> void +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature.Scheme.get -> string! +Microsoft.AspNetCore.Http.Features.IHttpRequestFeature.Scheme.set -> void +Microsoft.AspNetCore.Http.Features.IHttpRequestIdentifierFeature +Microsoft.AspNetCore.Http.Features.IHttpRequestIdentifierFeature.TraceIdentifier.get -> string! +Microsoft.AspNetCore.Http.Features.IHttpRequestIdentifierFeature.TraceIdentifier.set -> void +Microsoft.AspNetCore.Http.Features.IHttpRequestLifetimeFeature +Microsoft.AspNetCore.Http.Features.IHttpRequestLifetimeFeature.Abort() -> void +Microsoft.AspNetCore.Http.Features.IHttpRequestLifetimeFeature.RequestAborted.get -> System.Threading.CancellationToken +Microsoft.AspNetCore.Http.Features.IHttpRequestLifetimeFeature.RequestAborted.set -> void +Microsoft.AspNetCore.Http.Features.IHttpRequestTrailersFeature +Microsoft.AspNetCore.Http.Features.IHttpRequestTrailersFeature.Available.get -> bool +Microsoft.AspNetCore.Http.Features.IHttpRequestTrailersFeature.Trailers.get -> Microsoft.AspNetCore.Http.IHeaderDictionary! +Microsoft.AspNetCore.Http.Features.IHttpResetFeature +Microsoft.AspNetCore.Http.Features.IHttpResetFeature.Reset(int errorCode) -> void +Microsoft.AspNetCore.Http.Features.IHttpResponseBodyFeature +Microsoft.AspNetCore.Http.Features.IHttpResponseBodyFeature.CompleteAsync() -> System.Threading.Tasks.Task! +Microsoft.AspNetCore.Http.Features.IHttpResponseBodyFeature.DisableBuffering() -> void +Microsoft.AspNetCore.Http.Features.IHttpResponseBodyFeature.SendFileAsync(string! path, long offset, long? count, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task! +Microsoft.AspNetCore.Http.Features.IHttpResponseBodyFeature.StartAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task! +Microsoft.AspNetCore.Http.Features.IHttpResponseBodyFeature.Stream.get -> System.IO.Stream! +Microsoft.AspNetCore.Http.Features.IHttpResponseBodyFeature.Writer.get -> System.IO.Pipelines.PipeWriter! +Microsoft.AspNetCore.Http.Features.IHttpResponseFeature +Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.Body.get -> System.IO.Stream! +Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.Body.set -> void +Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.HasStarted.get -> bool +Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.Headers.get -> Microsoft.AspNetCore.Http.IHeaderDictionary! +Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.Headers.set -> void +Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.OnCompleted(System.Func! callback, object! state) -> void +Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.OnStarting(System.Func! callback, object! state) -> void +Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.ReasonPhrase.get -> string? +Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.ReasonPhrase.set -> void +Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.StatusCode.get -> int +Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.StatusCode.set -> void +Microsoft.AspNetCore.Http.Features.IHttpResponseTrailersFeature +Microsoft.AspNetCore.Http.Features.IHttpResponseTrailersFeature.Trailers.get -> Microsoft.AspNetCore.Http.IHeaderDictionary! +Microsoft.AspNetCore.Http.Features.IHttpResponseTrailersFeature.Trailers.set -> void +Microsoft.AspNetCore.Http.Features.IHttpSendFileFeature +Microsoft.AspNetCore.Http.Features.IHttpSendFileFeature.SendFileAsync(string! path, long offset, long? count, System.Threading.CancellationToken cancellation) -> System.Threading.Tasks.Task! +Microsoft.AspNetCore.Http.Features.IHttpUpgradeFeature +Microsoft.AspNetCore.Http.Features.IHttpUpgradeFeature.IsUpgradableRequest.get -> bool +Microsoft.AspNetCore.Http.Features.IHttpUpgradeFeature.UpgradeAsync() -> System.Threading.Tasks.Task! +Microsoft.AspNetCore.Http.Features.IHttpWebSocketFeature +Microsoft.AspNetCore.Http.Features.IHttpWebSocketFeature.AcceptAsync(Microsoft.AspNetCore.Http.WebSocketAcceptContext! context) -> System.Threading.Tasks.Task! +Microsoft.AspNetCore.Http.Features.IHttpWebSocketFeature.IsWebSocketRequest.get -> bool +Microsoft.AspNetCore.Http.Features.IHttpsCompressionFeature +Microsoft.AspNetCore.Http.Features.IHttpsCompressionFeature.Mode.get -> Microsoft.AspNetCore.Http.Features.HttpsCompressionMode +Microsoft.AspNetCore.Http.Features.IHttpsCompressionFeature.Mode.set -> void +Microsoft.AspNetCore.Http.Features.IItemsFeature +Microsoft.AspNetCore.Http.Features.IItemsFeature.Items.get -> System.Collections.Generic.IDictionary! +Microsoft.AspNetCore.Http.Features.IItemsFeature.Items.set -> void +Microsoft.AspNetCore.Http.Features.IQueryFeature +Microsoft.AspNetCore.Http.Features.IQueryFeature.Query.get -> Microsoft.AspNetCore.Http.IQueryCollection! +Microsoft.AspNetCore.Http.Features.IQueryFeature.Query.set -> void +Microsoft.AspNetCore.Http.Features.IRequestBodyPipeFeature +Microsoft.AspNetCore.Http.Features.IRequestBodyPipeFeature.Reader.get -> System.IO.Pipelines.PipeReader! +Microsoft.AspNetCore.Http.Features.IRequestCookiesFeature +Microsoft.AspNetCore.Http.Features.IRequestCookiesFeature.Cookies.get -> Microsoft.AspNetCore.Http.IRequestCookieCollection! +Microsoft.AspNetCore.Http.Features.IRequestCookiesFeature.Cookies.set -> void +Microsoft.AspNetCore.Http.Features.IResponseCookiesFeature +Microsoft.AspNetCore.Http.Features.IResponseCookiesFeature.Cookies.get -> Microsoft.AspNetCore.Http.IResponseCookies! +Microsoft.AspNetCore.Http.Features.IServerVariablesFeature +Microsoft.AspNetCore.Http.Features.IServerVariablesFeature.this[string! variableName].get -> string! +Microsoft.AspNetCore.Http.Features.IServerVariablesFeature.this[string! variableName].set -> void +Microsoft.AspNetCore.Http.Features.IServiceProvidersFeature +Microsoft.AspNetCore.Http.Features.IServiceProvidersFeature.RequestServices.get -> System.IServiceProvider! +Microsoft.AspNetCore.Http.Features.IServiceProvidersFeature.RequestServices.set -> void +Microsoft.AspNetCore.Http.Features.ISessionFeature +Microsoft.AspNetCore.Http.Features.ISessionFeature.Session.get -> Microsoft.AspNetCore.Http.ISession! +Microsoft.AspNetCore.Http.Features.ISessionFeature.Session.set -> void +Microsoft.AspNetCore.Http.Features.ITlsConnectionFeature +Microsoft.AspNetCore.Http.Features.ITlsConnectionFeature.ClientCertificate.get -> System.Security.Cryptography.X509Certificates.X509Certificate2? +Microsoft.AspNetCore.Http.Features.ITlsConnectionFeature.ClientCertificate.set -> void +Microsoft.AspNetCore.Http.Features.ITlsConnectionFeature.GetClientCertificateAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task! +Microsoft.AspNetCore.Http.Features.ITlsTokenBindingFeature +Microsoft.AspNetCore.Http.Features.ITlsTokenBindingFeature.GetProvidedTokenBindingId() -> byte[]! +Microsoft.AspNetCore.Http.Features.ITlsTokenBindingFeature.GetReferredTokenBindingId() -> byte[]! +Microsoft.AspNetCore.Http.Features.ITrackingConsentFeature +Microsoft.AspNetCore.Http.Features.ITrackingConsentFeature.CanTrack.get -> bool +Microsoft.AspNetCore.Http.Features.ITrackingConsentFeature.CreateConsentCookie() -> string! +Microsoft.AspNetCore.Http.Features.ITrackingConsentFeature.GrantConsent() -> void +Microsoft.AspNetCore.Http.Features.ITrackingConsentFeature.HasConsent.get -> bool +Microsoft.AspNetCore.Http.Features.ITrackingConsentFeature.IsConsentNeeded.get -> bool +Microsoft.AspNetCore.Http.Features.ITrackingConsentFeature.WithdrawConsent() -> void +Microsoft.AspNetCore.Http.IFormCollection +Microsoft.AspNetCore.Http.IFormCollection.ContainsKey(string! key) -> bool +Microsoft.AspNetCore.Http.IFormCollection.Count.get -> int +Microsoft.AspNetCore.Http.IFormCollection.Files.get -> Microsoft.AspNetCore.Http.IFormFileCollection! +Microsoft.AspNetCore.Http.IFormCollection.Keys.get -> System.Collections.Generic.ICollection! +Microsoft.AspNetCore.Http.IFormCollection.TryGetValue(string! key, out Microsoft.Extensions.Primitives.StringValues value) -> bool +Microsoft.AspNetCore.Http.IFormCollection.this[string! key].get -> Microsoft.Extensions.Primitives.StringValues +Microsoft.AspNetCore.Http.IFormFile +Microsoft.AspNetCore.Http.IFormFile.ContentDisposition.get -> string! +Microsoft.AspNetCore.Http.IFormFile.ContentType.get -> string! +Microsoft.AspNetCore.Http.IFormFile.CopyTo(System.IO.Stream! target) -> void +Microsoft.AspNetCore.Http.IFormFile.CopyToAsync(System.IO.Stream! target, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task! +Microsoft.AspNetCore.Http.IFormFile.FileName.get -> string! +Microsoft.AspNetCore.Http.IFormFile.Headers.get -> Microsoft.AspNetCore.Http.IHeaderDictionary! +Microsoft.AspNetCore.Http.IFormFile.Length.get -> long +Microsoft.AspNetCore.Http.IFormFile.Name.get -> string! +Microsoft.AspNetCore.Http.IFormFile.OpenReadStream() -> System.IO.Stream! +Microsoft.AspNetCore.Http.IFormFileCollection +Microsoft.AspNetCore.Http.IFormFileCollection.GetFile(string! name) -> Microsoft.AspNetCore.Http.IFormFile? +Microsoft.AspNetCore.Http.IFormFileCollection.GetFiles(string! name) -> System.Collections.Generic.IReadOnlyList! +Microsoft.AspNetCore.Http.IFormFileCollection.this[string! name].get -> Microsoft.AspNetCore.Http.IFormFile? +Microsoft.AspNetCore.Http.IHeaderDictionary +Microsoft.AspNetCore.Http.IHeaderDictionary.ContentLength.get -> long? +Microsoft.AspNetCore.Http.IHeaderDictionary.ContentLength.set -> void +Microsoft.AspNetCore.Http.IHeaderDictionary.this[string! key].get -> Microsoft.Extensions.Primitives.StringValues +Microsoft.AspNetCore.Http.IHeaderDictionary.this[string! key].set -> void +Microsoft.AspNetCore.Http.IQueryCollection +Microsoft.AspNetCore.Http.IQueryCollection.ContainsKey(string! key) -> bool +Microsoft.AspNetCore.Http.IQueryCollection.Count.get -> int +Microsoft.AspNetCore.Http.IQueryCollection.Keys.get -> System.Collections.Generic.ICollection! +Microsoft.AspNetCore.Http.IQueryCollection.TryGetValue(string! key, out Microsoft.Extensions.Primitives.StringValues value) -> bool +Microsoft.AspNetCore.Http.IQueryCollection.this[string! key].get -> Microsoft.Extensions.Primitives.StringValues +Microsoft.AspNetCore.Http.IRequestCookieCollection +Microsoft.AspNetCore.Http.IRequestCookieCollection.ContainsKey(string! key) -> bool +Microsoft.AspNetCore.Http.IRequestCookieCollection.Count.get -> int +Microsoft.AspNetCore.Http.IRequestCookieCollection.Keys.get -> System.Collections.Generic.ICollection! +Microsoft.AspNetCore.Http.IRequestCookieCollection.TryGetValue(string! key, out string? value) -> bool +Microsoft.AspNetCore.Http.IRequestCookieCollection.this[string! key].get -> string? +Microsoft.AspNetCore.Http.IResponseCookies +Microsoft.AspNetCore.Http.IResponseCookies.Append(string! key, string! value) -> void +Microsoft.AspNetCore.Http.IResponseCookies.Append(string! key, string! value, Microsoft.AspNetCore.Http.CookieOptions! options) -> void +Microsoft.AspNetCore.Http.IResponseCookies.Delete(string! key) -> void +Microsoft.AspNetCore.Http.IResponseCookies.Delete(string! key, Microsoft.AspNetCore.Http.CookieOptions! options) -> void +Microsoft.AspNetCore.Http.ISession +Microsoft.AspNetCore.Http.ISession.Clear() -> void +Microsoft.AspNetCore.Http.ISession.CommitAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task! +Microsoft.AspNetCore.Http.ISession.Id.get -> string! +Microsoft.AspNetCore.Http.ISession.IsAvailable.get -> bool +Microsoft.AspNetCore.Http.ISession.Keys.get -> System.Collections.Generic.IEnumerable! +Microsoft.AspNetCore.Http.ISession.LoadAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task! +Microsoft.AspNetCore.Http.ISession.Remove(string! key) -> void +Microsoft.AspNetCore.Http.ISession.Set(string! key, byte[]! value) -> void +Microsoft.AspNetCore.Http.ISession.TryGetValue(string! key, out byte[]! value) -> bool +Microsoft.AspNetCore.Http.SameSiteMode +Microsoft.AspNetCore.Http.SameSiteMode.Lax = 1 -> Microsoft.AspNetCore.Http.SameSiteMode +Microsoft.AspNetCore.Http.SameSiteMode.None = 0 -> Microsoft.AspNetCore.Http.SameSiteMode +Microsoft.AspNetCore.Http.SameSiteMode.Strict = 2 -> Microsoft.AspNetCore.Http.SameSiteMode +Microsoft.AspNetCore.Http.SameSiteMode.Unspecified = -1 -> Microsoft.AspNetCore.Http.SameSiteMode +Microsoft.AspNetCore.Http.WebSocketAcceptContext +Microsoft.AspNetCore.Http.WebSocketAcceptContext.WebSocketAcceptContext() -> void +static readonly Microsoft.AspNetCore.Http.Features.FeatureReference.Default -> Microsoft.AspNetCore.Http.Features.FeatureReference +virtual Microsoft.AspNetCore.Http.Features.FeatureCollection.Revision.get -> int +virtual Microsoft.AspNetCore.Http.WebSocketAcceptContext.SubProtocol.get -> string? +virtual Microsoft.AspNetCore.Http.WebSocketAcceptContext.SubProtocol.set -> void diff --git a/src/Http/Http.Features/src/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt b/src/Http/Http.Features/src/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt new file mode 100644 index 000000000000..4cc6095ff65a --- /dev/null +++ b/src/Http/Http.Features/src/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,17 @@ +#nullable enable +*REMOVED*Microsoft.AspNetCore.Http.Features.FeatureCollection.Set(TFeature instance) -> void +*REMOVED*Microsoft.AspNetCore.Http.Features.IFeatureCollection.Get() -> TFeature +*REMOVED*Microsoft.AspNetCore.Http.Features.IFeatureCollection.Set(TFeature instance) -> void +*REMOVED*Microsoft.AspNetCore.Http.Features.IHttpBufferingFeature +*REMOVED*Microsoft.AspNetCore.Http.Features.IHttpBufferingFeature.DisableRequestBuffering() -> void +*REMOVED*Microsoft.AspNetCore.Http.Features.IHttpBufferingFeature.DisableResponseBuffering() -> void +*REMOVED*Microsoft.AspNetCore.Http.Features.IHttpSendFileFeature +*REMOVED*Microsoft.AspNetCore.Http.Features.IHttpSendFileFeature.SendFileAsync(string! path, long offset, long? count, System.Threading.CancellationToken cancellation) -> System.Threading.Tasks.Task! +*REMOVED*Microsoft.AspNetCore.Http.Features.IServerVariablesFeature.this[string! variableName].get -> string! +*REMOVED*Microsoft.AspNetCore.Http.ISession.TryGetValue(string! key, out byte[]! value) -> bool +Microsoft.AspNetCore.Http.Features.FeatureCollection.Set(TFeature? instance) -> void +Microsoft.AspNetCore.Http.Features.IFeatureCollection.Get() -> TFeature? +Microsoft.AspNetCore.Http.Features.IFeatureCollection.Set(TFeature? instance) -> void +Microsoft.AspNetCore.Http.Features.IServerVariablesFeature.this[string! variableName].get -> string? +Microsoft.AspNetCore.Http.ISession.TryGetValue(string! key, out byte[]? value) -> bool +Microsoft.AspNetCore.Http.Features.FeatureCollection.FeatureCollection(int initialCapacity) -> void diff --git a/src/Http/Http/src/Internal/ResponseCookies.cs b/src/Http/Http/src/Internal/ResponseCookies.cs index 4a34b055d604..e7466c6a6ecb 100644 --- a/src/Http/Http/src/Internal/ResponseCookies.cs +++ b/src/Http/Http/src/Internal/ResponseCookies.cs @@ -88,6 +88,57 @@ public void Append(string key, string value, CookieOptions options) Headers[HeaderNames.SetCookie] = StringValues.Concat(Headers[HeaderNames.SetCookie], cookieValue); } + /// + public void Append(ReadOnlySpan> keyValuePairs, CookieOptions options) + { + if (options == null) + { + throw new ArgumentNullException(nameof(options)); + } + + // SameSite=None cookies must be marked as Secure. + if (!options.Secure && options.SameSite == SameSiteMode.None) + { + if (_logger == null) + { + var services = _features.Get()?.RequestServices; + _logger = services?.GetService>(); + } + + if (_logger != null) + { + foreach (var keyValuePair in keyValuePairs) + { + Log.SameSiteCookieNotSecure(_logger, keyValuePair.Key); + } + } + } + + var setCookieHeaderValue = new SetCookieHeaderValue(string.Empty) + { + Domain = options.Domain, + Path = options.Path, + Expires = options.Expires, + MaxAge = options.MaxAge, + Secure = options.Secure, + SameSite = (Net.Http.Headers.SameSiteMode)options.SameSite, + HttpOnly = options.HttpOnly + }; + + var cookierHeaderValue = setCookieHeaderValue.ToString()[1..]; + var cookies = new string[keyValuePairs.Length]; + var position = 0; + + foreach (var keyValuePair in keyValuePairs) + { + var key = _enableCookieNameEncoding ? Uri.EscapeDataString(keyValuePair.Key) : keyValuePair.Key; + cookies[position] = string.Concat(key, "=", Uri.EscapeDataString(keyValuePair.Value), cookierHeaderValue); + position++; + } + + Headers.Append(HeaderNames.SetCookie, cookies); + } + /// public void Delete(string key) { diff --git a/src/Mvc/Mvc.ViewFeatures/test/CookieTempDataProviderTest.cs b/src/Mvc/Mvc.ViewFeatures/test/CookieTempDataProviderTest.cs index 892c6f114671..c509e6645772 100644 --- a/src/Mvc/Mvc.ViewFeatures/test/CookieTempDataProviderTest.cs +++ b/src/Mvc/Mvc.ViewFeatures/test/CookieTempDataProviderTest.cs @@ -501,4 +501,4 @@ public override byte[] Serialize(IDictionary values) } } } -} \ No newline at end of file +} diff --git a/src/Security/CookiePolicy/src/ResponseCookiesWrapper.cs b/src/Security/CookiePolicy/src/ResponseCookiesWrapper.cs index 4a3dc976646e..f3f706510d88 100644 --- a/src/Security/CookiePolicy/src/ResponseCookiesWrapper.cs +++ b/src/Security/CookiePolicy/src/ResponseCookiesWrapper.cs @@ -2,7 +2,9 @@ // 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.Diagnostics; +using System.Runtime.InteropServices; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; @@ -152,6 +154,33 @@ public void Append(string key, string value, CookieOptions options) } } + public void Append(ReadOnlySpan> keyValuePairs, CookieOptions options) + { + if (options == null) + { + throw new ArgumentNullException(nameof(options)); + } + + var nonSuppressedValues = new List>(keyValuePairs.Length); + + foreach (var keyValuePair in keyValuePairs) + { + var key = keyValuePair.Key; + var value = keyValuePair.Value; + + if (ApplyAppendPolicy(ref key, ref value, options)) + { + nonSuppressedValues.Add(KeyValuePair.Create(key, value)); + } + else + { + _logger.CookieSuppressed(keyValuePair.Key); + } + } + + Cookies.Append(CollectionsMarshal.AsSpan(nonSuppressedValues), options); + } + private bool ApplyAppendPolicy(ref string key, ref string value, CookieOptions options) { var issueCookie = CanTrack || options.IsEssential; diff --git a/src/Security/CookiePolicy/test/CookieChunkingTests.cs b/src/Security/CookiePolicy/test/CookieChunkingTests.cs index 4b65df4073b5..9bc07c6f9f9c 100644 --- a/src/Security/CookiePolicy/test/CookieChunkingTests.cs +++ b/src/Security/CookiePolicy/test/CookieChunkingTests.cs @@ -3,6 +3,7 @@ using System; using Microsoft.AspNetCore.Http; +using Microsoft.Net.Http.Headers; using Xunit; namespace Microsoft.AspNetCore.Internal @@ -30,7 +31,7 @@ public void AppendLargeCookie_WithOptions_Appended() { Domain = "foo.com", HttpOnly = true, - SameSite = SameSiteMode.Strict, + SameSite = Http.SameSiteMode.Strict, Path = "/bar", Secure = true, Expires = now.AddMinutes(5), @@ -145,5 +146,59 @@ public void DeleteChunkedCookieWithOptions_AllDeleted() "TestCookieC7=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure", }, cookies); } + + + + [Fact] + public void DeleteChunkedCookieWithOptionsAndResponseCookies_AllDeleted() + { + var chunkingCookieManager = new ChunkingCookieManager(); + HttpContext httpContext = new DefaultHttpContext(); + + httpContext.Request.Headers["Cookie"] = new[] + { + "TestCookie=chunks-7", + "TestCookieC1=abcdefghi", + "TestCookieC2=jklmnopqr", + "TestCookieC3=stuvwxyz0", + "TestCookieC4=123456789", + "TestCookieC5=ABCDEFGHI", + "TestCookieC6=JKLMNOPQR", + "TestCookieC7=STUVWXYZ" + }; + + var cookieOptions = new CookieOptions() + { + Domain = "foo.com", + Path = "/", + Secure = true + }; + + httpContext.Response.Headers[HeaderNames.SetCookie] = new[] + { + "TestCookie=chunks-7; domain=foo.com; path=/; secure", + "TestCookieC1=STUVWXYZ; domain=foo.com; path=/; secure", + "TestCookieC2=123456789; domain=foo.com; path=/; secure", + "TestCookieC3=stuvwxyz0; domain=foo.com; path=/; secure", + "TestCookieC4=123456789; domain=foo.com; path=/; secure", + "TestCookieC5=ABCDEFGHI; domain=foo.com; path=/; secure", + "TestCookieC6=JKLMNOPQR; domain=foo.com; path=/; secure", + "TestCookieC7=STUVWXYZ; domain=foo.com; path=/; secure" + }; + + chunkingCookieManager.DeleteCookie(httpContext, "TestCookie", cookieOptions); + Assert.Equal(8, httpContext.Response.Headers[HeaderNames.SetCookie].Count); + Assert.Equal(new[] + { + "TestCookie=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure", + "TestCookieC1=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure", + "TestCookieC2=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure", + "TestCookieC3=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure", + "TestCookieC4=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure", + "TestCookieC5=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure", + "TestCookieC6=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure", + "TestCookieC7=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure" + }, httpContext.Response.Headers[HeaderNames.SetCookie]); + } } } diff --git a/src/Security/perf/Microbenchmarks/ChunkingCookieManagerBenchmark.cs b/src/Security/perf/Microbenchmarks/ChunkingCookieManagerBenchmark.cs new file mode 100644 index 000000000000..103722e8e9b8 --- /dev/null +++ b/src/Security/perf/Microbenchmarks/ChunkingCookieManagerBenchmark.cs @@ -0,0 +1,63 @@ +using BenchmarkDotNet.Attributes; +using Microsoft.AspNetCore.Authentication.Cookies; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Primitives; +using Microsoft.Net.Http.Headers; + +namespace Microsoft.AspNetCore.Security +{ + public class ChunkingCookieManagerBenchmark + { + private ChunkingCookieManager _chunkingCookieManager; + private HttpContext _httpContext; + private CookieOptions _cookieOptions; + private string _stringToAdd; + + [GlobalSetup] + public void GlobalSetup() + { + _chunkingCookieManager = new ChunkingCookieManager() + { + ChunkSize = 86 + }; + + _httpContext = new DefaultHttpContext(); + + _cookieOptions = new CookieOptions() + { + Domain = "foo.com", + Path = "/", + Secure = true + }; + + _httpContext.Request.Headers["Cookie"] = new[] + { + "TestCookie=chunks-7", + "TestCookieC1=abcdefghi", + "TestCookieC2=jklmnopqr", + "TestCookieC3=stuvwxyz0", + "TestCookieC4=123456789", + "TestCookieC5=ABCDEFGHI", + "TestCookieC6=JKLMNOPQR", + "TestCookieC7=STUVWXYZ" + }; + + _stringToAdd = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + } + + + [Benchmark] + public void AppendCookies() + { + _chunkingCookieManager.AppendResponseCookie(_httpContext, "TestCookie1", _stringToAdd, _cookieOptions); + _httpContext.Response.Headers[HeaderNames.SetCookie] = StringValues.Empty; + } + + [Benchmark] + public void DeleteCookies() + { + _chunkingCookieManager.DeleteCookie(_httpContext, "TestCookie", _cookieOptions); + _httpContext.Response.Headers[HeaderNames.SetCookie] = StringValues.Empty; + } + } +} diff --git a/src/Security/perf/Microbenchmarks/Microsoft.AspNetCore.Security.Microbenchmarks.csproj b/src/Security/perf/Microbenchmarks/Microsoft.AspNetCore.Security.Microbenchmarks.csproj index 0e1fd48c208e..cf86764d09e2 100644 --- a/src/Security/perf/Microbenchmarks/Microsoft.AspNetCore.Security.Microbenchmarks.csproj +++ b/src/Security/perf/Microbenchmarks/Microsoft.AspNetCore.Security.Microbenchmarks.csproj @@ -1,5 +1,5 @@ - + $(DefaultNetCoreTargetFramework) Exe @@ -7,10 +7,11 @@ true Microsoft.AspNetCore.Security - + - + + diff --git a/src/Shared/ChunkingCookieManager/ChunkingCookieManager.cs b/src/Shared/ChunkingCookieManager/ChunkingCookieManager.cs index 05f51180b093..5702cf5729ea 100644 --- a/src/Shared/ChunkingCookieManager/ChunkingCookieManager.cs +++ b/src/Shared/ChunkingCookieManager/ChunkingCookieManager.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; +using System.Text; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Primitives; using Microsoft.Net.Http.Headers; @@ -164,6 +165,14 @@ public void AppendResponseCookie(HttpContext context, string key, string? value, throw new ArgumentNullException(nameof(options)); } + var responseCookies = context.Response.Cookies; + + if (string.IsNullOrEmpty(value)) + { + responseCookies.Append(key, string.Empty, options); + return; + } + var template = new SetCookieHeaderValue(key) { Domain = options.Domain, @@ -177,10 +186,7 @@ public void AppendResponseCookie(HttpContext context, string key, string? value, var templateLength = template.ToString().Length; - value = value ?? string.Empty; - // Normal cookie - var responseCookies = context.Response.Cookies; if (!ChunkSize.HasValue || ChunkSize.Value > templateLength + value.Length) { responseCookies.Append(key, value, options); @@ -202,8 +208,9 @@ public void AppendResponseCookie(HttpContext context, string key, string? value, var dataSizePerCookie = ChunkSize.Value - templateLength - 3; // Budget 3 chars for the chunkid. var cookieChunkCount = (int)Math.Ceiling(value.Length * 1.0 / dataSizePerCookie); - responseCookies.Append(key, ChunkCountPrefix + cookieChunkCount.ToString(CultureInfo.InvariantCulture), options); - + var keyValuePairs = new KeyValuePair[cookieChunkCount + 1]; + keyValuePairs[0] = KeyValuePair.Create(key, ChunkCountPrefix + cookieChunkCount.ToString(CultureInfo.InvariantCulture)); + var offset = 0; for (var chunkId = 1; chunkId <= cookieChunkCount; chunkId++) { @@ -211,9 +218,10 @@ public void AppendResponseCookie(HttpContext context, string key, string? value, var length = Math.Min(dataSizePerCookie, remainingLength); var segment = value.Substring(offset, length); offset += length; - - responseCookies.Append(key + ChunkKeySuffix + chunkId.ToString(CultureInfo.InvariantCulture), segment, options); + keyValuePairs[chunkId] = KeyValuePair.Create(string.Concat(key, ChunkKeySuffix, chunkId.ToString(CultureInfo.InvariantCulture)), segment); } + + responseCookies.Append(keyValuePairs, options); } } @@ -241,14 +249,16 @@ public void DeleteCookie(HttpContext context, string key, CookieOptions options) throw new ArgumentNullException(nameof(options)); } - var keys = new List(); - keys.Add(key + "="); + var keys = new List + { + key + "=" + }; var requestCookie = context.Request.Cookies[key]; var chunks = ParseChunksCount(requestCookie); if (chunks > 0) { - for (int i = 1; i <= chunks + 1; i++) + for (var i = 1; i <= chunks + 1; i++) { var subkey = key + ChunkKeySuffix + i.ToString(CultureInfo.InvariantCulture); keys.Add(subkey + "="); @@ -275,43 +285,43 @@ public void DeleteCookie(HttpContext context, string key, CookieOptions options) var responseHeaders = context.Response.Headers; var existingValues = responseHeaders[HeaderNames.SetCookie]; + if (!StringValues.IsNullOrEmpty(existingValues)) { - responseHeaders[HeaderNames.SetCookie] = existingValues.Where(value => !rejectPredicate(value)).ToArray(); - } + var values = existingValues.ToArray(); + var newValues = new List(); - AppendResponseCookie( - context, - key, - string.Empty, - new CookieOptions() + for (var i = 0; i < values.Length; i++) { - Path = options.Path, - Domain = options.Domain, - SameSite = options.SameSite, - Secure = options.Secure, - IsEssential = options.IsEssential, - Expires = DateTimeOffset.UnixEpoch, - HttpOnly = options.HttpOnly, - }); - - for (int i = 1; i <= chunks; i++) - { - AppendResponseCookie( - context, - key + "C" + i.ToString(CultureInfo.InvariantCulture), - string.Empty, - new CookieOptions() + if (!rejectPredicate(values[i])) { - Path = options.Path, - Domain = options.Domain, - SameSite = options.SameSite, - Secure = options.Secure, - IsEssential = options.IsEssential, - Expires = DateTimeOffset.UnixEpoch, - HttpOnly = options.HttpOnly, - }); + newValues.Add(values[i]); + } + } + + responseHeaders[HeaderNames.SetCookie] = new StringValues(newValues.ToArray()); + } + + var responseCookies = context.Response.Cookies; + + var keyValuePairs = new KeyValuePair[chunks + 1]; + keyValuePairs[0] = KeyValuePair.Create(key, string.Empty); + + for (var i = 1; i <= chunks; i++) + { + keyValuePairs[i] = KeyValuePair.Create(string.Concat(key, "C", i.ToString(CultureInfo.InvariantCulture)), string.Empty); } + + responseCookies.Append(keyValuePairs, new CookieOptions() + { + Path = options.Path, + Domain = options.Domain, + SameSite = options.SameSite, + Secure = options.Secure, + IsEssential = options.IsEssential, + Expires = DateTimeOffset.UnixEpoch, + HttpOnly = options.HttpOnly, + }); } } }