
    &Xh_                    f   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  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       5/RAG/venv/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_integerr6   0   s    
 II(';?{7yAoQ+/9+Go(5J'##|HzG
S.3#-.A S. OOGXr$   c                L   |dk  s|dkD  rd| }t        |      t        |   }d}d}dd|z
  z	  }	 | d   |z  }||k(  r+	 | |   }|dz  }|dk\  r||dz
  |z  z  }n	|||z  z  }n|dz  }*t        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*   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Z K	
#y3588Fi500F
  II-vu=5=  /CD8L %3./s   8B 	B#B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7r$   )keyN)
isinstancedicttype	TypeErrorsortedkeys)header_dictr3   rO   rI   s       r"   _dict_to_iterablerQ   v   sc      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   )rL   r   strencode)r!   ts     r"   rE   rE      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.
        rZ   maxsizer]   s    r"   header_table_sizezEncoder.header_table_size       
   (((r$   c                    || j                   _        | j                   j                  r| j                  j	                  |       y y rY   )rZ   rc   resizedr\   r0   r^   r!   s     r"   rd   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)rZ   rg   r0   _encode_table_size_changerJ   rK   rQ   iterr   	indexablelenrE   addjoinr+   r,   )	r^   headershuffmanheader_blockhpack_headersr   	sensitive
new_headerencodeds	            r"   rT   zEncoder.encode   s    p  $$ > > @A(-D%gt$ .g6M& !MM $FI&+. & 0 00	Vq"1I	#F1I.	&)0DEJY HI $ ((<(		.8r$   c                   t         j                  d|||       |\  }}|st        nt        }| j                  j                  ||      }|4| j                  ||||      }|s| j                  j                  ||       |S |\  }	}}
|
r| j                  |	      }|S | j                  |	|||      }|s| j                  j                  ||       |S )z6
        Serializes a header key-value tuple.
        z7Adding %s to the header table, sensitive:%s, huffman:%s)
r+   r,   INDEX_INCREMENTALINDEX_NEVERrZ   search_encode_literalrn   _encode_indexed_encode_indexed_literal)r^   to_addrt   rq   r    r!   indexbitmatchrv   r;   perfects              r"   rn   zEncoder.add  s     			E		
 e -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(   )r6   r   )r^   r;   fields      r"   r|   zEncoder._encode_indexedM  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[   rT   r6   rm   ro   r   )r^   r    r!   r   rq   name_len	value_lens          r"   r{   zEncoder._encode_literalU  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$   )rx   r6   ordr[   rT   rm   ro   r   )r^   r;   r!   r   rq   prefixr   s          r"   r}   z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                    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\   r6   r   )r^   block
size_bytesbs       r"   rj   z!Encoder._encode_table_size_change  sO    
 11Jz1-AaDDLDU1XE 2 #%r$   NreturnNoner   intr!   r   r   r   )T)rp   zIterable[HeaderTuple | tuple[bytes | str, bytes | str] | tuple[bytes | str, bytes | str, bool | None]] | dict[bytes | str, bytes | str]rq   boolr   r   F)r~   ztuple[bytes, bytes]rt   r   rq   r   r   r   )r;   r   r   r   )
r    r   r!   r   r   r   rq   r   r   r   )
r;   r   r!   r   r   r   rq   r   r   r   )r   r   )__name__
__module____qualname____doc__r_   propertyrd   setterrT   rn   r|   r{   r}   rj    r$   r"   rW   rW      s    
0 ) ) 2 2  $k2k k ).kZ/b
*B,r$   rW   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 rY   )r   rZ   max_header_list_sizerc   max_allowed_table_size)r^   r   s     r"   r_   zDecoder.__init__  s,    'M  %9! '+&7&7&?&?#r$   c                .    | j                   j                  S ra   rb   r]   s    r"   rd   zDecoder.header_table_size  re   r$   c                &    || j                   _        y rY   rb   rh   s     r"   rd   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,   
memoryviewrm   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_memrp   data_leninflated_sizecurrent_indexcurrentindexedliteral_indexencoding_updater   consumedr3   hr@   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)rd   r   r   )r^   r3   s     r"   r   z Decoder._assert_valid_table_size  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)rA   r   r   rd   )r^   r:   new_sizer   r3   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)rA   r   rZ   get_by_indexr+   r,   )r^   r:   r;   r   r   s        r"   r   zDecoder._decode_indexed3  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_index<  s    ##Du#==r$   c                (    | j                  |d      S )NTr   r   r   s     r"   r   zDecoder._decode_literal_index?  s    ##Dt#<<r$   c                   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)r   rA   rZ   r   rm   r   r   r   r   rn   r+   r,   )r^   r:   r   total_consumedindexed_namer   not_indexable	high_byter;   r   r    lengthr3   r!   r   s                  r"   r   zDecoder._decode_literalB  s     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:   r   r   r   )r:   r   r   tuple[HeaderTuple, int])r:   r   r   r   r   r   )r   r   r   r   DEFAULT_MAX_HEADER_LIST_SIZEr_   r   rd   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])rP   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	   rq   r
   huffman_constantsr   r   huffman_tabler   structr   r   r   tabler   r   collections.abcr   	getLoggerr   r+   
INDEX_NONEry   rx   ranger.   r   r#   r6   rA   rQ   rE   rW   r   )is   0r"   <module>r      s    #  % [ [ # B ) K K 0(g!
 
 27q:AAFa<:   ' 
)>$N$4$&	!v vr@& @&e ;s   /B.