@@ -12,6 +12,7 @@ use std::fmt;
12
12
use std:: io:: Cursor ;
13
13
14
14
type EncodeBuf < ' a > = bytes:: buf:: Limit < & ' a mut BytesMut > ;
15
+
15
16
/// Header frame
16
17
///
17
18
/// This could be either a request or a response.
@@ -87,6 +88,9 @@ struct HeaderBlock {
87
88
/// The decoded header fields
88
89
fields : HeaderMap ,
89
90
91
+ /// Precomputed size of all of our header fields, for perf reasons
92
+ field_size : usize ,
93
+
90
94
/// Set to true if decoding went over the max header list size.
91
95
is_over_size : bool ,
92
96
@@ -115,6 +119,7 @@ impl Headers {
115
119
stream_id,
116
120
stream_dep : None ,
117
121
header_block : HeaderBlock {
122
+ field_size : calculate_headermap_size ( & fields) ,
118
123
fields,
119
124
is_over_size : false ,
120
125
pseudo,
@@ -131,6 +136,7 @@ impl Headers {
131
136
stream_id,
132
137
stream_dep : None ,
133
138
header_block : HeaderBlock {
139
+ field_size : calculate_headermap_size ( & fields) ,
134
140
fields,
135
141
is_over_size : false ,
136
142
pseudo : Pseudo :: default ( ) ,
@@ -196,6 +202,7 @@ impl Headers {
196
202
stream_dep,
197
203
header_block : HeaderBlock {
198
204
fields : HeaderMap :: new ( ) ,
205
+ field_size : 0 ,
199
206
is_over_size : false ,
200
207
pseudo : Pseudo :: default ( ) ,
201
208
} ,
@@ -350,6 +357,7 @@ impl PushPromise {
350
357
PushPromise {
351
358
flags : PushPromiseFlag :: default ( ) ,
352
359
header_block : HeaderBlock {
360
+ field_size : calculate_headermap_size ( & fields) ,
353
361
fields,
354
362
is_over_size : false ,
355
363
pseudo,
@@ -441,6 +449,7 @@ impl PushPromise {
441
449
flags,
442
450
header_block : HeaderBlock {
443
451
fields : HeaderMap :: new ( ) ,
452
+ field_size : 0 ,
444
453
is_over_size : false ,
445
454
pseudo : Pseudo :: default ( ) ,
446
455
} ,
@@ -892,6 +901,8 @@ impl HeaderBlock {
892
901
893
902
headers_size += decoded_header_size ( name. as_str ( ) . len ( ) , value. len ( ) ) ;
894
903
if headers_size < max_header_list_size {
904
+ self . field_size +=
905
+ decoded_header_size ( name. as_str ( ) . len ( ) , value. len ( ) ) ;
895
906
self . fields . append ( name, value) ;
896
907
} else if !self . is_over_size {
897
908
tracing:: trace!( "load_hpack; header list size over max" ) ;
@@ -958,14 +969,16 @@ impl HeaderBlock {
958
969
+ pseudo_size ! ( status)
959
970
+ pseudo_size ! ( authority)
960
971
+ pseudo_size ! ( path)
961
- + self
962
- . fields
963
- . iter ( )
964
- . map ( |( name, value) | decoded_header_size ( name. as_str ( ) . len ( ) , value. len ( ) ) )
965
- . sum :: < usize > ( )
972
+ + self . field_size
966
973
}
967
974
}
968
975
976
+ fn calculate_headermap_size ( map : & HeaderMap ) -> usize {
977
+ map. iter ( )
978
+ . map ( |( name, value) | decoded_header_size ( name. as_str ( ) . len ( ) , value. len ( ) ) )
979
+ . sum :: < usize > ( )
980
+ }
981
+
969
982
fn decoded_header_size ( name : usize , value : usize ) -> usize {
970
983
name + value + 32
971
984
}
0 commit comments