3
3
// See the LICENSE file in the project root for more information.
4
4
5
5
#nullable enable
6
- using System . Collections . Generic ;
7
6
using System . Diagnostics ;
8
7
9
8
namespace System . Net . Http . HPack
@@ -41,6 +40,8 @@ public void UpdateMaxHeaderTableSize(uint maxHeaderTableSize)
41
40
if ( _maxHeaderTableSize != maxHeaderTableSize )
42
41
{
43
42
_maxHeaderTableSize = maxHeaderTableSize ;
43
+
44
+ // Dynamic table size update will be written next HEADERS frame
44
45
_pendingTableSizeUpdate = true ;
45
46
46
47
// Check capacity and remove entries that exceed the new capacity
@@ -50,6 +51,7 @@ public void UpdateMaxHeaderTableSize(uint maxHeaderTableSize)
50
51
51
52
public bool EnsureDynamicTableSizeUpdate ( Span < byte > buffer , out int length )
52
53
{
54
+ // Check if there is a table size update that should be encoded
53
55
if ( _pendingTableSizeUpdate )
54
56
{
55
57
bool success = EncodeDynamicTableSizeUpdate ( ( int ) _maxHeaderTableSize , buffer , out length ) ;
@@ -68,7 +70,7 @@ public bool EncodeHeader(Span<byte> buffer, int staticTableIndex, HeaderEncoding
68
70
// Never index sensitive value.
69
71
if ( encodingHint == HeaderEncodingHint . NeverIndex )
70
72
{
71
- var index = ResolveDynamicTableIndex ( staticTableIndex , name ) ;
73
+ int index = ResolveDynamicTableIndex ( staticTableIndex , name ) ;
72
74
73
75
return index == - 1
74
76
? EncodeLiteralHeaderFieldNeverIndexingNewName ( name , value , buffer , out bytesWritten )
@@ -87,7 +89,7 @@ public bool EncodeHeader(Span<byte> buffer, int staticTableIndex, HeaderEncoding
87
89
// Don't attempt to add dynamic header as all existing dynamic headers will be removed.
88
90
if ( HeaderField . GetLength ( name . Length , value . Length ) > _maxHeaderTableSize )
89
91
{
90
- var index = ResolveDynamicTableIndex ( staticTableIndex , name ) ;
92
+ int index = ResolveDynamicTableIndex ( staticTableIndex , name ) ;
91
93
92
94
return index == - 1
93
95
? EncodeLiteralHeaderFieldWithoutIndexingNewName ( name , value , buffer , out bytesWritten )
@@ -110,20 +112,20 @@ private int ResolveDynamicTableIndex(int staticTableIndex, string name)
110
112
111
113
private bool EncodeDynamicHeader ( Span < byte > buffer , int staticTableIndex , string name , string value , out int bytesWritten )
112
114
{
113
- var headerField = GetEntry ( name , value ) ;
115
+ EncoderHeaderEntry ? headerField = GetEntry ( name , value ) ;
114
116
if ( headerField != null )
115
117
{
116
118
// Already exists in dynamic table. Write index.
117
- var index = CalculateDynamicTableIndex ( headerField . Index ) ;
119
+ int index = CalculateDynamicTableIndex ( headerField . Index ) ;
118
120
return EncodeIndexedHeaderField ( index , buffer , out bytesWritten ) ;
119
121
}
120
122
else
121
123
{
122
124
// Doesn't exist in dynamic table. Add new entry to dynamic table.
123
- var headerSize = ( uint ) HeaderField . GetLength ( name . Length , value . Length ) ;
125
+ uint headerSize = ( uint ) HeaderField . GetLength ( name . Length , value . Length ) ;
124
126
125
- var index = ResolveDynamicTableIndex ( staticTableIndex , name ) ;
126
- var success = index == - 1
127
+ int index = ResolveDynamicTableIndex ( staticTableIndex , name ) ;
128
+ bool success = index == - 1
127
129
? EncodeLiteralHeaderFieldIndexingNewName ( name , value , buffer , out bytesWritten )
128
130
: EncodeLiteralHeaderFieldIndexing ( index , value , buffer , out bytesWritten ) ;
129
131
@@ -147,7 +149,7 @@ private void EnsureCapacity(uint headerSize)
147
149
148
150
while ( _maxHeaderTableSize - _headerTableSize < headerSize )
149
151
{
150
- var removed = RemoveHeaderEntry ( ) ;
152
+ EncoderHeaderEntry ? removed = RemoveHeaderEntry ( ) ;
151
153
Debug . Assert ( removed != null ) ;
152
154
153
155
// Removed entries are tracked to be reused.
@@ -161,9 +163,9 @@ private void EnsureCapacity(uint headerSize)
161
163
{
162
164
return null ;
163
165
}
164
- var hash = name . GetHashCode ( ) ;
165
- var bucketIndex = CalculateBucketIndex ( hash ) ;
166
- for ( var e = _headerBuckets [ bucketIndex ] ; e != null ; e = e . Next )
166
+ int hash = name . GetHashCode ( ) ;
167
+ int bucketIndex = CalculateBucketIndex ( hash ) ;
168
+ for ( EncoderHeaderEntry ? e = _headerBuckets [ bucketIndex ] ; e != null ; e = e . Next )
167
169
{
168
170
// We've already looked up entries based on a hash of the name.
169
171
// Compare value before name as it is more likely to be different.
@@ -183,9 +185,9 @@ private int CalculateDynamicTableIndex(string name)
183
185
{
184
186
return - 1 ;
185
187
}
186
- var hash = name . GetHashCode ( ) ;
187
- var bucketIndex = CalculateBucketIndex ( hash ) ;
188
- for ( var e = _headerBuckets [ bucketIndex ] ; e != null ; e = e . Next )
188
+ int hash = name . GetHashCode ( ) ;
189
+ int bucketIndex = CalculateBucketIndex ( hash ) ;
190
+ for ( EncoderHeaderEntry ? e = _headerBuckets [ bucketIndex ] ; e != null ; e = e . Next )
189
191
{
190
192
if ( e . Hash == hash && string . Equals ( name , e . Name , StringComparison . Ordinal ) )
191
193
{
@@ -205,11 +207,11 @@ private void AddHeaderEntry(string name, string value, uint headerSize)
205
207
Debug . Assert ( headerSize <= _maxHeaderTableSize , "Header is bigger than dynamic table size." ) ;
206
208
Debug . Assert ( headerSize <= _maxHeaderTableSize - _headerTableSize , "Not enough room in dynamic table." ) ;
207
209
208
- var hash = name . GetHashCode ( ) ;
209
- var bucketIndex = CalculateBucketIndex ( hash ) ;
210
- var oldEntry = _headerBuckets [ bucketIndex ] ;
210
+ int hash = name . GetHashCode ( ) ;
211
+ int bucketIndex = CalculateBucketIndex ( hash ) ;
212
+ EncoderHeaderEntry ? oldEntry = _headerBuckets [ bucketIndex ] ;
211
213
// Attempt to reuse removed entry
212
- var newEntry = PopRemovedEntry ( ) ?? new EncoderHeaderEntry ( ) ;
214
+ EncoderHeaderEntry ? newEntry = PopRemovedEntry ( ) ?? new EncoderHeaderEntry ( ) ;
213
215
newEntry . Initialize ( hash , name , value , Head . Before . Index - 1 , oldEntry ) ;
214
216
_headerBuckets [ bucketIndex ] = newEntry ;
215
217
newEntry . AddBefore ( Head ) ;
@@ -229,7 +231,7 @@ private void PushRemovedEntry(EncoderHeaderEntry removed)
229
231
{
230
232
if ( _removed != null )
231
233
{
232
- var removed = _removed ;
234
+ EncoderHeaderEntry ? removed = _removed ;
233
235
_removed = _removed . Next ;
234
236
return removed ;
235
237
}
@@ -246,11 +248,11 @@ private void PushRemovedEntry(EncoderHeaderEntry removed)
246
248
{
247
249
return null ;
248
250
}
249
- var eldest = Head . After ;
250
- var hash = eldest . Hash ;
251
- var bucketIndex = CalculateBucketIndex ( hash ) ;
252
- var prev = _headerBuckets [ bucketIndex ] ;
253
- var e = prev ;
251
+ EncoderHeaderEntry ? eldest = Head . After ;
252
+ int hash = eldest . Hash ;
253
+ int bucketIndex = CalculateBucketIndex ( hash ) ;
254
+ EncoderHeaderEntry ? prev = _headerBuckets [ bucketIndex ] ;
255
+ EncoderHeaderEntry ? e = prev ;
254
256
while ( e != null )
255
257
{
256
258
EncoderHeaderEntry next = e . Next ;
@@ -280,6 +282,10 @@ private int CalculateBucketIndex(int hash)
280
282
}
281
283
}
282
284
285
+ /// <summary>
286
+ /// Hint for how the header should be encoded as HPack. This value can be overriden.
287
+ /// For example, a header that is larger than the dynamic table won't be indexed.
288
+ /// </summary>
283
289
internal enum HeaderEncodingHint
284
290
{
285
291
Index ,
0 commit comments