8
8
using Microsoft . AspNetCore . Http ;
9
9
using Microsoft . AspNetCore . Server . Kestrel . Internal . Infrastructure ;
10
10
using Microsoft . Extensions . Internal ;
11
- using Microsoft . Extensions . Primitives ;
12
11
13
12
namespace Microsoft . AspNetCore . Server . Kestrel . Internal . Http
14
13
{
15
14
public abstract class MessageBody
16
15
{
16
+ private static readonly MessageBody _zeroContentLengthClose = new ForZeroContentLength ( keepAlive : false ) ;
17
+ private static readonly MessageBody _zeroContentLengthKeepAlive = new ForZeroContentLength ( keepAlive : true ) ;
18
+
17
19
private readonly Frame _context ;
18
20
private bool _send100Continue = true ;
19
21
@@ -268,7 +270,13 @@ public static MessageBody For(
268
270
269
271
if ( headers . ContentLength . HasValue )
270
272
{
271
- return new ForContentLength ( keepAlive , headers . ContentLength . Value , context ) ;
273
+ var contentLength = headers . ContentLength . Value ;
274
+ if ( contentLength == 0 )
275
+ {
276
+ return keepAlive ? _zeroContentLengthKeepAlive : _zeroContentLengthClose ;
277
+ }
278
+
279
+ return new ForContentLength ( keepAlive , contentLength , context ) ;
272
280
}
273
281
274
282
// Avoid slowing down most common case
@@ -283,7 +291,7 @@ public static MessageBody For(
283
291
}
284
292
}
285
293
286
- return new ForContentLength ( keepAlive , 0 , context ) ;
294
+ return keepAlive ? _zeroContentLengthKeepAlive : _zeroContentLengthClose ;
287
295
}
288
296
289
297
private class ForRemainingData : MessageBody
@@ -300,6 +308,28 @@ protected override ValueTask<ArraySegment<byte>> PeekAsync(CancellationToken can
300
308
}
301
309
}
302
310
311
+ private class ForZeroContentLength : MessageBody
312
+ {
313
+ public ForZeroContentLength ( bool keepAlive )
314
+ : base ( null )
315
+ {
316
+ RequestKeepAlive = keepAlive ;
317
+ }
318
+
319
+ protected override ValueTask < ArraySegment < byte > > PeekAsync ( CancellationToken cancellationToken )
320
+ {
321
+ return new ValueTask < ArraySegment < byte > > ( ) ;
322
+ }
323
+
324
+ protected override void OnConsumedBytes ( int count )
325
+ {
326
+ if ( count > 0 )
327
+ {
328
+ throw new InvalidDataException ( "Consuming non-existant data" ) ;
329
+ }
330
+ }
331
+ }
332
+
303
333
private class ForContentLength : MessageBody
304
334
{
305
335
private readonly long _contentLength ;
0 commit comments