Reset Frame's IHttpRequestFeature.Headers and IHttpResponseFeature.Headers between requests (#879).

This commit is contained in:
Cesar Blum Silveira 2016-05-26 21:07:42 -07:00
parent 1a6ec294bc
commit 0a181b1f3f
3 changed files with 148 additions and 8 deletions

View File

@ -11,7 +11,6 @@ using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.Kestrel.Infrastructure;
using Microsoft.AspNetCore.Server.Kestrel.Exceptions;
using Microsoft.Extensions.Logging;
@ -217,13 +216,17 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
{
if (FrameRequestHeaders == null)
{
RequestHeaders = FrameRequestHeaders = new FrameRequestHeaders();
FrameRequestHeaders = new FrameRequestHeaders();
}
RequestHeaders = FrameRequestHeaders;
if (FrameResponseHeaders == null)
{
ResponseHeaders = FrameResponseHeaders = new FrameResponseHeaders();
FrameResponseHeaders = new FrameResponseHeaders();
}
ResponseHeaders = FrameResponseHeaders;
}
public void InitializeStreams(MessageBody messageBody)
@ -646,8 +649,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
{
responseHeaders.SetRawServer(Constants.ServerName, _bytesServer);
}
ResponseHeaders = responseHeaders;
}
if (!HasResponseStarted)

View File

@ -11,6 +11,7 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.Kestrel;
using Microsoft.AspNetCore.Server.Kestrel.Http;
using Microsoft.AspNetCore.Server.Kestrel.Infrastructure;
using Xunit;
@ -1057,9 +1058,6 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
[MemberData(nameof(ConnectionFilterData))]
public async Task NoResponseSentWhenConnectionIsClosedByServerBeforeClientFinishesSendingRequest(TestServiceContext testContext)
{
var testLogger = new TestApplicationErrorLogger();
testContext.Log = new KestrelTrace(testLogger);
using (var server = new TestServer(httpContext =>
{
httpContext.Abort();
@ -1077,5 +1075,99 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
}
}
}
[Theory]
[MemberData(nameof(ConnectionFilterData))]
public async Task RequestHeadersAreResetOnEachRequest(TestServiceContext testContext)
{
IHeaderDictionary originalRequestHeaders = null;
var firstRequest = true;
using (var server = new TestServer(httpContext =>
{
var requestFeature = httpContext.Features.Get<IHttpRequestFeature>();
if (firstRequest)
{
originalRequestHeaders = requestFeature.Headers;
requestFeature.Headers = new FrameRequestHeaders();
firstRequest = false;
}
else
{
Assert.Same(originalRequestHeaders, requestFeature.Headers);
}
return TaskUtilities.CompletedTask;
}, testContext))
{
using (var connection = server.CreateConnection())
{
await connection.SendEnd(
"GET / HTTP/1.1",
"",
"GET / HTTP/1.1",
"",
"");
await connection.ReceiveEnd(
"HTTP/1.1 200 OK",
$"Date: {testContext.DateHeaderValue}",
"Content-Length: 0",
"",
"HTTP/1.1 200 OK",
$"Date: {testContext.DateHeaderValue}",
"Content-Length: 0",
"",
"");
}
}
}
[Theory]
[MemberData(nameof(ConnectionFilterData))]
public async Task ResponseHeadersAreResetOnEachRequest(TestServiceContext testContext)
{
IHeaderDictionary originalResponseHeaders = null;
var firstRequest = true;
using (var server = new TestServer(httpContext =>
{
var responseFeature = httpContext.Features.Get<IHttpResponseFeature>();
if (firstRequest)
{
originalResponseHeaders = responseFeature.Headers;
responseFeature.Headers = new FrameResponseHeaders();
firstRequest = false;
}
else
{
Assert.Same(originalResponseHeaders, responseFeature.Headers);
}
return TaskUtilities.CompletedTask;
}, testContext))
{
using (var connection = server.CreateConnection())
{
await connection.SendEnd(
"GET / HTTP/1.1",
"",
"GET / HTTP/1.1",
"",
"");
await connection.ReceiveEnd(
"HTTP/1.1 200 OK",
$"Date: {testContext.DateHeaderValue}",
"Content-Length: 0",
"",
"HTTP/1.1 200 OK",
$"Date: {testContext.DateHeaderValue}",
"Content-Length: 0",
"",
"");
}
}
}
}
}

View File

@ -4,6 +4,7 @@
using System;
using System.Linq;
using System.Text;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.Kestrel;
using Microsoft.AspNetCore.Server.Kestrel.Http;
@ -115,5 +116,51 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
Assert.True(frame.HasResponseStarted);
Assert.Throws<InvalidOperationException>(() => ((IHttpResponseFeature)frame).ReasonPhrase = "Reason phrase");
}
[Fact]
public void InitializeHeadersResetsRequestHeaders()
{
// Arrange
var connectionContext = new ConnectionContext()
{
DateHeaderValueManager = new DateHeaderValueManager(),
ServerAddress = ServerAddress.FromUrl("http://localhost:5000"),
ServerOptions = new KestrelServerOptions(),
SocketOutput = new MockSocketOuptut()
};
var frame = new Frame<object>(application: null, context: connectionContext);
frame.InitializeHeaders();
// Act
var originalRequestHeaders = frame.RequestHeaders;
frame.RequestHeaders = new FrameRequestHeaders();
frame.InitializeHeaders();
// Assert
Assert.Same(originalRequestHeaders, frame.RequestHeaders);
}
[Fact]
public void InitializeHeadersResetsResponseHeaders()
{
// Arrange
var connectionContext = new ConnectionContext()
{
DateHeaderValueManager = new DateHeaderValueManager(),
ServerAddress = ServerAddress.FromUrl("http://localhost:5000"),
ServerOptions = new KestrelServerOptions(),
SocketOutput = new MockSocketOuptut()
};
var frame = new Frame<object>(application: null, context: connectionContext);
frame.InitializeHeaders();
// Act
var originalResponseHeaders = frame.ResponseHeaders;
frame.ResponseHeaders = new FrameResponseHeaders();
frame.InitializeHeaders();
// Assert
Assert.Same(originalResponseHeaders, frame.ResponseHeaders);
}
}
}