diff --git a/.autover/changes/9e75413c-9cb6-4521-aaca-09b557fff2b3.json b/.autover/changes/9e75413c-9cb6-4521-aaca-09b557fff2b3.json new file mode 100644 index 000000000..691797349 --- /dev/null +++ b/.autover/changes/9e75413c-9cb6-4521-aaca-09b557fff2b3.json @@ -0,0 +1,49 @@ +{ + "Projects": [ + { + "Name": "Amazon.Lambda.Core", + "Type": "Minor", + "ChangelogMessages": [ + "Lambda response streaming is now available as GA. The RequiresPreviewFeatures attribute has been removed", + "The LambdaLogger.ConfigureStructuredLogging API has been deployed to the managed runtime. The RequiresPreviewFeatures attribute has been removed" + ] + }, + { + "Name": "Amazon.Lambda.Annotations", + "Type": "Minor", + "ChangelogMessages": [ + "Updated Amazon.Lambda.Core dependency to include Lambda Response Streaming support." + ] + }, + { + "Name": "Amazon.Lambda.AspNetCoreServer", + "Type": "Minor", + "ChangelogMessages": [ + "Removed RequiresPreviewFeatures attribute for Lambda Response Streaming." + "Updated Amazon.Lambda.Core dependency to include Lambda Response Streaming support." + ] + }, + { + "Name": "Amazon.Lambda.AspNetCoreServer.Hosting", + "Type": "Minor", + "ChangelogMessages": [ + "Removed RequiresPreviewFeatures attribute for Lambda Response Streaming." + "Updated Amazon.Lambda.Core dependency to include Lambda Response Streaming support." + ] + }, + { + "Name": "Amazon.Lambda.PowerShellHost", + "Type": "Minor", + "ChangelogMessages": [ + "Updated Amazon.Lambda.Core dependency to include Lambda Response Streaming support." + ] + }, + { + "Name": "Amazon.Lambda.RuntimeSupport", + "Type": "Minor", + "ChangelogMessages": [ + "Updated Amazon.Lambda.Core dependency to include Lambda Response Streaming support." + ] + } + ] +} \ No newline at end of file diff --git a/Libraries/src/Amazon.Lambda.AspNetCoreServer.Hosting/HostingOptions.cs b/Libraries/src/Amazon.Lambda.AspNetCoreServer.Hosting/HostingOptions.cs index cf7ef34ba..3389368c7 100644 --- a/Libraries/src/Amazon.Lambda.AspNetCoreServer.Hosting/HostingOptions.cs +++ b/Libraries/src/Amazon.Lambda.AspNetCoreServer.Hosting/HostingOptions.cs @@ -39,7 +39,6 @@ public class HostingOptions /// FunctionHandlerAsync writes directly to the Lambda response stream and /// returns null. Requires net8.0 or later. /// - [System.Runtime.Versioning.RequiresPreviewFeatures(ParameterizedPreviewMessage)] public bool EnableResponseStreaming { get; set; } = false; /// diff --git a/Libraries/src/Amazon.Lambda.AspNetCoreServer/APIGatewayHttpApiV2ProxyFunction.cs b/Libraries/src/Amazon.Lambda.AspNetCoreServer/APIGatewayHttpApiV2ProxyFunction.cs index 819306c30..e9578068c 100644 --- a/Libraries/src/Amazon.Lambda.AspNetCoreServer/APIGatewayHttpApiV2ProxyFunction.cs +++ b/Libraries/src/Amazon.Lambda.AspNetCoreServer/APIGatewayHttpApiV2ProxyFunction.cs @@ -59,7 +59,6 @@ private protected override void InternalCustomResponseExceptionHandling(APIGatew /// instead of multiValueHeaders. API Gateway HTTP API v2 expects the headers /// format; using multiValueHeaders causes a 500 Internal Server Error. /// - [System.Runtime.Versioning.RequiresPreviewFeatures(ParameterizedPreviewMessage)] protected override Amazon.Lambda.Core.ResponseStreaming.HttpResponseStreamPrelude BuildStreamingPrelude(IHttpResponseFeature responseFeature) { var prelude = new Amazon.Lambda.Core.ResponseStreaming.HttpResponseStreamPrelude diff --git a/Libraries/src/Amazon.Lambda.AspNetCoreServer/APIGatewayProxyFunction.cs b/Libraries/src/Amazon.Lambda.AspNetCoreServer/APIGatewayProxyFunction.cs index 1398239de..4e3e7a35d 100644 --- a/Libraries/src/Amazon.Lambda.AspNetCoreServer/APIGatewayProxyFunction.cs +++ b/Libraries/src/Amazon.Lambda.AspNetCoreServer/APIGatewayProxyFunction.cs @@ -113,7 +113,6 @@ private protected override void InternalCustomResponseExceptionHandling(APIGatew /// /// The ASP.NET Core response feature for the current invocation. /// A populated . - [System.Runtime.Versioning.RequiresPreviewFeatures(ParameterizedPreviewMessage)] protected override Amazon.Lambda.Core.ResponseStreaming.HttpResponseStreamPrelude BuildStreamingPrelude(IHttpResponseFeature responseFeature) { var prelude = new Amazon.Lambda.Core.ResponseStreaming.HttpResponseStreamPrelude diff --git a/Libraries/src/Amazon.Lambda.AspNetCoreServer/AbstractAspNetCoreFunction.cs b/Libraries/src/Amazon.Lambda.AspNetCoreServer/AbstractAspNetCoreFunction.cs index 51c930333..55b69f67f 100644 --- a/Libraries/src/Amazon.Lambda.AspNetCoreServer/AbstractAspNetCoreFunction.cs +++ b/Libraries/src/Amazon.Lambda.AspNetCoreServer/AbstractAspNetCoreFunction.cs @@ -24,12 +24,6 @@ namespace Amazon.Lambda.AspNetCoreServer /// public abstract class AbstractAspNetCoreFunction { - internal const string ParameterizedPreviewMessage = - "Response streaming is in preview till a new version of .NET Lambda runtime client that supports response streaming " + - "has been deployed to the .NET Lambda managed runtime. Till deployment has been made the feature can be used by deploying as an " + - "executable including the latest version of Amazon.Lambda.RuntimeSupport and setting the \"EnablePreviewFeatures\" in the Lambda " + - "project file to \"true\""; - /// /// Key to access the ILambdaContext object from the HttpContext.Items collection. /// @@ -206,7 +200,6 @@ public void RegisterResponseContentEncodingForContentEncoding(string contentEnco /// buffering it and returning a typed response object (which will be null). /// Requires net8.0 or later. /// - [System.Runtime.Versioning.RequiresPreviewFeatures(ParameterizedPreviewMessage)] public virtual bool EnableResponseStreaming { get; set; } = false; @@ -678,7 +671,6 @@ protected virtual void PostMarshallResponseFeature(IHttpResponseFeature aspNetCo /// /// The ASP.NET Core response feature for the current invocation. /// A populated . - [System.Runtime.Versioning.RequiresPreviewFeatures(ParameterizedPreviewMessage)] protected abstract Amazon.Lambda.Core.ResponseStreaming.HttpResponseStreamPrelude BuildStreamingPrelude(IHttpResponseFeature responseFeature); /// @@ -689,7 +681,6 @@ protected virtual void PostMarshallResponseFeature(IHttpResponseFeature aspNetCo /// /// The HTTP response prelude containing status code and headers. /// A writable for the response body. - [System.Runtime.Versioning.RequiresPreviewFeatures(ParameterizedPreviewMessage)] protected virtual System.IO.Stream CreateLambdaResponseStream( Amazon.Lambda.Core.ResponseStreaming.HttpResponseStreamPrelude prelude) { @@ -701,7 +692,6 @@ protected virtual System.IO.Stream CreateLambdaResponseStream( /// is true. Writes the response directly to a /// . /// - [System.Runtime.Versioning.RequiresPreviewFeatures(ParameterizedPreviewMessage)] private async Task ExecuteStreamingRequestAsync(InvokeFeatures features) { var responseFeature = (IHttpResponseFeature)features; diff --git a/Libraries/src/Amazon.Lambda.AspNetCoreServer/ApplicationLoadBalancerFunction.cs b/Libraries/src/Amazon.Lambda.AspNetCoreServer/ApplicationLoadBalancerFunction.cs index 2bb08c711..6a2805088 100644 --- a/Libraries/src/Amazon.Lambda.AspNetCoreServer/ApplicationLoadBalancerFunction.cs +++ b/Libraries/src/Amazon.Lambda.AspNetCoreServer/ApplicationLoadBalancerFunction.cs @@ -225,7 +225,6 @@ private protected override void InternalCustomResponseExceptionHandling(Applicat } /// - [System.Runtime.Versioning.RequiresPreviewFeatures(ParameterizedPreviewMessage)] protected override HttpResponseStreamPrelude BuildStreamingPrelude(IHttpResponseFeature responseFeature) => throw new NotImplementedException(); private string GetSingleHeaderValue(ApplicationLoadBalancerRequest request, string headerName) diff --git a/Libraries/src/Amazon.Lambda.AspNetCoreServer/Internal/StreamingResponseBodyFeature.cs b/Libraries/src/Amazon.Lambda.AspNetCoreServer/Internal/StreamingResponseBodyFeature.cs index 03ec929a1..22084f4b0 100644 --- a/Libraries/src/Amazon.Lambda.AspNetCoreServer/Internal/StreamingResponseBodyFeature.cs +++ b/Libraries/src/Amazon.Lambda.AspNetCoreServer/Internal/StreamingResponseBodyFeature.cs @@ -20,7 +20,6 @@ namespace Amazon.Lambda.AspNetCoreServer.Internal /// ; after all writes go directly to the /// obtained from the stream opener delegate. /// - [RequiresPreviewFeatures(AbstractAspNetCoreFunction.ParameterizedPreviewMessage)] internal class StreamingResponseBodyFeature : IHttpResponseBodyFeature { private readonly ILogger _logger; diff --git a/Libraries/src/Amazon.Lambda.Core/LambdaLogger.cs b/Libraries/src/Amazon.Lambda.Core/LambdaLogger.cs index 38afe7371..de5ddc407 100644 --- a/Libraries/src/Amazon.Lambda.Core/LambdaLogger.cs +++ b/Libraries/src/Amazon.Lambda.Core/LambdaLogger.cs @@ -139,7 +139,6 @@ public static void Log(string level, Exception exception, string message, params /// When structured logging is enabled this method will allow overriding the default configuration the Lambda runtime uses for structured logging. /// /// The options to use for configuring structured logging. - [RequiresPreviewFeatures("This method is in preview until the latest changes of the .NET Lambda runtime client have been deployed to the Lambda managed runtimes")] public static void ConfigureStructuredLogging(StructuredLoggingOptions options) => _configureStructuredLoggingAction(options); internal static void SetConfigureStructuredLoggingAction(Action configureStructuredLoggingAction) diff --git a/Libraries/src/Amazon.Lambda.Core/ResponseStreaming/HttpResponseStreamPrelude.cs b/Libraries/src/Amazon.Lambda.Core/ResponseStreaming/HttpResponseStreamPrelude.cs index 1a10aa2dc..4ac36491a 100644 --- a/Libraries/src/Amazon.Lambda.Core/ResponseStreaming/HttpResponseStreamPrelude.cs +++ b/Libraries/src/Amazon.Lambda.Core/ResponseStreaming/HttpResponseStreamPrelude.cs @@ -15,7 +15,6 @@ namespace Amazon.Lambda.Core.ResponseStreaming /// headers, and cookies for the response. The prelude must be sent as the first chunk of the response stream, followed by the response body chunks. /// This allows you to set the status code and headers for the response before sending any of the response body. /// - [RequiresPreviewFeatures(LambdaResponseStreamFactory.PreviewMessage)] public class HttpResponseStreamPrelude { /// diff --git a/Libraries/src/Amazon.Lambda.Core/ResponseStreaming/LambdaResponseStream.cs b/Libraries/src/Amazon.Lambda.Core/ResponseStreaming/LambdaResponseStream.cs index 83ac446a4..f61bb7f3f 100644 --- a/Libraries/src/Amazon.Lambda.Core/ResponseStreaming/LambdaResponseStream.cs +++ b/Libraries/src/Amazon.Lambda.Core/ResponseStreaming/LambdaResponseStream.cs @@ -15,7 +15,6 @@ namespace Amazon.Lambda.Core.ResponseStreaming /// to the Lambda Runtime API. Returned by . /// Integrates with standard .NET stream consumers such as . /// - [RequiresPreviewFeatures(LambdaResponseStreamFactory.PreviewMessage)] public class LambdaResponseStream : Stream { private readonly ILambdaResponseStream _responseStream; diff --git a/Libraries/src/Amazon.Lambda.Core/ResponseStreaming/LambdaResponseStreamFactory.cs b/Libraries/src/Amazon.Lambda.Core/ResponseStreaming/LambdaResponseStreamFactory.cs index 1b9e6d3b6..29bddfa05 100644 --- a/Libraries/src/Amazon.Lambda.Core/ResponseStreaming/LambdaResponseStreamFactory.cs +++ b/Libraries/src/Amazon.Lambda.Core/ResponseStreaming/LambdaResponseStreamFactory.cs @@ -10,15 +10,8 @@ namespace Amazon.Lambda.Core.ResponseStreaming /// /// Factory to create Lambda response streams for writing streaming responses in AWS Lambda functions. The created streams are write-only and non-seekable. /// - [RequiresPreviewFeatures(LambdaResponseStreamFactory.PreviewMessage)] public class LambdaResponseStreamFactory { - internal const string PreviewMessage = - "Response streaming is in preview till a new version of .NET Lambda runtime client that supports response streaming " + - "has been deployed to the .NET Lambda managed runtime. Till deployment has been made the feature can be used by deploying as an " + - "executable including the latest version of Amazon.Lambda.RuntimeSupport and setting the \"EnablePreviewFeatures\" in the Lambda " + - "project file to \"true\""; - internal const string UninitializedFactoryMessage = "LambdaResponseStreamFactory is not initialized. This is caused by mismatch versions of Amazon.Lambda.Core and Amazon.Lambda.RuntimeSupport. " + "Update both packages to the current version to address the issue."; diff --git a/Libraries/test/Amazon.Lambda.AspNetCoreServer.Hosting.Tests/ResponseStreamingHostingTests.cs b/Libraries/test/Amazon.Lambda.AspNetCoreServer.Hosting.Tests/ResponseStreamingHostingTests.cs index f70f91629..b9718aca9 100644 --- a/Libraries/test/Amazon.Lambda.AspNetCoreServer.Hosting.Tests/ResponseStreamingHostingTests.cs +++ b/Libraries/test/Amazon.Lambda.AspNetCoreServer.Hosting.Tests/ResponseStreamingHostingTests.cs @@ -16,7 +16,6 @@ namespace Amazon.Lambda.AspNetCoreServer.Hosting.Tests; /// /// Tests for response streaming integration in hosting (Requirement 10). /// -[RequiresPreviewFeatures] public class ResponseStreamingHostingTests { [Fact] diff --git a/Libraries/test/Amazon.Lambda.AspNetCoreServer.Hosting.Tests/ResponseStreamingPropertyTests.cs b/Libraries/test/Amazon.Lambda.AspNetCoreServer.Hosting.Tests/ResponseStreamingPropertyTests.cs index 43ebc4dd4..0717e29cd 100644 --- a/Libraries/test/Amazon.Lambda.AspNetCoreServer.Hosting.Tests/ResponseStreamingPropertyTests.cs +++ b/Libraries/test/Amazon.Lambda.AspNetCoreServer.Hosting.Tests/ResponseStreamingPropertyTests.cs @@ -14,7 +14,6 @@ namespace Amazon.Lambda.AspNetCoreServer.Hosting.Tests; -[RequiresPreviewFeatures] public class ResponseStreamingPropertyTests { private static IServiceProvider BuildServiceProvider(HostingOptions hostingOptions) diff --git a/Libraries/test/Amazon.Lambda.AspNetCoreServer.Test/BuildStreamingPreludeTests.cs b/Libraries/test/Amazon.Lambda.AspNetCoreServer.Test/BuildStreamingPreludeTests.cs index c2971d0ab..2e4122b1b 100644 --- a/Libraries/test/Amazon.Lambda.AspNetCoreServer.Test/BuildStreamingPreludeTests.cs +++ b/Libraries/test/Amazon.Lambda.AspNetCoreServer.Test/BuildStreamingPreludeTests.cs @@ -9,7 +9,6 @@ namespace Amazon.Lambda.AspNetCoreServer.Test { - [RequiresPreviewFeatures] public class BuildStreamingPreludeTests { // Subclass that skips host startup entirely and @@ -83,10 +82,12 @@ public void StatusCode_DefaultsTo200_WhenFeatureStatusCodeIsZero() } // ----------------------------------------------------------------------- - // 6.3 Non-Set-Cookie headers appear in MultiValueHeaders with all values preserved + // 6.3 Non-Set-Cookie headers appear in Headers with all values preserved. + // HTTP API v2 uses the single-value "headers" collection (not "multiValueHeaders"), + // so multiple values for the same header are joined with ", ". // ----------------------------------------------------------------------- [Fact] - public void NonSetCookieHeaders_AppearInMultiValueHeaders_WithAllValuesPreserved() + public void NonSetCookieHeaders_AppearInHeaders_WithAllValuesPreserved() { var builder = CreateBuilder(); var rf = MakeResponseFeature(200, new System.Collections.Generic.Dictionary @@ -98,18 +99,18 @@ public void NonSetCookieHeaders_AppearInMultiValueHeaders_WithAllValuesPreserved var prelude = builder.InvokeBuildStreamingPrelude(rf); - Assert.True(prelude.MultiValueHeaders.ContainsKey("Content-Type")); - Assert.Equal(new[] { "application/json" }, prelude.MultiValueHeaders["Content-Type"]); + Assert.True(prelude.Headers.ContainsKey("Content-Type")); + Assert.Equal("application/json", prelude.Headers["Content-Type"]); - Assert.True(prelude.MultiValueHeaders.ContainsKey("X-Custom")); - Assert.Equal(new[] { "val1", "val2" }, prelude.MultiValueHeaders["X-Custom"]); + Assert.True(prelude.Headers.ContainsKey("X-Custom")); + Assert.Equal("val1, val2", prelude.Headers["X-Custom"]); - Assert.True(prelude.MultiValueHeaders.ContainsKey("Cache-Control")); - Assert.Equal(new[] { "no-cache", "no-store" }, prelude.MultiValueHeaders["Cache-Control"]); + Assert.True(prelude.Headers.ContainsKey("Cache-Control")); + Assert.Equal("no-cache, no-store", prelude.Headers["Cache-Control"]); } [Fact] - public void NonSetCookieHeaders_MultiValueHeaders_PreservesMultipleValues() + public void NonSetCookieHeaders_Headers_JoinsMultipleValues() { var builder = CreateBuilder(); var rf = MakeResponseFeature(200, new System.Collections.Generic.Dictionary @@ -119,8 +120,8 @@ public void NonSetCookieHeaders_MultiValueHeaders_PreservesMultipleValues() var prelude = builder.InvokeBuildStreamingPrelude(rf); - Assert.Equal(new[] { "text/html", "application/xhtml+xml", "application/xml" }, - prelude.MultiValueHeaders["Accept"]); + Assert.Equal("text/html, application/xhtml+xml, application/xml", + prelude.Headers["Accept"]); } // ----------------------------------------------------------------------- @@ -141,12 +142,12 @@ public void SetCookieHeader_MovedToCookies_AbsentFromMultiValueHeaders() // Cookie value is in Cookies Assert.Contains("session=abc123; Path=/; HttpOnly", prelude.Cookies); - // Set-Cookie is NOT in MultiValueHeaders - Assert.False(prelude.MultiValueHeaders.ContainsKey("Set-Cookie")); - Assert.False(prelude.MultiValueHeaders.ContainsKey("set-cookie")); + // Set-Cookie is NOT in Headers + Assert.False(prelude.Headers.ContainsKey("Set-Cookie")); + Assert.False(prelude.Headers.ContainsKey("set-cookie")); // Other headers are still present - Assert.True(prelude.MultiValueHeaders.ContainsKey("Content-Type")); + Assert.True(prelude.Headers.ContainsKey("Content-Type")); } [Fact] @@ -164,8 +165,8 @@ public void SetCookieHeader_IsCaseInsensitive() var prelude = builder.InvokeBuildStreamingPrelude(rf); Assert.Contains("id=xyz; Path=/", prelude.Cookies); - Assert.False(prelude.MultiValueHeaders.ContainsKey("Set-Cookie")); - Assert.False(prelude.MultiValueHeaders.ContainsKey("set-cookie")); + Assert.False(prelude.Headers.ContainsKey("Set-Cookie")); + Assert.False(prelude.Headers.ContainsKey("set-cookie")); } // ----------------------------------------------------------------------- @@ -192,8 +193,8 @@ public void MultipleSetCookieValues_AllAppearInCookies() Assert.Contains("theme=dark; Path=/", prelude.Cookies); Assert.Contains("lang=en; Path=/; SameSite=Strict", prelude.Cookies); - // None of them should be in MultiValueHeaders - Assert.False(prelude.MultiValueHeaders.ContainsKey("Set-Cookie")); + // None of them should be in Headers + Assert.False(prelude.Headers.ContainsKey("Set-Cookie")); } [Fact] @@ -212,8 +213,8 @@ public void MultipleSetCookieValues_WithOtherHeaders_CookiesAndHeadersAreSeparat Assert.Equal(2, prelude.Cookies.Count); Assert.Contains("a=1", prelude.Cookies); Assert.Contains("b=2", prelude.Cookies); - Assert.True(prelude.MultiValueHeaders.ContainsKey("Location")); - Assert.False(prelude.MultiValueHeaders.ContainsKey("Set-Cookie")); + Assert.True(prelude.Headers.ContainsKey("Location")); + Assert.False(prelude.Headers.ContainsKey("Set-Cookie")); } [Fact] @@ -225,7 +226,7 @@ public void EmptyHeaders_ProducesEmptyMultiValueHeadersAndCookies() var prelude = builder.InvokeBuildStreamingPrelude(rf); Assert.Equal(HttpStatusCode.NoContent, prelude.StatusCode); - Assert.Empty(prelude.MultiValueHeaders); + Assert.Empty(prelude.Headers); Assert.Empty(prelude.Cookies); } @@ -244,8 +245,8 @@ public void ContentLengthHeader_ExcludedFromPrelude() var prelude = builder.InvokeBuildStreamingPrelude(rf); - Assert.True(prelude.MultiValueHeaders.ContainsKey("Content-Type")); - Assert.False(prelude.MultiValueHeaders.ContainsKey("Content-Length")); + Assert.True(prelude.Headers.ContainsKey("Content-Type")); + Assert.False(prelude.Headers.ContainsKey("Content-Length")); } [Fact] @@ -260,8 +261,8 @@ public void TransferEncodingHeader_ExcludedFromPrelude() var prelude = builder.InvokeBuildStreamingPrelude(rf); - Assert.True(prelude.MultiValueHeaders.ContainsKey("Content-Type")); - Assert.False(prelude.MultiValueHeaders.ContainsKey("Transfer-Encoding")); + Assert.True(prelude.Headers.ContainsKey("Content-Type")); + Assert.False(prelude.Headers.ContainsKey("Transfer-Encoding")); } } } diff --git a/Libraries/test/Amazon.Lambda.AspNetCoreServer.Test/ResponseStreamingPropertyTests.cs b/Libraries/test/Amazon.Lambda.AspNetCoreServer.Test/ResponseStreamingPropertyTests.cs index 05c6bed87..013c015a3 100644 --- a/Libraries/test/Amazon.Lambda.AspNetCoreServer.Test/ResponseStreamingPropertyTests.cs +++ b/Libraries/test/Amazon.Lambda.AspNetCoreServer.Test/ResponseStreamingPropertyTests.cs @@ -20,7 +20,6 @@ namespace Amazon.Lambda.AspNetCoreServer.Test { - [RequiresPreviewFeatures] public class ResponseStreamingPropertyTests { // ----------------------------------------------------------------------- @@ -52,7 +51,6 @@ protected override void PostMarshallItemsFeatureFeature( base.PostMarshallItemsFeatureFeature(aspNetCoreItemFeature, lambdaRequest, lambdaContext); } - [RequiresPreviewFeatures] protected override Stream CreateLambdaResponseStream( Amazon.Lambda.Core.ResponseStreaming.HttpResponseStreamPrelude prelude) { @@ -195,12 +193,13 @@ public void Property3_Prelude_StatusCodeAndNonCookieHeaders_Correct( int expectedStatus = statusCode == 0 ? 200 : statusCode; Assert.Equal((System.Net.HttpStatusCode)expectedStatus, prelude.StatusCode); - Assert.True(prelude.MultiValueHeaders.ContainsKey(headerKey), - $"Header '{headerKey}' missing from MultiValueHeaders"); - Assert.Equal(headerValues, prelude.MultiValueHeaders[headerKey].ToArray()); + // HTTP API v2 uses the single-value "headers" collection; multiple values are joined with ", ". + Assert.True(prelude.Headers.ContainsKey(headerKey), + $"Header '{headerKey}' missing from Headers"); + Assert.Equal(string.Join(", ", headerValues), prelude.Headers[headerKey]); - Assert.False(prelude.MultiValueHeaders.ContainsKey("Set-Cookie")); - Assert.False(prelude.MultiValueHeaders.ContainsKey("set-cookie")); + Assert.False(prelude.Headers.ContainsKey("Set-Cookie")); + Assert.False(prelude.Headers.ContainsKey("set-cookie")); } @@ -227,12 +226,12 @@ public void Property4_SetCookieHeaders_MovedToCookies_AbsentFromMultiValueHeader foreach (var cookie in cookies) Assert.Contains(cookie, prelude.Cookies); - Assert.False(prelude.MultiValueHeaders.ContainsKey("Set-Cookie"), - "Set-Cookie must not appear in MultiValueHeaders"); - Assert.False(prelude.MultiValueHeaders.ContainsKey("set-cookie"), - "set-cookie must not appear in MultiValueHeaders"); + Assert.False(prelude.Headers.ContainsKey("Set-Cookie"), + "Set-Cookie must not appear in Headers"); + Assert.False(prelude.Headers.ContainsKey("set-cookie"), + "set-cookie must not appear in Headers"); - Assert.True(prelude.MultiValueHeaders.ContainsKey("content-type")); + Assert.True(prelude.Headers.ContainsKey("content-type")); } @@ -446,7 +445,6 @@ protected override void PostMarshallItemsFeatureFeature( base.PostMarshallItemsFeatureFeature(aspNetCoreItemFeature, lambdaRequest, lambdaContext); } - [RequiresPreviewFeatures] protected override Stream CreateLambdaResponseStream( Amazon.Lambda.Core.ResponseStreaming.HttpResponseStreamPrelude prelude) { diff --git a/Libraries/test/Amazon.Lambda.AspNetCoreServer.Test/StreamingFunctionHandlerAsyncTests.cs b/Libraries/test/Amazon.Lambda.AspNetCoreServer.Test/StreamingFunctionHandlerAsyncTests.cs index 6ba2a6291..ef5c9711a 100644 --- a/Libraries/test/Amazon.Lambda.AspNetCoreServer.Test/StreamingFunctionHandlerAsyncTests.cs +++ b/Libraries/test/Amazon.Lambda.AspNetCoreServer.Test/StreamingFunctionHandlerAsyncTests.cs @@ -30,7 +30,6 @@ namespace Amazon.Lambda.AspNetCoreServer.Test /// a instead of calling LambdaResponseStreamFactory.CreateHttpStream, /// allowing tests to run without the Lambda runtime. /// - [RequiresPreviewFeatures] public class StreamingFunctionHandlerAsyncTests { // ----------------------------------------------------------------------- @@ -75,7 +74,6 @@ protected override void PostMarshallItemsFeatureFeature( base.PostMarshallItemsFeatureFeature(aspNetCoreItemFeature, lambdaRequest, lambdaContext); } - [RequiresPreviewFeatures] protected override Stream CreateLambdaResponseStream( Amazon.Lambda.Core.ResponseStreaming.HttpResponseStreamPrelude prelude) { @@ -467,18 +465,6 @@ public void FunctionHandlerAsync_HasLambdaSerializerAttribute() attr.SerializerType); } - [Fact] - public void EnableResponseStreaming_Property_HasRequiresPreviewFeaturesAttribute() - { - var prop = typeof(APIGatewayHttpApiV2ProxyFunction) - .GetProperty(nameof(APIGatewayHttpApiV2ProxyFunction.EnableResponseStreaming)); - - Assert.NotNull(prop); - - var attr = prop.GetCustomAttribute(); - Assert.NotNull(attr); - } - [Fact] public void EnableResponseStreaming_Property_DefaultsToFalse() { @@ -531,7 +517,6 @@ protected CustomPipelineStreamingFunction() EnableResponseStreaming = true; } - [RequiresPreviewFeatures] protected override Stream CreateLambdaResponseStream( Amazon.Lambda.Core.ResponseStreaming.HttpResponseStreamPrelude prelude) { diff --git a/Libraries/test/Amazon.Lambda.AspNetCoreServer.Test/StreamingResponseBodyFeatureTests.cs b/Libraries/test/Amazon.Lambda.AspNetCoreServer.Test/StreamingResponseBodyFeatureTests.cs index cdbd403e4..e7686ec64 100644 --- a/Libraries/test/Amazon.Lambda.AspNetCoreServer.Test/StreamingResponseBodyFeatureTests.cs +++ b/Libraries/test/Amazon.Lambda.AspNetCoreServer.Test/StreamingResponseBodyFeatureTests.cs @@ -11,7 +11,6 @@ namespace Amazon.Lambda.AspNetCoreServer.Test { - [RequiresPreviewFeatures] public class StreamingResponseBodyFeatureTests { // Helper: creates a StreamingResponseBodyFeature backed by a MemoryStream stand-in.