
    jje                    j   d Z ddlmZ ddlZddlmZmZ ddlmZm	Z	m
Z
 ddlmZ ddlmZmZ dd	lmZ dd
lmZmZmZ ddlmZmZ erddlmZ  ej6                  e      ZdZdZdZ dZ! e"d      D  cg c]
  } d| z  dz
   c} Z#dZ$ddZ%ddZ&ddZ'	 	 d dZ(d!dZ) G d d      Z* G d d      Z+yc c} w )"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                    t        | d         }t        | d         }|s0| j                  |j                  d      |j                  d            S | j                  ||      S )zj
    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       T/home/ubuntu/.cache/pipx/cdb5059130eadca/lib/python3.12/site-packages/hpack/hpack.py_unicode_if_neededr$   %   s[    
 D&)EG 4ell76KLLD%((    c                X   t         j                  d| |       | dk  rd|  }t        |      |dk  s|dkD  rd| }t        |      t        |   }| |k  rt	        | g      S |g}| |z  } | dk\  r"|j                  | dz  dz          | d	z  } | dk\  r"|j                  |        t	        |      S )
zi
    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_integerr7   2   s    
 II(';?{7yAoQ+/9+Go(5J'##|HzG
S.3#-.A S. OOGXr%   c                ~   |dk  s|dkD  rd| }t        |      t        |   }d}d}dd|z
  z	  }	 | d   |z  }||k(  rD	 | |   }|dz  }|dk\  r||dz
  |z  z  }n	|||z  z  }n|dz  }|t        kD  rd| }t        |      Ct
        j                  d||       ||fS # t        $ r}	d	| }t        |      |	d
}	~	ww xY w)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+   z-Variable integer representation is too long: z3Unable to decode HPACK integer representation from NzDecoded %d, consumed %d bytes)r.   r/   VARINT_MAX_LENGTHr   
IndexErrorr,   r-   )
datar3   r4   r5   indexshiftmasknumber	next_byteerrs
             r#   decode_integerrC   Q   s    Q+/9+Go(5JEEQ_%D/a4Z K	
#y3588Fi500F
,, J$RC,S11) 4 II-vu=5=  /CD8L %3./s   AB 	B<&B77B<c              #     K   t        | t              sdt        |        }t        |      t	        | j                         d       }|D ]  }|| |   f  yw)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                8    t        |       j                  d       S )N   :)	_to_bytes
startswith)ks    r#   <lambda>z#_dict_to_iterable.<locals>.<lambda>   s    )A,11$77 r%   )keyN)
isinstancedicttype	TypeErrorsortedkeys)header_dictr4   rQ   rK   s       r#   _dict_to_iterablerS      sh      k4(,T+->,?@n7D  $;s###$s   AAc                t    t        |       }|t        u r| S |t        urt        |       } | j                  d      S )zB
    Convert anything to bytes through a UTF-8 encoded string
    r   )rN   r   strencode)r"   ts     r#   rG   rG      s8     	UAEz|E
<<  r%   c                      e Zd ZdZddZedd       Zej                  dd       Z	 d	 	 	 	 	 ddZdddZ	ddZ
dddZddd	Zdd
Zy)Encoderzm
    An HPACK encoder object. This object takes HTTP headers and emits encoded
    HTTP/2 header blocks.
    c                b    t               | _        t        t        t              | _        g | _        y N)r   header_tabler
   r   r   huffman_codertable_size_changesselfs    r#   __init__zEncoder.__init__   s)    'M+/
 .0r%   c                .    | j                   j                  S z>
        Controls the size of the HPACK header table.
        r\   maxsizer_   s    r#   header_table_sizezEncoder.header_table_size       
   (((r%   c                    || j                   _        | j                   j                  r| j                  j	                  |       y y r[   )r\   re   resizedr^   r1   r`   r"   s     r#   rf   zEncoder.header_table_size   s8    $)!$$##**51 %r%   c                $   g }| j                   j                  r0|j                  | j                                d| j                   _        t	        |t
              rt        |      }n	 t        |      }|D ]s  }d}t	        |t              r|j                   }nt        |      dkD  r|d   }t        |d         t        |d         f}|j                  | j                  |||             u dj                  |      }t        j                  d|       |S )a	  
        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\   ri   r1   _encode_table_size_changerL   rM   rS   iterr   	indexablelenrG   addjoinr,   r-   )	r`   headershuffmanheader_blockhpack_headersr   	sensitive
new_headerencodeds	            r#   rV   zEncoder.encode   s   p  $$ > > @A(-D%gt$ .g6M& !MM $ 		JFI&+. & 0 00	Vq"1I	#F1I.	&)0DEJY HI		J ((<(		.8r%   c                   |\  }}|s|nd}t         j                  d||||       |st        nt        }| j                  j                  ||      }|4| j                  ||||      }	|s| j                  j                  ||       |	S |\  }
}}|| j                  |
      }	|	S | j                  |
|||      }	|s| j                  j                  ||       |	S )a}  
        Serializes a header key-value tuple.

        When sensitive is True, the header will not be added to the header table
        (see https://www.rfc-editor.org/rfc/rfc7541.html#section-7.1.3 for details),
        furthermore, the header value will be redacted in debug logs, as "SENSITIVE_REDACTED",
        to prevent accidental exposure of sensitive information.
        s   SENSITIVE_REDACTEDz:Adding %s=%s to the header table, sensitive:%s, huffman:%s)
r,   r-   INDEX_INCREMENTALINDEX_NEVERr\   search_encode_literalrp   _encode_indexed_encode_indexed_literal)r`   to_addrv   rs   r!   r"   display_valueindexbitmatchrx   r=   perfects               r#   rp   zEncoder.add)  s     e%.4I		H	
 -6$; !!((u5= **4'JG!!%%dE2N
  %tW**51G  22uhG !!%%dE2r%   c                J    t        |d      }|dxx   dz  cc<   t        |      S )zD
        Encodes a header using the indexed representation.
        r+   r   r)   )r7   r   )r`   r=   fields      r#   r~   zEncoder._encode_indexeda  s(     ua(aDU|r%   c                N   |r6| j                   j                  |      }| j                   j                  |      }t        t        |      d      }t        t        |      d      }|r|dxx   dz  cc<   |dxx   dz  cc<   dj	                  |t        |      |t        |      |g      S )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]   rV   r7   ro   rq   r   )r`   r!   r"   r   rs   name_len	value_lens          r#   r}   zEncoder._encode_literali  s     %%,,T2D&&--e4E!#d)Q/"3u:q1	QK4KaLD LxxuXeI.>F
 	
r%   c                @   |t         k7  rt        |d      }nt        |d      }|dxx   t        |      z  cc<   |r| j                  j	                  |      }t        t        |      d      }|r|dxx   dz  cc<   dj                  t        |      t        |      |g      S )zv
        Encodes a header with an indexed name and a literal value and performs
        incremental indexing.
              r   r+   r)   r%   )rz   r7   ordr]   rV   ro   rq   r   )r`   r=   r"   r   rs   prefixr   s          r#   r   zEncoder._encode_indexed_literal~  s    
 ((#E1-F#E1-Fq	S]"	&&--e4E"3u:q1	aLD Lxxvi(8%@AAr%   c                    d}| j                   D ])  }t        |d      }|dxx   dz  cc<   |t        |      z  }+ g | _         |S )zd
        Produces the encoded form of all header table size change context
        updates.
        r%   r   r       )r^   r7   r   )r`   block
size_bytesbs       r#   rl   z!Encoder._encode_table_size_change  sT    
 11 	Jz1-AaDDLDU1XE	 #%r%   NreturnNoner   intr"   r   r   r   )T)rr   zIterable[HeaderTuple | tuple[bytes | str, bytes | str] | tuple[bytes | str, bytes | str, bool | None]] | dict[bytes | str, bytes | str]rs   boolr   r   F)r   ztuple[bytes, bytes]rv   r   rs   r   r   r   )r=   r   r   r   )
r!   r   r"   r   r   r   rs   r   r   r   )
r=   r   r"   r   r   r   rs   r   r   r   )r   r   )__name__
__module____qualname____doc__ra   propertyrf   setterrV   rp   r~   r}   r   rl    r%   r#   rY   rY      s    
0 ) ) 2 2  $k2k k ).kZ6p
*B,r%   rY   c                      e Zd ZdZefddZedd       Zej                  dd       ZdddZ	ddZ
ddZddZdd	Zdd
ZddZy)Decodera  
    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                f    t               | _        || _        | j                  j                  | _        y r[   )r   r\   max_header_list_sizere   max_allowed_table_size)r`   r   s     r#   ra   zDecoder.__init__  s,    'M  %9! '+&7&7&?&?#r%   c                .    | j                   j                  S rc   rd   r_   s    r#   rf   zDecoder.header_table_size  rg   r%   c                &    || j                   _        y r[   rd   rj   s     r#   rf   zDecoder.header_table_size  s    $)!r%   c                   t         j                  d|       t        |      }g }t        |      }d}d}||k  r||   }t	        |dz        }	t	        |dz        }
t	        |dz        }|	r| j                  ||d       \  }}nY|
r| j                  ||d       \  }}n?|r&|rd}t        |      | j                  ||d       }d}n| j                  ||d       \  }}|rP|j                  |       |t        |d   |d         z  }|| j                  kD  rd	| j                   d
}t        |      ||z  }||k  r| j                          	 |D cg c]  }t        ||       c}S c c}w # t         $ r}d}t        |      |d}~ww xY w)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-   
memoryviewro   r   _decode_indexed_decode_literal_indexr   _update_encoding_context_decode_literal_no_indexr1   r   r   r	   _assert_valid_table_sizer$   UnicodeDecodeError)r`   r<   r    data_memrr   data_leninflated_sizecurrent_indexcurrentindexedliteral_indexencoding_updater   consumedr4   hrB   s                    r#   r   zDecoder.decode  s    			-&d#%'t9h& =)G7T>*G !40M #7T>2O#'#7#7]^,$  #'#=#=]^,$  ! KC,S1188]^,  $(#@#@]^,$  v&!1&)VAY!GG 4#<#<<6t7P7P6QQcdC2377X%M_ h&h 	%%'	38?@1&q#.@@@! 	35C$S)s2	3s*   E' E"E' "E' '	F0E>>Fc                P    | j                   | j                  kD  rd}t        |      y)zs
        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)rf   r   r   )r`   r4   s     r#   r   z Decoder._assert_valid_table_size2  s.    
 !!D$?$??GC',, @r%   c                j    t        |d      \  }}|| j                  kD  rd}t        |      || _        |S )zC
        Handles a byte that updates the encoding context.
        r   z)Encoder exceeded max allowable table size)rC   r   r   rf   )r`   r<   new_sizer   r4   s        r#   r   z Decoder._update_encoding_context;  s@    
 ,D!4(d111=C',,!)r%   c                    t        |d      \  }}t        | j                  j                  |       }t        j                  d||       ||fS )zP
        Decodes a header represented using the indexed representation.
        r+   zDecoded %s, consumed %d)rC   r   r\   get_by_indexr,   r-   )r`   r<   r=   r   r   s        r#   r   zDecoder._decode_indexedG  sK     )q1xd//<<UCD		+VX>xr%   c                (    | j                  |d      S )NFshould_index_decode_literalr`   r<   s     r#   r   z Decoder._decode_literal_no_indexP  s    ##Du#==r%   c                (    | j                  |d      S )NTr   r   r   s     r#   r   zDecoder._decode_literal_indexS  s    ##Dt#<<r%   c                   t        |t              r|j                         }d}|r|d   dz  }d}d}n|d   }|dz  }d}t        |dz        }|r2t	        ||      \  }}	| j
                  j                  |      d   }
|	}d}nR|dd	 }t	        |d
      \  }}	||	|	|z    }
t        |
      |k7  rd}t        |      |d   dz  rt        |
      }
|	|z   dz   }||	|z   d	 }t	        |d
      \  }}	||	|	|z    }t        |      |k7  rd}t        |      |d   dz  rt        |      }|||	z   z  }|rt        |
|      }nt        |
|      }|r| j
                  j                  |
|       t        j                  d|||       ||fS )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)rL   r   tobytesr   rC   r\   r   ro   r   r   r   r   rp   r,   r-   )r`   r<   r   total_consumedindexed_namer   not_indexable	high_byter=   r   r!   lengthr4   r"   r   s                  r#   r   zDecoder._decode_literalV  s    dJ'<<>D 7T>LH!MQI$t+LH T!12M,T8<OE8$$11%8;D%NF 8D-dA6FHF!23D4yF".(--Aw~%d+%.2NHv%&' *$2Xh/0u:*C$S))7T>"5)E 	&8++
 ,T59F u-F !!$.		=		
 ~%%r%   N)r   r   r   r   r   r   r   )r<   r   r    r   r   zIterable[HeaderTuple]r   )r<   bytes | memoryviewr   r   )r<   r   r   tuple[HeaderTuple, int])r<   r   r   r   r   r   )r   r   r   r   DEFAULT_MAX_HEADER_LIST_SIZEra   r   rf   r   r   r   r   r   r   r   r   r   r%   r#   r   r     sg    * 4P @8 ) ) * *Q3f-
 >=O&r%   r   )r   r   r    r   r   r   )r2   r   r3   r   r   r0   )r<   r   r3   r   r   ztuple[int, int])rR   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	   rs   r
   huffman_constantsr   r   huffman_tabler   structr   r   r   tabler   r   collections.abcr   	getLoggerr   r,   
INDEX_NONEr{   rz   r:   ranger/   r   r$   r7   rC   rS   rG   rY   r   )is   0r#   <module>r      s    #  % [ [ # B ) K K 0(g!
  
 27q:AAFa<:   ' 
)>/d$4$&	!} }@C& C&I ;s   1B0