From c1a8f68323622ea21270ef91695e2215823de367 Mon Sep 17 00:00:00 2001 From: Justin Perez Date: Tue, 26 Nov 2024 07:39:23 +0000 Subject: [PATCH 1/2] Return 206 Partial Content on Valid Range for Static Assets --- src/StaticAssets/src/StaticAssetsInvoker.cs | 2 +- .../test/StaticAssetsIntegrationTests.cs | 24 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/StaticAssets/src/StaticAssetsInvoker.cs b/src/StaticAssets/src/StaticAssetsInvoker.cs index 1d21cc2929ec..c7555c901b93 100644 --- a/src/StaticAssets/src/StaticAssetsInvoker.cs +++ b/src/StaticAssets/src/StaticAssetsInvoker.cs @@ -223,7 +223,7 @@ private async Task SendRangeAsync(StaticAssetInvocationContext requestContext, R if (requestContext.Response.StatusCode == StatusCodes.Status200OK) { - requestContext.Response.StatusCode = StatusCodes.Status416RangeNotSatisfiable; + requestContext.Response.StatusCode = StatusCodes.Status206PartialContent; } await ApplyResponseHeadersAsync(requestContext, StatusCodes.Status206PartialContent); diff --git a/src/StaticAssets/test/StaticAssetsIntegrationTests.cs b/src/StaticAssets/test/StaticAssetsIntegrationTests.cs index 541a468a15a2..a316d8d0b1e5 100644 --- a/src/StaticAssets/test/StaticAssetsIntegrationTests.cs +++ b/src/StaticAssets/test/StaticAssetsIntegrationTests.cs @@ -989,6 +989,30 @@ public async Task IfUnmodifiedSinceDateLessThanLastModifiedShouldReturn412(HttpM Assert.Equal(HttpStatusCode.PreconditionFailed, res2.StatusCode); } + // 14.35.2 Range Retrieval Requests + // The presence of a Range header in an unconditional GET modifies + // what is returned if the GET is otherwise successful. In other + // words, the response carries a status code of 206 (Partial + // Content) instead of 200 (OK). + [Fact] + public async Task RangeGivesMatchingRange() + { + var client = await CreateClient(); + + var req1 = new HttpRequestMessage(HttpMethod.Get, "http://localhost/sample.txt"); + req1.Headers.Range = new RangeHeaderValue(0, 4); + var res1 = await client.SendAsync(req1); + + var req2 = new HttpRequestMessage(HttpMethod.Get, "http://localhost/sample.txt"); + req2.Headers.Range = new RangeHeaderValue(7, 11); + var res2 = await client.SendAsync(req2); + + Assert.Equal(HttpStatusCode.PartialContent, res1.StatusCode); + Assert.Equal("Hello", await res1.Content.ReadAsStringAsync()); + Assert.Equal(HttpStatusCode.PartialContent, res2.StatusCode); + Assert.Equal("World", await res2.Content.ReadAsStringAsync()); + } + public static IEnumerable SupportedMethods => new[] { new [] { HttpMethod.Get }, From b8548cf5c8a1f0499e9ae73f7205d69b8910c78c Mon Sep 17 00:00:00 2001 From: Justin Perez Date: Tue, 26 Nov 2024 07:48:01 +0000 Subject: [PATCH 2/2] Assert content length is correct --- src/StaticAssets/test/StaticAssetsIntegrationTests.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/StaticAssets/test/StaticAssetsIntegrationTests.cs b/src/StaticAssets/test/StaticAssetsIntegrationTests.cs index a316d8d0b1e5..fda161ea055a 100644 --- a/src/StaticAssets/test/StaticAssetsIntegrationTests.cs +++ b/src/StaticAssets/test/StaticAssetsIntegrationTests.cs @@ -1009,8 +1009,11 @@ public async Task RangeGivesMatchingRange() Assert.Equal(HttpStatusCode.PartialContent, res1.StatusCode); Assert.Equal("Hello", await res1.Content.ReadAsStringAsync()); + Assert.Equal(5, res1.Content.Headers.ContentLength); + Assert.Equal(HttpStatusCode.PartialContent, res2.StatusCode); Assert.Equal("World", await res2.Content.ReadAsStringAsync()); + Assert.Equal(5, res2.Content.Headers.ContentLength); } public static IEnumerable SupportedMethods => new[]