
    ^i_                       S r SSKJr  SSKrSSKJrJr  SSKJrJ	r	J
r
  SSKJr  SSKJrJr  SS	KJr  SS
KJrJrJr  SSKJrJr  \(       a  SSKJr  \R6                  " \5      rSrSrSr \!" S5       V s/ s H  n SU -  S-
  PM     sn r"Sr#SS jr$SS jr%SS jr&  SS jr'S S jr( " S S5      r) " S S5      r*gs  sn f )!zL
Implements the HPACK header compression algorithm as detailed by RFC 7541.
    )annotationsN)TYPE_CHECKINGAny   )HPACKDecodingErrorInvalidTableSizeErrorOversizedHeaderListError)HuffmanEncoder)REQUEST_CODESREQUEST_CODES_LENGTH)decode_huffman)HeaderTupleHeaderWeaklyTypedNeverIndexedHeaderTuple)HeaderTabletable_entry_size)Iterable          @	      i   c                    [        U S   5      n[        U S   5      nU(       d0  U R                  UR                  S5      UR                  S5      5      $ U R                  X#5      $ )z^
Provides a header as a unicode string if raw is False, otherwise returns
it as a bytestring.
r   r   utf-8)bytes	__class__decode)headerrawnamevalues       E/home/james-whalen/.local/lib/python3.13/site-packages/hpack/hpack.py_unicode_if_neededr#   #   sY    
 D&)EG 4ell76KLLD((    c                `   [         R                  SX5        U S:  a  SU  3n[        U5      eUS:  d  US:  a  SU 3n[        U5      e[        U   nX:  a  [	        U /5      $ U/nX-  n U S:  a$  UR                  U S-  S-   5        U S	-  n U S:  a  M$  UR                  U 5        [	        U5      $ )
z]
Encodes an integer according to the wacky integer encoding rules
defined in the HPACK spec.
zEncoding %d with %d bitsr   z'Can only encode positive integers, got r      )Prefix bits must be between 1 and 8, got          )logdebug
ValueError_PREFIX_BIT_MAX_NUMBERS	bytearrayappend)integerprefix_bitsmsg
max_numberelementss        r"   encode_integerr6   0   s    
 II('?{7yAoQ+/9+Go(5J'##|HG
S.3#-.A S. OOGXr$   c                N   US:  d  US:  a  SU 3n[        U5      e[        U   nSnSnSSU-
  -	  n U S   U-  nXs:X  a*   X   nUS-  nUS:  a  XxS-
  U-  -  nOXxU-  -  nOUS-  nM)  [        R                  S
Xt5        Xt4$ ! [         a  n	SU < 3n[        U5      U	eS	n	A	ff = f)z
Decodes an integer according to the wacky integer encoding rules
defined in the HPACK spec. Returns a tuple of the decoded integer and the
number of bytes that were consumed from ``data`` in order to get that
integer.
r   r&   r'   r      r(   r*   z3Unable to decode HPACK integer representation from NzDecoded %d, consumed %d bytes)r-   r.   
IndexErrorr   r+   r,   )
datar2   r3   r4   indexshiftmasknumber	next_byteerrs
             r"   decode_integerrA   O   s     Q+/9+Go(5JEEQ_%D/a4 K	
#3588F500F
  II-v==  /CD8L %3./s   /B #B 
B$BB$c              #     #    [        U [        5      (       d  S[        U 5       3n[        U5      e[	        U R                  5       S S9nU H  nX0U   4v   M     g7f)z
Converts a dictionary to an iterable of key-value tuples. This is a
HPACK-specific function because it pulls "special-headers" out first and
then emits them.
zheader_dict not a dict, but c                @    [        U 5      R                  S5      (       + $ )N   :)	_to_bytes
startswith)ks    r"   <lambda>#_dict_to_iterable.<locals>.<lambda>   s    )A,11$77r$   )keyN)
isinstancedicttype	TypeErrorsortedkeys)header_dictr3   rP   rJ   s       r"   _dict_to_iterablerR   v   sc      k4((,T+->,?@n7D s### s   AAc                x    [        U 5      nU[        L a  U $ U[        La  [        U 5      n U R                  S5      $ )z:
Convert anything to bytes through a UTF-8 encoded string
r   )rM   r   strencode)r!   ts     r"   rE   rE      s8     	UAEz|E
<<  r$   c                      \ rS rSrSrSS jr\SS j5       r\R                  SS j5       r S     SS jjr	SSS jjr
SS jrSSS	 jjrSSS
 jjrSS jrSrg)Encoder   za
An HPACK encoder object. This object takes HTTP headers and emits encoded
HTTP/2 header blocks.
c                b    [        5       U l        [        [        [        5      U l        / U l        g N)r   header_tabler
   r   r   huffman_codertable_size_changesselfs    r"   __init__Encoder.__init__   s)    'M+/
 .0r$   c                .    U R                   R                  $ z.
Controls the size of the HPACK header table.
r\   maxsizer_   s    r"   header_table_sizeEncoder.header_table_size       
   (((r$   c                    XR                   l        U R                   R                  (       a  U R                  R	                  U5        g g r[   )r\   rf   resizedr^   r0   r`   r!   s     r"   rg   rh      s6    $)!$$##**51 %r$   c                N   / nU R                   R                  (       a0  UR                  U R                  5       5        SU R                   l        [	        U[
        5      (       a  [        U5      nO [        U5      nU H}  nSn[	        U[        5      (       a  UR                  (       + nO[        U5      S:  a  US   n[        US   5      [        US   5      4nUR                  U R                  XvU5      5        M     SR                  U5      n[        R                  SU5        U$ )ah  
Takes a set of headers and encodes them into a HPACK-encoded header
block.

:param headers: The headers to encode. Must be either an iterable of
                tuples, an iterable of :class:`HeaderTuple
                <hpack.HeaderTuple>`, or a ``dict``.

                If an iterable of tuples, the tuples may be either
                two-tuples or three-tuples. If they are two-tuples, the
                tuples must be of the format ``(name, value)``. If they
                are three-tuples, they must be of the format
                ``(name, value, sensitive)``, where ``sensitive`` is a
                boolean value indicating whether the header should be
                added to header tables anywhere. If not present,
                ``sensitive`` defaults to ``False``.

                If an iterable of :class:`HeaderTuple
                <hpack.HeaderTuple>`, the tuples must always be
                two-tuples. Instead of using ``sensitive`` as a third
                tuple entry, use :class:`NeverIndexedHeaderTuple
                <hpack.NeverIndexedHeaderTuple>` to request that
                the field never be indexed.

                .. warning:: HTTP/2 requires that all special headers
                    (headers whose names begin with ``:`` characters)
                    appear at the *start* of the header block. While
                    this method will ensure that happens for ``dict``
                    subclasses, callers using any other iterable of
                    tuples **must** ensure they place their special
                    headers at the start of the iterable.

                    For efficiency reasons users should prefer to use
                    iterables of two-tuples: fixing the ordering of
                    dictionary headers is an expensive operation that
                    should be avoided if possible.

:param huffman: (optional) Whether to Huffman-encode any header sent as
                a literal value. Except for use when debugging, it is
                recommended that this be left enabled.

:returns: A bytestring containing the HPACK-encoded header block.
Fr   r   r   r$   zEncoded header block to %s)r\   rk   r0   _encode_table_size_changerK   rL   rR   iterr   	indexablelenrE   addjoinr+   r,   )	r`   headershuffmanheader_blockhpack_headersr   	sensitive
new_headerencodeds	            r"   rU   Encoder.encode   s   p  $$ > > @A(-D%gt$$ .g6M& !MM $FI&+.. & 0 00	Vq"1I	#F1I.	&)0DEJ HI $ ((<(		.8r$   c                   [         R                  SUUU5        Uu  pEU(       d  [        O[        nU R                  R                  XE5      nUc6  U R                  XEXc5      nU(       d  U R                  R                  XE5        U$ Uu  pn
U
(       a  U R                  U	5      nU$ U R                  XXc5      nU(       d  U R                  R                  XE5        U$ )z&
Serializes a header key-value tuple.
z7Adding %s to the header table, sensitive:%s, huffman:%s)
r+   r,   INDEX_INCREMENTALINDEX_NEVERr\   search_encode_literalrr   _encode_indexed_encode_indexed_literal)r`   to_addrx   ru   r    r!   indexbitmatchrz   r;   perfects              r"   rr   Encoder.add  s     			E		
  -6$; !!((5= **4JG!!%%d2N
  %W**51G  22hG !!%%d2r$   c                J    [        US5      nUS==   S-  ss'   [        U5      $ )z4
Encodes a header using the indexed representation.
r*   r   r(   )r6   r   )r`   r;   fields      r"   r   Encoder._encode_indexedM  s(     ua(aDU|r$   c                b   U(       a6  U R                   R                  U5      nU R                   R                  U5      n[        [        U5      S5      n[        [        U5      S5      nU(       a  US==   S-  ss'   US==   S-  ss'   SR	                  U[        U5      U[        U5      U/5      $ )z
Encodes a header with a literal name and literal value. If ``indexing``
is True, the header will be added to the header table: otherwise it
will not.
r*   r   r(   r$   )r]   rU   r6   rq   rs   r   )r`   r    r!   r   ru   name_len	value_lens          r"   r   Encoder._encode_literalU  s     %%,,T2D&&--e4E!#d)Q/"3u:q1	QK4KaLD LxxuXeI.>F
 	
r$   c                V   U[         :w  a  [        US5      nO[        US5      nUS==   [        U5      -  ss'   U(       a  U R                  R	                  U5      n[        [        U5      S5      nU(       a  US==   S-  ss'   SR                  [        U5      [        U5      U/5      $ )z^
Encodes a header with an indexed name and a literal value and performs
incremental indexing.
      r   r*   r(   r$   )r}   r6   ordr]   rU   rq   rs   r   )r`   r;   r!   r   ru   prefixr   s          r"   r   Encoder._encode_indexed_literalj  s    
 ((#E1-F#E1-Fq	S]"	&&--e4E"3u:q1	aLD Lxxvi(8%@AAr$   c                    SnU R                    H*  n[        US5      nUS==   S-  ss'   U[        U5      -  nM,     / U l         U$ )zL
Produces the encoded form of all header table size change context
updates.
r$      r       )r^   r6   r   )r`   block
size_bytesbs       r"   rn   !Encoder._encode_table_size_change  sO    
 11Jz1-AaDDLDU1XE 2 #%r$   )r\   r]   r^   NreturnNoner   intr!   r   r   r   )T)rt   zIterable[HeaderTuple | tuple[bytes | str, bytes | str] | tuple[bytes | str, bytes | str, bool | None]] | dict[bytes | str, bytes | str]ru   boolr   r   F)r   ztuple[bytes, bytes]rx   r   ru   r   r   r   )r;   r   r   r   )
r    r   r!   r   r   r   ru   r   r   r   )
r;   r   r!   r   r   r   ru   r   r   r   )r   r   )__name__
__module____qualname____firstlineno____doc__ra   propertyrg   setterrU   rr   r   r   r   rn   __static_attributes__ r$   r"   rX   rX      s    
0 ) ) 2 2  $k2k k ).kZ/b
*B,r$   rX   c                      \ rS rSrSr\4SS jjr\SS j5       r\R                  SS j5       rSSS jjr
SS jrSS jrSS	 jrSS
 jrSS jrSS jrSrg)Decoderi  a  
An HPACK decoder object.

.. versionchanged:: 2.3.0
   Added ``max_header_list_size`` argument.

:param max_header_list_size: The maximum decompressed size we will allow
    for any single header block. This is a protection against DoS attacks
    that attempt to force the application to expand a relatively small
    amount of data into a really large header list, allowing enormous
    amounts of memory to be allocated.

    If this amount of data is exceeded, a `OversizedHeaderListError
    <hpack.OversizedHeaderListError>` exception will be raised. At this
    point the connection should be shut down, as the HPACK state will no
    longer be usable.

    Defaults to 64kB.
:type max_header_list_size: ``int``
c                d    [        5       U l        Xl        U R                  R                  U l        g r[   )r   r\   max_header_list_sizerf   max_allowed_table_size)r`   r   s     r"   ra   Decoder.__init__  s*    'M  %9! '+&7&7&?&?#r$   c                .    U R                   R                  $ rd   re   r_   s    r"   rg   Decoder.header_table_size  ri   r$   c                $    XR                   l        g r[   re   rl   s     r"   rg   r     s    $)!r$   c                8   [         R                  SU5        [        U5      n/ n[        U5      nSnSnXu:  Ga  X   n[	        US-  5      n	[	        US-  5      n
[	        US-  5      nU	(       a  U R                  X7S 5      u  pOcU
(       a  U R                  X7S 5      u  pOFU(       a*  U(       a  Sn[        U5      eU R                  X7S 5      nSnOU R                  X7S 5      u  pU(       aP  UR                  U5        U[        US   US   5      -  nX`R                  :  a  S	U R                   S
3n[        U5      eX}-  nXu:  a  GM  U R                  5          U Vs/ s H  n[        X5      PM     sn$ s  snf ! [          a  nSn[        U5      UeSnAff = f)a  
Takes an HPACK-encoded header block and decodes it into a header set.

:param data: A bytestring representing a complete HPACK-encoded header
             block.
:param raw: (optional) Whether to return the headers as tuples of raw
            byte strings or to decode them as UTF-8 before returning
            them. The default value is False, which returns tuples of
            Unicode strings
:returns: A list of two-tuples of ``(name, value)`` representing the
          HPACK-encoded headers, in the order they were decoded.
:raises HPACKDecodingError: If an error is encountered while decoding
                            the header block.
zDecoding %sr   r(   @   r   Nz/Table size update not at the start of the blockr   zA header list larger than z has been receivedz!Unable to decode headers as UTF-8)r+   r,   
memoryviewrq   r   _decode_indexed_decode_literal_indexr   _update_encoding_context_decode_literal_no_indexr0   r   r   r	   _assert_valid_table_sizer#   UnicodeDecodeError)r`   r:   r   data_memrt   data_leninflated_sizecurrent_indexcurrentindexedliteral_indexencoding_updater   consumedr3   hr@   s                    r"   r   Decoder.decode  s    			-&d#%'t9& )G7T>*G !40M #7T>2O#'#7#7^,$  #'#=#=^,$  ! KC,S1188^,  $(#@#@^,$  v&!1&)VAY!GG #<#<<6t7P7P6QQcdC2377%M_ &h 	%%'	38?@1&q.@@@! 	35C$S)s2	3s*   E< E74E< 7E< <
FFFc                R    U R                   U R                  :  a  Sn[        U5      eg)z[
Check that the table size set by the encoder is lower than the maximum
we expect to have.
z3Encoder did not shrink table size to within the maxN)rg   r   r   )r`   r3   s     r"   r    Decoder._assert_valid_table_size  s.    
 !!D$?$??GC',, @r$   c                f    [        US5      u  p#X R                  :  a  Sn[        U5      eX l        U$ )z3
Handles a byte that updates the encoding context.
r   z)Encoder exceeded max allowable table size)rA   r   r   rg   )r`   r:   new_sizer   r3   s        r"   r    Decoder._update_encoding_context'  s:    
 ,D!4111=C',,!)r$   c                    [        US5      u  p#[        U R                  R                  U5      6 n[        R                  SXC5        XC4$ )z@
Decodes a header represented using the indexed representation.
r*   zDecoded %s, consumed %d)rA   r   r\   get_by_indexr+   r,   )r`   r:   r;   r   r   s        r"   r   Decoder._decode_indexed3  sE     )q1d//<<UCD		+V>r$   c                "    U R                  USS9$ )NFshould_index_decode_literalr`   r:   s     r"   r    Decoder._decode_literal_no_index<  s    ##Du#==r$   c                "    U R                  USS9$ )NTr   r   r   s     r"   r   Decoder._decode_literal_index?  s    ##Dt#<<r$   c                   SnU(       a  US   S-  nSnSnOUS   nUS-  nSn[        US-  5      nU(       a0  [        X5      u  pU R                  R                  U5      S   n
U	nSnOTUSS	 n[        US
5      u  pXX-    n
[	        U
5      U:w  a  Sn[        U5      eUS   S-  (       a  [        U
5      n
X-   S-   nXU-   S	 n[        US
5      u  pXX-    n[	        U5      U:w  a  Sn[        U5      eUS   S-  (       a  [        U5      nX;U	-   -  nU(       a  [        X5      nO[        X5      nU(       a  U R                  R                  X5        [        R                  SUUU5        X4$ )z.
Decodes a header represented with a literal.
r   ?   r   F   r      r   Nr*   zTruncated header blockr(   z/Decoded %s, total consumed %d bytes, indexed %s)r   rA   r\   r   rq   r   r   r   r   rr   r+   r,   )r`   r:   r   total_consumedindexed_namer   not_indexable	high_byter;   r   r    lengthr3   r!   r   s                  r"   r   Decoder._decode_literalB  s     7T>LH!MQI$t+LH T!12M,T<OE$$11%8;D%NF 8D-dA6F!23D4yF".(--Aw~%d+%.2Nv%&' *$2h/0u:*C$S))7T>"5)E 	8++
 ,T9F -F !!$.		=		
 %%r$   )r\   rg   r   r   N)r   r   r   r   r   r   r   )r:   r   r   r   r   zIterable[HeaderTuple]r   )r:   r   r   r   )r:   r   r   tuple[HeaderTuple, int])r:   r   r   r   r   r   )r   r   r   r   r   DEFAULT_MAX_HEADER_LIST_SIZEra   r   rg   r   r   r   r   r   r   r   r   r   r   r$   r"   r   r     sg    * 4P @8 ) ) * *Q3f-
 >=L&r$   r   )r   r   r   r   r   r   )r1   r   r2   r   r   r/   )r:   r   r2   r   r   ztuple[int, int])rQ   zdict[bytes | str, bytes | str]r   z)Iterable[tuple[bytes | str, bytes | str]])r!   zbytes | str | Anyr   r   )+r   
__future__r   loggingtypingr   r   
exceptionsr   r   r	   ru   r
   huffman_constantsr   r   huffman_tabler   structr   r   r   tabler   r   collections.abcr   	getLoggerr   r+   
INDEX_NONEr~   r}   ranger.   r   r#   r6   rA   rR   rE   rX   r   )is   0r"   <module>r      s    #  % [ [ # B ) K K 0(!
 
 27q:AAFa<:   ' 
)>$N$4$&	!v vr@& @&e ;s   4B;