
    gX                     L   d 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  ej&                  e      Zd
ZdZdZ ed      D  cg c]
  } d| z  dz
   c} Z	 eZdZd Z d Z!d Z"d Z#d Z$ G d d      Z% G d d      Z&yc c} w # e$ r eefZY 6w xY w)ze
hpack/hpack
~~~~~~~~~~~

Implements the HPACK header compression algorithm as detailed by the IETF.
    N   )HeaderTabletable_entry_size)HPACKDecodingErrorOversizedHeaderListErrorInvalidTableSizeError)HuffmanEncoder)REQUEST_CODESREQUEST_CODES_LENGTH)decode_huffman)HeaderTupleNeverIndexedHeaderTuple          @	      i   c                     t        | d         }t        | d         }|s"|j                  d      }|j                  d      }| 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decode	__class__)headerrawnamevalues       @/var/www/openai/venv/lib/python3.12/site-packages/hpack/hpack.py_unicode_if_neededr   +   sR    
 D&)E{{7#W%D%((    c                 P   t         j                  d| |       | dk  rt        d| z        |dk  s|dkD  rt        d|z        t        |   }| |k  rt	        | g      S |g}| |z  } | dk\  r"|j                  | dz  dz          | d	z  } | dk\  r"|j                  |        t	        |      S )
zn
    This 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 %sr      +Prefix bits must be between 1 and 8, got %s         )logdebug
ValueError_PREFIX_BIT_MAX_NUMBERS	bytearrayappend)integerprefix_bits
max_numberelementss       r   encode_integerr0   8   s    
 II(';?{7'A
 	
 Q+/9KG
 	
 )5J'##<:nOOWs]c12MG n 	 ""r   c                 :   |dk  s|dkD  rt        d|z        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 t        d| z        w xY w)
z
    This 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%   z5Unable to decode HPACK integer representation from %rzDecoded %d, consumed %d bytes)r(   r)   
IndexErrorr   r&   r'   )datar-   r.   indexshiftmasknumber	next_bytes           r   decode_integerr:   Z   s     Q+/9KG
 	
 )5JEEQ_%D
a4Z K	
#y3588Fi500F
   II-vu=5=  
 CdJ
 	

s   8B Bc              #      K   t        | t              sJ t        | j                         d       }|D ]  }|| |   f  yw)z
    This converts a dictionary to an iterable of two-tuples. This is a
    HPACK-specific function because it pulls "special-headers" out first and
    then emits them.
    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sortedkeys)header_dictrF   rB   s      r   _dict_to_iterablerH      sM      k4(((7D ;s### s   A Ac                 ~    t        | t              st        |       } t        | t              r| S | j	                  d      S )z"
    Convert string to bytes.
    r   )rC   
basestringstrr   encode)strings    r   r>   r>      s4     fj)V.6JFMM'4JJr   c                   v    e Zd ZdZd Zed        Zej                  d        ZddZddZ	d Z
ddZdd	Z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+/
 #%r   c                 .    | j                   j                  S z>
        Controls the size of the HPACK header table.
        rR   maxsizerU   s    r   header_table_sizezEncoder.header_table_size       
   (((r   c                     || j                   _        | j                   j                  r| j                  j	                  |       y y rQ   )rR   r[   resizedrT   r+   rV   r   s     r   r\   zEncoder.header_table_size   s8    $)!$$##**51 %r   c                 
   g }t        |t              rt        |      }| j                  j                  r0|j                  | j                                d| j                  _        |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)rC   rD   rH   rR   r_   r+   _encode_table_size_changer   	indexablelenr>   addjoinr&   r'   )rV   headershuffmanheader_blockr   	sensitives         r   rL   zEncoder.encode   s    d 
 gt$'0G $$ > > @A(-D% FI&+. & 0 00	Vq"1I	q	*IfQi,@AFG DE  xx-		.=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 )zQ
        This function takes a header key-value tuple and serializes it.
        z7Adding %s to the header table, sensitive:%s, huffman:%s)
r&   r'   INDEX_INCREMENTALINDEX_NEVERrR   search_encode_literalre   _encode_indexed_encode_indexed_literal)rV   to_addrj   rh   r   r   indexbitmatchencodedr5   perfects              r   re   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#   )r0   r   )rV   r5   fields      r   rp   zEncoder._encode_indexed8  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   )rS   rL   r0   rd   rf   r   )rV   r   r   rs   rh   name_len	value_lens          r   ro   zEncoder._encode_literal@  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   )rl   r0   ordrS   rL   rd   rf   r   )rV   r5   r   rs   rh   prefixr{   s          r   rq   zEncoder._encode_indexed_literalU  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       )rT   r0   r   )rV   block
size_bytess      r   rb   z!Encoder._encode_table_size_changek  sQ    
 11J'
A6JqMT!MU:&&E 2 #%r   N)TF)__name__
__module____qualname____doc__rW   propertyr\   setterrL   re   rp   ro   rq   rb    r   r   rO   rO      s\    
% ) ) 2 2
Ob/b
*B,r   rO   c                   z    e Zd ZdZefdZed        Zej                  d        ZddZ	d Z
d Zd Zd	 Zd
 Z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 rQ   )r   rR   max_header_list_sizer[   max_allowed_table_size)rV   r   s     r   rW   zDecoder.__init__  s,    'M  %9! '+&7&7&?&?#r   c                 .    | j                   j                  S rY   rZ   rU   s    r   r\   zDecoder.header_table_size  r]   r   c                 &    || j                   _        y rQ   rZ   r`   s     r   r\   zDecoder.header_table_size  s    $)!r   c                    t         j                  d|       t        |      }g }t        |      }d}d}||k  r||   }|dz  rdnd}	|dz  rdnd}
|dz  rdnd}|	r| j	                  ||d       \  }}nW|
r| j                  ||d       \  }}n=|r$|rt        d	      | j                  ||d       }d}n| j                  ||d       \  }}|rC|j                  |       |t        | z  }|| j                  kD  rt        d
| j                  z        ||z  }||k  r| j                          	 |D cg c]  }t        ||       c}S c c}w # t        $ r t        d      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#   TF@   r   Nz/Table size update not at the start of the blockz.A header list larger than %d has been receivedz"Unable to decode headers as UTF-8.)r&   r'   
memoryviewrd   _decode_indexed_decode_literal_indexr   _update_encoding_context_decode_literal_no_indexr+   r   r   r   _assert_valid_table_sizer   UnicodeDecodeError)rV   r4   r   data_memrg   data_leninflated_sizecurrent_indexcurrentindexedliteral_indexencoding_updater   consumedhs                  r   r   zDecoder.decode  s    			-&d#t9h& =)G%nd%G %,dNDM '.nd%O#'#7#7]^,$  #'#=#=]^,$  ! ,I   88]^,  $(#@#@]^,$  v&!16!:: 4#<#<<2H112 
 X%Me h&n 	%%'	K8?@1&q#.@@@! 	K$%IJJ	Ks   *E	 .EE	 E	 	Ec                 L    | j                   | j                  kD  rt        d      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)r\   r   r   rU   s    r   r   z Decoder._assert_valid_table_size
  s.    
 !!D$?$??'E  @r   c                 f    t        |d      \  }}|| j                  kD  rt        d      || _        |S )zC
        Handles a byte that updates the encoding context.
        r   z)Encoder exceeded max allowable table size)r:   r   r   r\   )rV   r4   new_sizer   s       r   r   z Decoder._update_encoding_context  sB    
 ,D!4(d111';  "*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)r:   r   rR   get_by_indexr&   r'   )rV   r4   r5   r   r   s        r   r   zDecoder._decode_indexed!  sK     )q1xd//<<UCD		+VX>xr   c                 &    | j                  |d      S )NF_decode_literalrV   r4   s     r   r   z Decoder._decode_literal_no_index*  s    ##D%00r   c                 &    | j                  |d      S )NTr   r   s     r   r   zDecoder._decode_literal_index-  s    ##D$//r   c                    d}|r|d   dz  }d}d}n|d   }|dz  }d}|dz  }|r2t        ||      \  }}	| j                  j                  |      d   }
|	}d}nP|dd	 }t        |d
      \  }}	||	|	|z    }
t        |
      |k7  rt	        d      |d   dz  rt        |
      }
|	|z   dz   }||	|z   d	 }t        |d
      \  }}	||	|	|z    }t        |      |k7  rt	        d      |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:   rR   r   rd   r   r   r   r   re   r&   r'   )rV   r4   should_indextotal_consumedindexed_namerz   not_indexable	high_byter5   r   r   lengthr   r   s                 r   r   zDecoder._decode_literal0  s     7T>LH!MQI$t+LH%,M,T8<OE8$$11%8;D%NF 8D-dA6FHF!23D4yF"()ABBAw~%d+%.2NHv%&' *$2Xh/0u:$%=>>7T>"5)E 	&8++ ,T59F u-F !!$.		=		
 ~%%r   Nr   )r   r   r   r   DEFAULT_MAX_HEADER_LIST_SIZErW   r   r\   r   r   r   r   r   r   r   r   r   r   r   r   r   y  sh    ( -I @8 ) ) * *SKj 10I&r   r   )'r   loggingtabler   r   
exceptionsr   r   r   rh   r	   huffman_constantsr
   r   huffman_tabler   structr   r   	getLoggerr   r&   
INDEX_NONErm   rl   ranger)   rJ   	NameErrorrK   r   r   r   r0   r:   rH   r>   rO   r   )is   0r   <module>r      s     0  $ * 8g!
 
 27q:AAFa<: J  ' 
)#D&R$KZ Zz@& @&w
 ;  uJs   B*B 	B#"B#