aspnetcore icon indicating copy to clipboard operation
aspnetcore copied to clipboard

Duplicate Accept-Ranges Header when using MapStaticAssets

Open Spacefish opened this issue 1 year ago • 3 comments

Is there an existing issue for this?

  • [X] I have searched the existing issues

Describe the bug

I created a new .NET 9 Preview 5 Web API Project and added the app.MapStaticAssets() right after app.MapControllers();

when i put .png files into wwwroot publish the app and then access one of the .PNG files. The server reponds with two "Accept-Ranges: bytes" headers instead of one:

image

Expected Behavior

The "Accept-Ranges" header should only be included once in the response

Steps To Reproduce

No response

Exceptions (if any)

No response

.NET Version

9.0.100-preview.5.24307.3

Anything else?

One time it´s probably added here: https://github.com/dotnet/aspnetcore/blob/94e0528789588c56e3cf4e26d15f1dba29b70ecb/src/StaticAssets/src/StaticAssetsInvoker.cs#L100

Spacefish avatar Jun 24 '24 21:06 Spacefish

I have the same problem with 9.0.100-rc.2.24474.11 and a Razor Pages project. The ETag header also appears twice, with different values.

app.MapStaticAssets();
app.MapRazorPages().WithStaticAssets();
<link rel="icon" href="~/favicon.svg" type="image/svg+xml" />

Image

rmacfie avatar Oct 19 '24 16:10 rmacfie

@rmacfie the ETag values look correct. One is a strong ETag, the other is a weak ETag.

meenzen avatar Oct 19 '24 17:10 meenzen

@rmacfie the ETag values look correct. One is a strong ETag, the other is a weak ETag.

I see, thanks. I didn't know about weak/strong ETags.

rmacfie avatar Oct 19 '24 17:10 rmacfie

Actually, I have to retract my previous statement

@rmacfie the ETag values look correct. One is a strong ETag, the other is a weak ETag.

This is in fact a problem, nginx logs now show this:

[warn] 28#28: *13 upstream sent duplicate header line: "ETag: W/"LFlDWVt+WUQe+BA4QzvZFa7xxShkuDO3RUnd2NMZqck="", previous value: "ETag: "f0tElo7+QL7qWWjny3nVY1Vm4Gez30sJ4Q4cd+pywNg="", ignored while reading response header from upstream

meenzen avatar Jan 13 '25 14:01 meenzen

Hello,

Any word on this? We are having problems with our IDS which is complaining about the wrong headers in HTTP responses.

Just to summarize there is more than one issue:

1 Duplicate Accept-Range which is not a multiple value header therefore should appear only once in a response according to this RFC https://datatracker.ietf.org/doc/html/rfc7233#section-2.3

2 Vary is set to Content-Enconding which might be good for proxies but browsers expect Vary: Accept-Encoding. Furthermore the Content-Encoding is the header that must be set by the party that applied the encoding in this case clearly the server https://datatracker.ietf.org/doc/html/rfc7231#section-3.1.2.2. This contradicts the use of the Vary header which is a list of client headers that affected the decision making of the server. https://datatracker.ietf.org/doc/html/rfc9110#field.vary The RFC clearly states that "what parts of a request message".... This clearly means that the correct header in the Vary response from the server is Accept-Encoding and NOT Content-Encoding. This is because the client did NOT send Content-Ecoding...it sends Accept-Encoding. So using the Vary with a server response headers is not correct.

I repro the issue by createing a MVC web app with the latest workload and making sure MapStaticAssets is turned on:

Image

vitasystems avatar Feb 11 '25 18:02 vitasystems

Running .NET Core 9.0.103 - having the exact same issue. I went through all possible solutions suggested by one popular LLM and once it exploded I came to this thread. Any solution/workarounds?

grzegorzurbanek avatar Mar 07 '25 13:03 grzegorzurbanek

Fixed by https://github.com/dotnet/sdk/pull/50149 and https://github.com/dotnet/sdk/pull/50291.

You can control the final set of headers via endpoint routing and a convention. Like

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapStaticAssets()
   .Add(endpointBuilder =>
   {
       endpointBuilder.Add(b =>
       {
           b.Use((context, next) =>
           {
               // Schedule header removal at the last possible moment
               context.Response.OnStarting(state =>
               {
                   var httpContext = (HttpContext)state;
                   httpContext.Response.Headers.Remove("Accept-Ranges");
                   return Task.CompletedTask;
               }, context);

               return next();
           });
       });
   });

app.Run();

A fix will be available on the 10.0 RC1 SDK.

javiercn avatar Aug 16 '25 11:08 javiercn