diff --git a/src/Microsoft.AspNetCore.Server.Kestrel/Http/Frame.cs b/src/Microsoft.AspNetCore.Server.Kestrel/Http/Frame.cs
index 467b841fd6..d50aa1b613 100644
--- a/src/Microsoft.AspNetCore.Server.Kestrel/Http/Frame.cs
+++ b/src/Microsoft.AspNetCore.Server.Kestrel/Http/Frame.cs
@@ -610,10 +610,15 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
var responseHeaders = _frameHeaders.ResponseHeaders;
responseHeaders.Reset();
var dateHeaderValues = DateHeaderValueManager.GetDateHeaderValues();
+
responseHeaders.SetRawDate(dateHeaderValues.String, dateHeaderValues.Bytes);
- responseHeaders.SetRawServer("Kestrel", Headers.BytesServer);
responseHeaders.SetRawContentLength("0", _bytesContentLengthZero);
+ if (ServerOptions.AddServerHeader)
+ {
+ responseHeaders.SetRawServer(Constants.ServerName, Headers.BytesServer);
+ }
+
ResponseHeaders = responseHeaders;
}
}
diff --git a/src/Microsoft.AspNetCore.Server.Kestrel/Infrastructure/Constants.cs b/src/Microsoft.AspNetCore.Server.Kestrel/Infrastructure/Constants.cs
index b7dcc01a41..3031b022dc 100644
--- a/src/Microsoft.AspNetCore.Server.Kestrel/Infrastructure/Constants.cs
+++ b/src/Microsoft.AspNetCore.Server.Kestrel/Infrastructure/Constants.cs
@@ -23,6 +23,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Infrastructure
///
public const string RFC1123DateFormat = "r";
+ public const string ServerName = "Kestrel";
+
private static int? GetECONNRESET()
{
switch (PlatformServices.Default.Runtime.OperatingSystemPlatform)
diff --git a/src/Microsoft.AspNetCore.Server.Kestrel/Infrastructure/HttpComponentFactory.cs b/src/Microsoft.AspNetCore.Server.Kestrel/Infrastructure/HttpComponentFactory.cs
index 4d647e2caa..baeb975233 100644
--- a/src/Microsoft.AspNetCore.Server.Kestrel/Infrastructure/HttpComponentFactory.cs
+++ b/src/Microsoft.AspNetCore.Server.Kestrel/Infrastructure/HttpComponentFactory.cs
@@ -50,7 +50,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Infrastructure
if (!_headerPool.TryDequeue(out headers))
{
- headers = new Headers();
+ headers = new Headers(ServerOptions);
}
headers.Initialize(dateValueManager);
@@ -76,11 +76,23 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Infrastructure
public readonly FrameRequestHeaders RequestHeaders = new FrameRequestHeaders();
public readonly FrameResponseHeaders ResponseHeaders = new FrameResponseHeaders();
+ private readonly KestrelServerOptions _options;
+
+ public Headers(KestrelServerOptions options)
+ {
+ _options = options;
+ }
+
public void Initialize(DateHeaderValueManager dateValueManager)
{
var dateHeaderValues = dateValueManager.GetDateHeaderValues();
+
ResponseHeaders.SetRawDate(dateHeaderValues.String, dateHeaderValues.Bytes);
- ResponseHeaders.SetRawServer("Kestrel", BytesServer);
+
+ if (_options.AddServerHeader)
+ {
+ ResponseHeaders.SetRawServer(Constants.ServerName, BytesServer);
+ }
}
public void Uninitialize()
diff --git a/src/Microsoft.AspNetCore.Server.Kestrel/KestrelServerOptions.cs b/src/Microsoft.AspNetCore.Server.Kestrel/KestrelServerOptions.cs
index ddf85f9a27..708eb240b2 100644
--- a/src/Microsoft.AspNetCore.Server.Kestrel/KestrelServerOptions.cs
+++ b/src/Microsoft.AspNetCore.Server.Kestrel/KestrelServerOptions.cs
@@ -32,6 +32,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel
public bool NoDelay { get; set; } = true;
+ ///
+ /// Gets or sets whether the Server header should be included in each response.
+ ///
+ public bool AddServerHeader { get; set; } = true;
+
///
/// The amount of time after the server begins shutting down before connections will be forcefully closed.
/// By default, Kestrel will wait 5 seconds for any ongoing requests to complete before terminating
diff --git a/test/Microsoft.AspNetCore.Server.KestrelTests/FrameResponseHeadersTests.cs b/test/Microsoft.AspNetCore.Server.KestrelTests/FrameResponseHeadersTests.cs
index 07be384d2c..097d4dac9a 100644
--- a/test/Microsoft.AspNetCore.Server.KestrelTests/FrameResponseHeadersTests.cs
+++ b/test/Microsoft.AspNetCore.Server.KestrelTests/FrameResponseHeadersTests.cs
@@ -15,10 +15,13 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
{
public class FrameResponseHeadersTests
{
- [Fact]
- public void InitialDictionaryContainsServerAndDate()
+ [Theory]
+ [InlineData(true)]
+ [InlineData(false)]
+ public void InitialDictionaryContainsServerAndDate(bool addServerHeader)
{
- var serverOptions = new KestrelServerOptions();
+ var serverOptions = new KestrelServerOptions { AddServerHeader = addServerHeader };
+
var connectionContext = new ConnectionContext
{
DateHeaderValueManager = new DateHeaderValueManager(),
@@ -31,12 +34,22 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
IDictionary headers = frame.ResponseHeaders;
- Assert.Equal(2, headers.Count);
+ if (addServerHeader)
+ {
+ Assert.Equal(2, headers.Count);
- StringValues serverHeader;
- Assert.True(headers.TryGetValue("Server", out serverHeader));
- Assert.Equal(1, serverHeader.Count);
- Assert.Equal("Kestrel", serverHeader[0]);
+ StringValues serverHeader;
+ Assert.True(headers.TryGetValue("Server", out serverHeader));
+ Assert.Equal(1, serverHeader.Count);
+ Assert.Equal("Kestrel", serverHeader[0]);
+ }
+ else
+ {
+ Assert.Equal(1, headers.Count);
+
+ StringValues serverHeader;
+ Assert.False(headers.TryGetValue("Server", out serverHeader));
+ }
StringValues dateHeader;
DateTime date;