8
8
Implements the version dated January 9, 2014.
9
9
"""
10
10
import collections
11
+ import logging
11
12
12
13
from .huffman import HuffmanDecoder , HuffmanEncoder
13
14
from hyper .http20 .huffman_constants import (
14
15
REQUEST_CODES , REQUEST_CODES_LENGTH , RESPONSE_CODES , RESPONSE_CODES_LENGTH
15
16
)
16
17
18
+ log = logging .getLogger (__name__ )
19
+
17
20
18
21
def encode_integer (integer , prefix_bits ):
19
22
"""
20
23
This encodes an integer according to the wacky integer encoding rules
21
24
defined in the HPACK spec.
22
25
"""
26
+ log .debug ("Encoding %d with %d bits." , integer , prefix_bits )
27
+
23
28
max_number = (2 ** prefix_bits ) - 1
24
29
25
30
if (integer < max_number ):
@@ -63,6 +68,8 @@ def decode_integer(data, prefix_bits):
63
68
number += next_byte * multiple (index )
64
69
break
65
70
71
+ log .debug ("Decoded %d consuming %d bytes." , number , index + 1 )
72
+
66
73
return (number , index + 1 )
67
74
68
75
@@ -163,6 +170,12 @@ def header_table_size(self):
163
170
164
171
@header_table_size .setter
165
172
def header_table_size (self , value ):
173
+ log .debug (
174
+ "Setting header table size to %d from %d" ,
175
+ value ,
176
+ self ._header_table_size
177
+ )
178
+
166
179
# If the new value is larger than the current one, no worries!
167
180
# Otherwise, we may need to shrink the header table.
168
181
if value < self ._header_table_size :
@@ -178,6 +191,10 @@ def header_table_size(self, value):
178
191
# to be removed from the reference set.
179
192
self .reference_set .discard ((n , v ))
180
193
194
+ log .debug (
195
+ "Removed %s: %s from the encoder header table" , n , v
196
+ )
197
+
181
198
self ._header_table_size = value
182
199
183
200
def encode (self , headers , huffman = True ):
@@ -202,6 +219,8 @@ def encode(self, headers, huffman=True):
202
219
Literal text values may optionally be Huffman encoded. For now we don't
203
220
do that, because it's an extra bit of complication, but we will later.
204
221
"""
222
+ log .debug ("HPACK encoding %s" , headers )
223
+
205
224
# First, turn the headers into a list of tuples if possible. This is
206
225
# the natural way to interact with them in HPACK.
207
226
if isinstance (headers , dict ):
@@ -225,6 +244,7 @@ def encode(self, headers, huffman=True):
225
244
# reference set, just emit an 'empty the reference set' message.
226
245
if (len (self .reference_set - incoming_set ) >
227
246
(len (self .reference_set ) // 2 )):
247
+ log .debug ("Emptying the encoder reference set." )
228
248
header_block = b'\x80 ' # Indexed representation of 0.
229
249
230
250
# Remove everything from the reference set.
@@ -234,6 +254,8 @@ def encode(self, headers, huffman=True):
234
254
235
255
header_block += self .add (to_add , huffman )
236
256
257
+ log .debug ("Encoded header block to %s" , header_block )
258
+
237
259
return header_block
238
260
239
261
def remove (self , to_remove ):
@@ -242,6 +264,8 @@ def remove(self, to_remove):
242
264
them. These must be in the header table, so must be represented as
243
265
their indexed form.
244
266
"""
267
+ log .debug ("Removing %s from the header table" , to_remove )
268
+
245
269
encoded = []
246
270
247
271
for name , value in to_remove :
@@ -274,6 +298,8 @@ def add(self, to_add, huffman=False):
274
298
This function takes a set of header key-value tuples and serializes
275
299
them for adding to the header table.
276
300
"""
301
+ log .debug ("Adding %s to the header table" , to_add )
302
+
277
303
encoded = []
278
304
279
305
for name , value in to_add :
@@ -360,6 +386,8 @@ def _add_to_header_table(self, name, value):
360
386
# be removed from the reference set.
361
387
self .reference_set .discard ((n , v ))
362
388
389
+ log .debug ("Evicted %s: %s from the header table" , n , v )
390
+
363
391
def _encode_indexed (self , index ):
364
392
"""
365
393
Encodes a header using the indexed representation.
@@ -493,6 +521,12 @@ def header_table_size(self):
493
521
494
522
@header_table_size .setter
495
523
def header_table_size (self , value ):
524
+ log .debug (
525
+ "Resizing decoder header table to %d from %d" ,
526
+ value ,
527
+ self ._header_table_size
528
+ )
529
+
496
530
# If the new value is larger than the current one, no worries!
497
531
# Otherwise, we may need to shrink the header table.
498
532
if value < self ._header_table_size :
@@ -508,12 +542,16 @@ def header_table_size(self, value):
508
542
# to be removed from the reference set.
509
543
self .reference_set .discard ((n , v ))
510
544
545
+ log .debug ("Evicting %s: %s from the header table" , n , v )
546
+
511
547
self ._header_table_size = value
512
548
513
549
def decode (self , data ):
514
550
"""
515
551
Takes an HPACK-encoded header block and decodes it into a header set.
516
552
"""
553
+ log .debug ("Decoding %s" , data )
554
+
517
555
headers = set ()
518
556
data_len = len (data )
519
557
current_index = 0
@@ -571,6 +609,8 @@ def _add_to_header_table(self, name, value):
571
609
# be removed from the reference set.
572
610
self .reference_set .discard ((n , v ))
573
611
612
+ log .debug ("Evicting %s: %s from the header table" , n , v )
613
+
574
614
def _decode_indexed (self , data ):
575
615
"""
576
616
Decodes a header represented using the indexed representation.
@@ -598,9 +638,15 @@ def _decode_indexed(self, data):
598
638
# Since this updates the reference set, don't bother returning the
599
639
# header.
600
640
if header in self .reference_set :
641
+ log .debug (
642
+ "Removed %s from the reference set, consumed %d" ,
643
+ header ,
644
+ consumed
645
+ )
601
646
self .reference_set .remove (header )
602
647
return None , consumed
603
648
else :
649
+ log .debug ("Decoded %s, consumed %d" , header , consumed )
604
650
self .reference_set .add (header )
605
651
return header , consumed
606
652
@@ -666,4 +712,11 @@ def _decode_literal(self, data, should_index):
666
712
667
713
header = (name , value )
668
714
715
+ log .debug (
716
+ "Decoded %s, consumed %d, indexed %s" ,
717
+ header ,
718
+ consumed ,
719
+ should_index
720
+ )
721
+
669
722
return header , total_consumed
0 commit comments