@@ -336,21 +336,26 @@ private static (int bytesConsumed, int value) DecodeInteger(ReadOnlySpan<byte> h
336
336
return ( 2 , prefixMask + b ) ;
337
337
}
338
338
339
- private static ( int bytesConsumed , string value ) DecodeString ( ReadOnlySpan < byte > headerBlock )
339
+ private static ( int bytesConsumed , string value , bool huffmanEncoded ) DecodeString ( ReadOnlySpan < byte > headerBlock )
340
340
{
341
341
( int bytesConsumed , int stringLength ) = DecodeInteger ( headerBlock , 0b01111111 ) ;
342
- if ( ( headerBlock [ 0 ] & 0b10000000 ) != 0 )
342
+ bool isHuffmanCoded = ( headerBlock [ 0 ] & 0b10000000 ) != 0 ;
343
+
344
+ headerBlock = headerBlock . Slice ( bytesConsumed , stringLength ) ;
345
+
346
+ if ( isHuffmanCoded )
343
347
{
344
348
// Huffman encoded
345
349
byte [ ] buffer = new byte [ stringLength * 2 ] ;
346
- int bytesDecoded = HuffmanDecoder . Decode ( headerBlock . Slice ( bytesConsumed , stringLength ) , buffer ) ;
350
+ int bytesDecoded = HuffmanDecoder . Decode ( headerBlock , buffer ) ;
347
351
string value = Encoding . ASCII . GetString ( buffer , 0 , bytesDecoded ) ;
348
- return ( bytesConsumed + stringLength , value ) ;
352
+
353
+ return ( bytesConsumed + stringLength , value , true ) ;
349
354
}
350
355
else
351
356
{
352
- string value = Encoding . ASCII . GetString ( headerBlock . Slice ( bytesConsumed , stringLength ) ) ;
353
- return ( bytesConsumed + stringLength , value ) ;
357
+ string value = Encoding . ASCII . GetString ( headerBlock ) ;
358
+ return ( bytesConsumed + stringLength , value , false ) ;
354
359
}
355
360
}
356
361
@@ -432,9 +437,11 @@ private static (int bytesConsumed, HttpHeaderData headerData) DecodeLiteralHeade
432
437
i += bytesConsumed ;
433
438
434
439
string name ;
440
+ bool nameCompressed = false ;
441
+
435
442
if ( index == 0 )
436
443
{
437
- ( bytesConsumed , name ) = DecodeString ( headerBlock . Slice ( i ) ) ;
444
+ ( bytesConsumed , name , nameCompressed ) = DecodeString ( headerBlock . Slice ( i ) ) ;
438
445
i += bytesConsumed ;
439
446
}
440
447
else
@@ -443,18 +450,19 @@ private static (int bytesConsumed, HttpHeaderData headerData) DecodeLiteralHeade
443
450
}
444
451
445
452
string value ;
446
- ( bytesConsumed , value ) = DecodeString ( headerBlock . Slice ( i ) ) ;
453
+ bool valueCompressed ;
454
+ ( bytesConsumed , value , valueCompressed ) = DecodeString ( headerBlock . Slice ( i ) ) ;
447
455
i += bytesConsumed ;
448
456
449
- return ( i , new HttpHeaderData ( name , value ) ) ;
457
+ return ( i , new HttpHeaderData ( name , value , huffmanEncodedName : nameCompressed , huffmanEncodedValue : valueCompressed ) ) ;
450
458
}
451
459
452
460
private static ( int bytesConsumed , HttpHeaderData headerData ) DecodeHeader ( ReadOnlySpan < byte > headerBlock )
453
461
{
454
462
int i = 0 ;
455
463
456
464
byte b = headerBlock [ 0 ] ;
457
- if ( ( b & 0b10000000 ) != 0 )
465
+ if ( ( b & 0b10000000 ) == 0b10000000 )
458
466
{
459
467
// Indexed header
460
468
( int bytesConsumed , int index ) = DecodeInteger ( headerBlock , 0b01111111 ) ;
@@ -474,7 +482,7 @@ private static (int bytesConsumed, HttpHeaderData headerData) DecodeHeader(ReadO
474
482
}
475
483
else
476
484
{
477
- // Literal, never indexed
485
+ // Literal, never indexed OR literal, without indexing.
478
486
return DecodeLiteralHeader ( headerBlock , 0b00001111 ) ;
479
487
}
480
488
}
@@ -537,13 +545,14 @@ public async Task<byte[]> ReadBodyAsync()
537
545
requestData . RequestId = streamId ;
538
546
539
547
Memory < byte > data = headersFrame . Data ;
548
+
540
549
int i = 0 ;
541
550
while ( i < data . Length )
542
551
{
543
552
( int bytesConsumed , HttpHeaderData headerData ) = DecodeHeader ( data . Span . Slice ( i ) ) ;
544
553
545
554
byte [ ] headerRaw = data . Span . Slice ( i , bytesConsumed ) . ToArray ( ) ;
546
- headerData = new HttpHeaderData ( headerData . Name , headerData . Value , headerData . HuffmanEncoded , headerRaw ) ;
555
+ headerData = new HttpHeaderData ( headerData . Name , headerData . Value , headerData . HuffmanEncodedName , headerData . HuffmanEncodedValue , headerRaw ) ;
547
556
548
557
requestData . Headers . Add ( headerData ) ;
549
558
i += bytesConsumed ;
@@ -614,7 +623,19 @@ public async Task SendResponseHeadersAsync(int streamId, bool endStream = true,
614
623
{
615
624
foreach ( HttpHeaderData headerData in headers )
616
625
{
617
- bytesGenerated += HPackEncoder . EncodeHeader ( headerData . Name , headerData . Value , headerData . HuffmanEncoded ? HPackFlags . HuffmanEncode : HPackFlags . None , headerBlock . AsSpan ( bytesGenerated ) ) ;
626
+ HPackFlags hpackFlags = HPackFlags . None ;
627
+
628
+ if ( headerData . HuffmanEncodedName )
629
+ {
630
+ hpackFlags |= HPackFlags . HuffmanEncodeName ;
631
+ }
632
+
633
+ if ( headerData . HuffmanEncodedValue )
634
+ {
635
+ hpackFlags |= HPackFlags . HuffmanEncodeValue ;
636
+ }
637
+
638
+ bytesGenerated += HPackEncoder . EncodeHeader ( headerData . Name , headerData . Value , hpackFlags , headerBlock . AsSpan ( bytesGenerated ) ) ;
618
639
}
619
640
}
620
641
0 commit comments