Skip to content

Commit bac6e02

Browse files
committed
Reuse Http2MessageBody
1 parent 58c13c3 commit bac6e02

File tree

9 files changed

+54
-18
lines changed

9 files changed

+54
-18
lines changed

src/Servers/Kestrel/Core/src/Internal/Http/Http1MessageBody.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ internal abstract class Http1MessageBody : MessageBody
1717
protected bool _completed;
1818

1919
protected Http1MessageBody(Http1Connection context)
20-
: base(context)
2120
{
21+
Reset(context);
2222
_context = context;
2323
}
2424

src/Servers/Kestrel/Core/src/Internal/Http/MessageBody.cs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ internal abstract class MessageBody
1515
private static readonly MessageBody _zeroContentLengthClose = new ZeroContentLengthMessageBody(keepAlive: false);
1616
private static readonly MessageBody _zeroContentLengthKeepAlive = new ZeroContentLengthMessageBody(keepAlive: true);
1717

18-
private readonly HttpProtocol _context;
18+
private HttpProtocol _context;
1919

2020
private bool _send100Continue = true;
2121
private long _consumedBytes;
@@ -26,11 +26,6 @@ internal abstract class MessageBody
2626
protected long _alreadyTimedBytes;
2727
protected long _examinedUnconsumedBytes;
2828

29-
protected MessageBody(HttpProtocol context)
30-
{
31-
_context = context;
32-
}
33-
3429
public static MessageBody ZeroContentLengthClose => _zeroContentLengthClose;
3530

3631
public static MessageBody ZeroContentLengthKeepAlive => _zeroContentLengthKeepAlive;
@@ -73,6 +68,18 @@ public virtual Task StopAsync()
7368

7469
protected virtual Task OnStopAsync() => Task.CompletedTask;
7570

71+
protected void Reset(HttpProtocol context)
72+
{
73+
_context = context;
74+
_send100Continue = true;
75+
_consumedBytes = 0;
76+
_stopped = false;
77+
_timingEnabled = false;
78+
_backpressure = false;
79+
_alreadyTimedBytes = 0;
80+
_examinedUnconsumedBytes = 0;
81+
}
82+
7683
protected void TryProduceContinue()
7784
{
7885
if (_send100Continue)

src/Servers/Kestrel/Core/src/Internal/Http/ZeroContentLengthMessageBody.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
1111
internal sealed class ZeroContentLengthMessageBody : MessageBody
1212
{
1313
public ZeroContentLengthMessageBody(bool keepAlive)
14-
: base(null)
1514
{
15+
Reset(null);
1616
RequestKeepAlive = keepAlive;
1717
}
1818

src/Servers/Kestrel/Core/src/Internal/Http2/Http2MessageBody.cs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
1212
{
1313
internal sealed class Http2MessageBody : MessageBody
1414
{
15-
private readonly Http2Stream _context;
15+
private Http2Stream _context;
1616
private ReadResult _readResult;
1717

18-
private Http2MessageBody(Http2Stream context)
19-
: base(context)
18+
public Http2MessageBody(Http2Stream context)
2019
{
21-
_context = context;
20+
Reset(context);
2221
}
2322

2423
protected override void OnReadStarting()
@@ -46,16 +45,29 @@ protected override void OnDataRead(long bytesRead)
4645
AddAndCheckConsumedBytes(bytesRead);
4746
}
4847

49-
public static MessageBody For(Http2Stream context)
48+
public static MessageBody For(Http2Stream context, Http2MessageBody previousMessageBody)
5049
{
5150
if (context.ReceivedEmptyRequestBody)
5251
{
5352
return ZeroContentLengthClose;
5453
}
5554

55+
if (previousMessageBody is Http2MessageBody http2MessageBody)
56+
{
57+
http2MessageBody.Reset(context);
58+
return http2MessageBody;
59+
}
60+
5661
return new Http2MessageBody(context);
5762
}
5863

64+
public void Reset(Http2Stream context)
65+
{
66+
base.Reset(context);
67+
_context = context;
68+
_readResult = default;
69+
}
70+
5971
public override void AdvanceTo(SequencePosition consumed)
6072
{
6173
AdvanceTo(consumed, consumed);

src/Servers/Kestrel/Core/src/Internal/Http2/Http2Stream.cs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ internal abstract partial class Http2Stream : HttpProtocol, IThreadPoolWorkItem
2323
private Http2OutputProducer _http2Output;
2424
private StreamInputFlowControl _inputFlowControl;
2525
private StreamOutputFlowControl _outputFlowControl;
26+
private Http2MessageBody _messageBody;
2627

2728
private bool _decrementCalled;
2829

@@ -170,7 +171,23 @@ protected override string CreateRequestId()
170171
=> StringUtilities.ConcatAsHexSuffix(ConnectionId, ':', (uint)StreamId);
171172

172173
protected override MessageBody CreateMessageBody()
173-
=> Http2MessageBody.For(this);
174+
{
175+
if (ReceivedEmptyRequestBody)
176+
{
177+
return MessageBody.ZeroContentLengthClose;
178+
}
179+
180+
if (_messageBody != null)
181+
{
182+
_messageBody.Reset(this);
183+
}
184+
else
185+
{
186+
_messageBody = new Http2MessageBody(this);
187+
}
188+
189+
return _messageBody;
190+
}
174191

175192
// Compare to Http1Connection.OnStartLine
176193
protected override bool TryParseRequest(ReadResult result, out bool endConnection)

src/Servers/Kestrel/Core/src/Internal/Http3/Http3MessageBody.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ internal sealed class Http3MessageBody : MessageBody
1616
private ReadResult _readResult;
1717

1818
private Http3MessageBody(Http3Stream context)
19-
: base(context)
2019
{
20+
Reset(context);
2121
_context = context;
2222
}
2323
protected override void OnReadStarting()

src/Servers/Kestrel/Core/test/BodyControlTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,8 @@ public async Task ResponsePipeThrowsObjectDisposedExceptionAfterStop()
141141
private class MockMessageBody : MessageBody
142142
{
143143
public MockMessageBody(bool upgradeable = false)
144-
: base(null)
145144
{
145+
Reset(null);
146146
RequestUpgrade = upgradeable;
147147
}
148148

src/Servers/Kestrel/Core/test/Http1ConnectionTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -886,7 +886,7 @@ public async Task ConsumesRequestWhenApplicationDoesNotConsumeIt()
886886
var buffer = new byte[10];
887887
await context.Response.Body.WriteAsync(buffer, 0, 10);
888888
});
889-
var mockMessageBody = new Mock<MessageBody>(null);
889+
var mockMessageBody = new Mock<MessageBody>();
890890
_http1Connection.NextMessageBody = mockMessageBody.Object;
891891

892892
var requestProcessingTask = _http1Connection.ProcessRequestsAsync(httpApplication);

src/Servers/Kestrel/Core/test/HttpRequestStreamTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ public async Task SynchronousReadsThrowIfDisallowedByIHttpBodyControlFeature()
108108

109109
var mockBodyControl = new Mock<IHttpBodyControlFeature>();
110110
mockBodyControl.Setup(m => m.AllowSynchronousIO).Returns(() => allowSynchronousIO);
111-
var mockMessageBody = new Mock<MessageBody>(null);
111+
var mockMessageBody = new Mock<MessageBody>();
112112
mockMessageBody.Setup(m => m.ReadAsync(CancellationToken.None)).Returns(new ValueTask<ReadResult>(new ReadResult(default, isCanceled: false, isCompleted: true)));
113113

114114
var pipeReader = new HttpRequestPipeReader();

0 commit comments

Comments
 (0)