Skip to content

Commit 78f4a21

Browse files
twsouthwickCZEMacLeod
authored andcommitted
Add Content-Type as default header that is set (#186)
This was a default value that it appears some internal teams had relied on and caused problems when they were migrating. This change expands an existing middleware to handle adding any default response headers
1 parent 4a52311 commit 78f4a21

File tree

4 files changed

+85
-32
lines changed

4 files changed

+85
-32
lines changed

src/Microsoft.AspNetCore.SystemWebAdapters.CoreServices/DefaultCacheControlMiddleware.cs

Lines changed: 0 additions & 31 deletions
This file was deleted.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.Threading.Tasks;
5+
using Microsoft.AspNetCore.Http;
6+
using Microsoft.Net.Http.Headers;
7+
8+
namespace Microsoft.AspNetCore.SystemWebAdapters;
9+
10+
/// <summary>
11+
/// System.Web would set some response headers by default. This adds those early in the pipeline so they can still be overridden. If they exist, they will not be replaced.
12+
/// </summary>
13+
internal class SetDefaultResponseHeadersMiddleware
14+
{
15+
private readonly RequestDelegate _next;
16+
17+
private readonly (string Header, string Value)[] _defaultHeaders = new (string, string)[]
18+
{
19+
(HeaderNames.CacheControl, CacheControlHeaderValue.PrivateString),
20+
(HeaderNames.ContentType, "text/html")
21+
};
22+
23+
public SetDefaultResponseHeadersMiddleware(RequestDelegate next) => _next = next;
24+
25+
public Task InvokeAsync(HttpContext context)
26+
{
27+
foreach (var (header, value) in _defaultHeaders)
28+
{
29+
if (!context.Response.Headers.ContainsKey(header))
30+
{
31+
context.Response.Headers[header] = value;
32+
}
33+
}
34+
35+
return _next(context);
36+
}
37+
}

src/Microsoft.AspNetCore.SystemWebAdapters.CoreServices/SystemWebAdaptersExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public static void UseSystemWebAdapters(this IApplicationBuilder app)
2929
{
3030
HttpRuntime.Current = app.ApplicationServices.GetRequiredService<IHttpRuntime>();
3131

32-
app.UseMiddleware<DefaultCacheControlMiddleware>();
32+
app.UseMiddleware<SetDefaultResponseHeadersMiddleware>();
3333
app.UseMiddleware<PreBufferRequestStreamMiddleware>();
3434
app.UseMiddleware<SessionMiddleware>();
3535
app.UseMiddleware<BufferResponseStreamMiddleware>();
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.Threading.Tasks;
5+
using Microsoft.AspNetCore.Http;
6+
using Xunit;
7+
8+
namespace Microsoft.AspNetCore.SystemWebAdapters.Tests;
9+
10+
public class SetDefaultResponseHeadersMiddlewareTests
11+
{
12+
[Fact]
13+
public async Task NoHeaders()
14+
{
15+
// Arrange
16+
var context = new DefaultHttpContext();
17+
var next = Task (HttpContextCore context) => Task.CompletedTask;
18+
var middleware = new SetDefaultResponseHeadersMiddleware(new(next));
19+
20+
// Act
21+
await middleware.InvokeAsync(context);
22+
23+
// Assert
24+
Assert.Equal(2, context.Response.Headers.Count);
25+
Assert.Equal("text/html", context.Response.Headers.ContentType);
26+
Assert.Equal("private", context.Response.Headers.CacheControl);
27+
}
28+
29+
[Theory]
30+
[InlineData("Content-Type", "some-content-type")]
31+
[InlineData("Cache-Control", "cache-value")]
32+
public async Task Existing(string name, string value)
33+
{
34+
// Arrange
35+
var context = new DefaultHttpContext();
36+
context.Response.Headers[name] = value;
37+
38+
var next = Task (HttpContextCore context) => Task.CompletedTask;
39+
var middleware = new SetDefaultResponseHeadersMiddleware(new(next));
40+
41+
// Act
42+
await middleware.InvokeAsync(context);
43+
44+
// Assert
45+
Assert.Equal(value, context.Response.Headers[name]);
46+
}
47+
}

0 commit comments

Comments
 (0)