Skip to content

Commit 0ec739d

Browse files
committed
Remove min buffer size
1 parent 08f94ac commit 0ec739d

File tree

3 files changed

+187
-109
lines changed

3 files changed

+187
-109
lines changed

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ public class Http1OutputProducer : IHttpOutputProducer, IHttpOutputAborter, IDis
4343
private long _unflushedBytes;
4444
private bool _autoChunk;
4545
private readonly PipeWriter _pipeWriter;
46-
private const int MemorySizeThreshold = 1024;
4746
private const int BeginChunkLengthMax = 5;
4847
private const int EndChunkLength = 2;
4948

@@ -606,7 +605,7 @@ private void EnsureCapacity(int sizeHint)
606605

607606
// If the sizeHint is 0, any capacity will do
608607
// Otherwise, the buffer must have enough space for the entire size hint, or we need to add a segment.
609-
if ((sizeHint == 0 && remainingSize > 0) || (sizeHint > 0 && remainingSize >= Math.Min(MemorySizeThreshold, sizeHint)))
608+
if ((sizeHint == 0 && remainingSize > 0) || (sizeHint > 0 && remainingSize >= sizeHint))
610609
{
611610
// We have capacity in the current segment
612611
return;

src/Servers/Kestrel/test/InMemory.FunctionalTests/ChunkedResponseTests.cs

Lines changed: 158 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -421,23 +421,62 @@ await connection.Receive(
421421
}
422422
}
423423

424-
[Theory]
425-
[InlineData(false)]
426-
[InlineData(true)]
427-
public async Task ChunksWithGetMemoryBeforeFirstFlushStillFlushes(bool start)
424+
[Fact]
425+
public async Task ChunksWithGetMemoryAfterStartAsyncBeforeFirstFlushStillFlushes()
428426
{
429427
var testContext = new TestServiceContext(LoggerFactory);
430428

431429
using (var server = new TestServer(async httpContext =>
432430
{
433431
var response = httpContext.Response;
434432

435-
if (start)
433+
await response.StartAsync();
434+
var memory = response.BodyWriter.GetMemory();
435+
var fisrtPartOfResponse = Encoding.ASCII.GetBytes("Hello ");
436+
fisrtPartOfResponse.CopyTo(memory);
437+
response.BodyWriter.Advance(6);
438+
439+
memory = response.BodyWriter.GetMemory();
440+
var secondPartOfResponse = Encoding.ASCII.GetBytes("World!");
441+
secondPartOfResponse.CopyTo(memory);
442+
response.BodyWriter.Advance(6);
443+
444+
await response.BodyWriter.FlushAsync();
445+
}, testContext))
446+
{
447+
using (var connection = server.CreateConnection())
436448
{
437-
await response.StartAsync();
449+
await connection.Send(
450+
"GET / HTTP/1.1",
451+
"Host: ",
452+
"",
453+
"");
454+
await connection.Receive(
455+
"HTTP/1.1 200 OK",
456+
$"Date: {testContext.DateHeaderValue}",
457+
"Transfer-Encoding: chunked",
458+
"",
459+
"c",
460+
"Hello World!",
461+
"0",
462+
"",
463+
"");
438464
}
439-
var memory = response.BodyWriter.GetMemory();
440465

466+
await server.StopAsync();
467+
}
468+
}
469+
470+
[Fact]
471+
public async Task ChunksWithGetMemoryBeforeFirstFlushStillFlushes()
472+
{
473+
var testContext = new TestServiceContext(LoggerFactory);
474+
475+
using (var server = new TestServer(async httpContext =>
476+
{
477+
var response = httpContext.Response;
478+
479+
var memory = response.BodyWriter.GetMemory();
441480
var fisrtPartOfResponse = Encoding.ASCII.GetBytes("Hello ");
442481
fisrtPartOfResponse.CopyTo(memory);
443482
response.BodyWriter.Advance(6);
@@ -473,10 +512,8 @@ await connection.Receive(
473512
}
474513
}
475514

476-
[Theory]
477-
[InlineData(false)]
478-
[InlineData(true)]
479-
public async Task ChunksWithGetMemoryLargeWriteBeforeFirstFlush(bool start)
515+
[Fact]
516+
public async Task ChunksWithGetMemoryLargeWriteBeforeFirstFlush()
480517
{
481518
var length = new IntAsRef();
482519
var semaphore = new SemaphoreSlim(initialCount: 0);
@@ -485,10 +522,6 @@ public async Task ChunksWithGetMemoryLargeWriteBeforeFirstFlush(bool start)
485522
using (var server = new TestServer(async httpContext =>
486523
{
487524
var response = httpContext.Response;
488-
if (start)
489-
{
490-
await response.StartAsync();
491-
}
492525

493526
var memory = response.BodyWriter.GetMemory();
494527
length.Value = memory.Length;
@@ -535,10 +568,8 @@ await connection.Receive(
535568
}
536569
}
537570

538-
[Theory]
539-
[InlineData(false)]
540-
[InlineData(true)]
541-
public async Task ChunksWithGetMemoryWithInitialFlushWorks(bool start)
571+
[Fact]
572+
public async Task ChunksWithGetMemoryAndStartAsyncWithInitialFlushWorks()
542573
{
543574
var length = new IntAsRef();
544575
var semaphore = new SemaphoreSlim(initialCount: 0);
@@ -548,10 +579,7 @@ public async Task ChunksWithGetMemoryWithInitialFlushWorks(bool start)
548579
{
549580
var response = httpContext.Response;
550581

551-
if (start)
552-
{
553-
await response.StartAsync();
554-
}
582+
await response.StartAsync();
555583

556584
await response.BodyWriter.FlushAsync();
557585

@@ -600,22 +628,76 @@ await connection.Receive(
600628
}
601629
}
602630

603-
[Theory]
604-
[InlineData(false)]
605-
[InlineData(true)]
606-
public async Task ChunkGetMemoryMultipleAdvance(bool start)
631+
[Fact]
632+
public async Task ChunksWithGetMemoryBeforeFlushEdgeCase()
607633
{
634+
var length = new IntAsRef();
635+
var semaphore = new SemaphoreSlim(initialCount: 0);
608636
var testContext = new TestServiceContext(LoggerFactory);
609637

610638
using (var server = new TestServer(async httpContext =>
611639
{
612640
var response = httpContext.Response;
613641

614-
if (start)
642+
await response.StartAsync();
643+
644+
var memory = response.BodyWriter.GetMemory();
645+
length.Value = memory.Length - 1;
646+
semaphore.Release();
647+
648+
var fisrtPartOfResponse = Encoding.ASCII.GetBytes(new string('a', length.Value));
649+
fisrtPartOfResponse.CopyTo(memory);
650+
response.BodyWriter.Advance(length.Value);
651+
652+
var secondMemory = response.BodyWriter.GetMemory(6);
653+
654+
var secondPartOfResponse = Encoding.ASCII.GetBytes("World!");
655+
secondPartOfResponse.CopyTo(secondMemory);
656+
response.BodyWriter.Advance(6);
657+
658+
await response.BodyWriter.FlushAsync();
659+
}, testContext))
660+
{
661+
using (var connection = server.CreateConnection())
615662
{
616-
await response.StartAsync();
663+
await connection.Send(
664+
"GET / HTTP/1.1",
665+
"Host: ",
666+
"",
667+
"");
668+
669+
// Wait for length to be set
670+
await semaphore.WaitAsync();
671+
672+
await connection.Receive(
673+
"HTTP/1.1 200 OK",
674+
$"Date: {testContext.DateHeaderValue}",
675+
"Transfer-Encoding: chunked",
676+
"",
677+
length.Value.ToString("x"),
678+
new string('a', length.Value),
679+
"6",
680+
"World!",
681+
"0",
682+
"",
683+
"");
617684
}
618685

686+
await server.StopAsync();
687+
}
688+
}
689+
690+
[Fact]
691+
public async Task ChunkGetMemoryMultipleAdvance()
692+
{
693+
var testContext = new TestServiceContext(LoggerFactory);
694+
695+
using (var server = new TestServer(async httpContext =>
696+
{
697+
var response = httpContext.Response;
698+
699+
await response.StartAsync();
700+
619701
var memory = response.BodyWriter.GetMemory(4096);
620702
var fisrtPartOfResponse = Encoding.ASCII.GetBytes("Hello ");
621703
fisrtPartOfResponse.CopyTo(memory);
@@ -649,20 +731,16 @@ await connection.Receive(
649731
}
650732
}
651733

652-
[Theory]
653-
[InlineData(false)]
654-
[InlineData(true)]
655-
public async Task ChunkGetSpanMultipleAdvance(bool start)
734+
[Fact]
735+
public async Task ChunkGetSpanMultipleAdvance()
656736
{
657737
var testContext = new TestServiceContext(LoggerFactory);
658738

659739
using (var server = new TestServer(async httpContext =>
660740
{
661741
var response = httpContext.Response;
662-
if (start)
663-
{
664-
await response.StartAsync();
665-
}
742+
await response.StartAsync();
743+
666744
// To avoid using span in an async method
667745
void NonAsyncMethod()
668746
{
@@ -866,27 +944,22 @@ await connection.Receive(
866944
}
867945

868946
[Theory]
869-
[InlineData(15, false)]
870-
[InlineData(255, false)]
871-
[InlineData(15, true)]
872-
[InlineData(255, true)]
873-
public async Task ChunkGetMemoryWithSmallerSizesWork(int writeSize, bool start)
947+
[InlineData(15)]
948+
[InlineData(255)]
949+
public async Task ChunkGetMemoryWithoutStartWithSmallerSizesWork(int writeSize)
874950
{
875951
var testContext = new TestServiceContext(LoggerFactory);
876952

877953
using (var server = new TestServer(async httpContext =>
878954
{
879955
var response = httpContext.Response;
880956

881-
if (start)
882-
{
883-
await response.StartAsync();
884-
}
885957

886958
var memory = response.BodyWriter.GetMemory(4096);
887959
var fisrtPartOfResponse = Encoding.ASCII.GetBytes(new string('a', writeSize));
888960
fisrtPartOfResponse.CopyTo(memory);
889961
response.BodyWriter.Advance(writeSize);
962+
await response.BodyWriter.FlushAsync();
890963
}, testContext))
891964
{
892965
using (var connection = server.CreateConnection())
@@ -913,21 +986,54 @@ await connection.Receive(
913986
}
914987

915988
[Theory]
916-
[InlineData(false)]
917-
[InlineData(true)]
918-
public async Task ChunkedWithBothPipeAndStreamWorks(bool start)
989+
[InlineData(15)]
990+
[InlineData(255)]
991+
public async Task ChunkGetMemoryWithStartWithSmallerSizesWork(int writeSize)
919992
{
993+
var testContext = new TestServiceContext(LoggerFactory);
994+
920995
using (var server = new TestServer(async httpContext =>
921996
{
922997
var response = httpContext.Response;
923998

924-
if (start)
999+
var memory = response.BodyWriter.GetMemory(4096);
1000+
var fisrtPartOfResponse = Encoding.ASCII.GetBytes(new string('a', writeSize));
1001+
fisrtPartOfResponse.CopyTo(memory);
1002+
response.BodyWriter.Advance(writeSize);
1003+
await response.BodyWriter.FlushAsync();
1004+
}, testContext))
1005+
{
1006+
using (var connection = server.CreateConnection())
9251007
{
926-
await response.StartAsync();
1008+
await connection.Send(
1009+
"GET / HTTP/1.1",
1010+
"Host: ",
1011+
"",
1012+
"");
1013+
await connection.Receive(
1014+
"HTTP/1.1 200 OK",
1015+
$"Date: {testContext.DateHeaderValue}",
1016+
"Transfer-Encoding: chunked",
1017+
"",
1018+
writeSize.ToString("X").ToLower(),
1019+
new string('a', writeSize),
1020+
"0",
1021+
"",
1022+
"");
9271023
}
9281024

929-
var memory = response.BodyWriter.GetMemory(4096);
1025+
await server.StopAsync();
1026+
}
1027+
}
9301028

1029+
[Fact]
1030+
public async Task ChunkedWithBothPipeAndStreamWorks()
1031+
{
1032+
using (var server = new TestServer(async httpContext =>
1033+
{
1034+
var response = httpContext.Response;
1035+
1036+
var memory = response.BodyWriter.GetMemory(4096);
9311037
var fisrtPartOfResponse = Encoding.ASCII.GetBytes("hello,");
9321038
fisrtPartOfResponse.CopyTo(memory);
9331039
response.BodyWriter.Advance(6);

0 commit comments

Comments
 (0)