-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Description
Is there an existing issue for this?
- I have searched the existing issues
Describe the bug
When using the HttpSys server, the request header dictionary (HttpRequest.Headers) behaves unexpectedly when trying to remove a header using IHeaderDictionary.Remove(). The Remove() method fails to remove some headers, even when those headers are present in the request - when enumerating the collection after the call to Remove(), the original header is still returned.
Expected Behavior
If a header is present in the header dictionary, it should be removed from the collection when Remove() is called. Subsequent operations on the collection (enumeration, indexer, ContainsKey, etc.) should not return the removed header.
Steps To Reproduce
Create an ASP.NET Core app, using HttpSys as the server. The code below reproduces the issue.
in Startup.cs:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.Run(httpContext =>
{
var headers = httpContext.Request.Headers;
bool removed = headers.Remove("Connection");
Debug.WriteLine(removed); // prints 'false'
string connection = headers["Connection"];
Debug.WriteLine(connection); // prints 'Close'
return Task.CompletedTask;
});
}in Program.cs:
var builder = Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseHttpSys(options =>
{
options.UrlPrefixes.Add("http://+:5000/");
});
webBuilder.UseStartup<Startup>();
});
var app = builder.Build();
app.Run();This curl command was used:
curl --verbose --header Connection:Close http://localhost:5000/
Note that a number of other headers such as 'Accept-Encoding' also reproduce the issue.
Exceptions (if any)
No response
.NET Version
net6.0
Anything else?
Relevant line of code in RequestHeaders implementation: https://github.com/dotnet/aspnetcore/blob/main/src/Shared/HttpSys/RequestProcessing/RequestHeaders.Generated.cs#L1860
If the _Connection field hasn't been populated at this point in the code, PropertiesTryRemove() returns false and the header isn't removed. Later on, if the same header is retrieved using PropertiesTryGetValue(), the actual header value is retrieved by calling NativeRequestContext.GetKnownHeader().
Other details:
- This issue appears to affect all the 'known' headers listed in the RequestHeaders.Generated.cs file.
- The issue does not repro if the header was previously loaded, due to enumerating the header dictionary or retrieving the header using
request.Headers["Connection"]. - The issue does not repro on Kestrel.