
    gZ                        d Z ddlZddlZddlmZ ddlmZmZ ddlm	Z	m
Z
  ej                  d      Z eg d      Z eg d	      Z eg d
      Z eg d      Z eddg      Z eddg      Z e eee            Zd Zd Zd Zd Zd Z ej8                  dg d      Zd Zd Zd Z d Z!d Z"d Z#d Z$d Z%d Z&d  Z'd! Z(d" Z)d# Z*d$ Z+d% Z,d& Z-d' Z.d( Z/d) Z0d* Z1d+ Z2 G d, d-ejf                        Z4y).zW
h2/utilities
~~~~~~~~~~~~

Utility functions that do not belong in a separate module.
    N)
whitespace)HeaderTupleNeverIndexedHeaderTuple   )ProtocolErrorFlowControlErrors   [A-Z])
s
   connection
connections   proxy-connectionzproxy-connections
   keep-alivez
keep-alives   transfer-encodingztransfer-encodings   upgradeupgrade)   :method:method   :scheme:scheme
   :authority
:authority   :path:path   :status:status	   :protocol	:protocol)s   authorizationauthorizations   proxy-authorizationzproxy-authorization)
r   r   r   r   r   r   r   r   r   r   r   r   r   r   c              #      K   | D ]?  }|d   t         v rt        |  |d   dv rt        |d         dk  rt        |  <| A yw)a  
    Certain headers are at risk of being attacked during the header compression
    phase, and so need to be kept out of header compression contexts. This
    function automatically transforms certain specific headers into HPACK
    never-indexed fields to ensure they don't get added to header compression
    contexts.

    This function currently implements two rules:

    - 'authorization' and 'proxy-authorization' fields are automatically made
      never-indexed.
    - Any 'cookie' header field shorter than 20 bytes long is made
      never-indexed.

    These fields are the most at-risk. These rules are inspired by Firefox
    and nghttp2.
    r   )   cookiecookier      N)_SECURE_HEADERSr   lenheadershdr_validation_flagsheaders      A/var/www/openai/venv/lib/python3.12/site-packages/h2/utilities.py_secure_headersr#   B   sU     $ !9')622AY00S^b5H)622L s   AAc                 n    | D ]0  \  }}|dv st        |t              s|j                  d      c S |c S  y)z<
    Extracts the request method from the headers list.
    r   r   utf-8N
isinstancebytesencode)r   kvs      r"   extract_method_headerr-   ]   s9     1((a'xx((     c                     | D ]M  \  }}t        |t              rd}d}d}nd}d}d}|j                  |      s y||k7  r<|j                  |      c S  y)	a  
    Searches a header block for a :status header to confirm that a given
    collection of headers are an informational response. Assumes the header
    block is well formed: that is, that the HTTP/2 special headers are first
    in the block, and so that it can stop looking when it finds the first
    header field whose name does not begin with a colon.

    :param headers: The HTTP/2 header block.
    :returns: A boolean indicating if this is an informational response.
       :r      1:r   1FNr(   r)   
startswith)r   nr,   sigilstatusinformational_starts         r"   is_informational_responser:   i   sk     1aEF"&EF"& ||E" ; ||/00' r.   c                 :    d}| |z   }||kD  rt        d|z        |S )a-  
    Increments a flow control window, guarding against that window becoming too
    large.

    :param current: The current value of the flow control window.
    :param increment: The increment to apply to that window.
    :returns: The new value of the window.
    :raises: ``FlowControlError``
    iz-May not increment flow control window past %d)r   )current	incrementLARGEST_FLOW_CONTROL_WINDOWnew_sizes       r"   guard_increment_windowr@      s<     #,"H--;'(
 	

 Or.   c                 n    | D ]0  \  }}|dv st        |t              s|j                  d      c S |c S  y)a  
    Given a header set, searches for the authority header and returns the
    value.

    Note that this doesn't terminate early, so should only be called if the
    headers are for a client request. Otherwise, will loop over the entire
    header set, which is potentially unwise.

    :param headers: The HTTP header set.
    :returns: The value of the authority header, or ``None``.
    :rtype: ``bytes`` or ``None``.
    r   r   r&   Nr'   )r   r6   r,   s      r"   authority_from_headersrC      s?     1 ..,6q%,@188G$GaG  r.   HeaderValidationFlags)	is_client
is_traileris_response_headeris_push_promisec                     t        | |      } t        | |      } t        | |      } t        | |      } t	        | |      } t        | |      } t        | |      } t        | |      } | S )z
    Validates a header sequence against a set of constraints from RFC 7540.

    :param headers: The HTTP header set.
    :param hdr_validation_flags: An instance of HeaderValidationFlags.
    )_reject_empty_header_names_reject_uppercase_header_fields_reject_surrounding_whitespace
_reject_te_reject_connection_header_reject_pseudo_header_fields_check_host_authority_header_check_path_headerr   r    s     r"   validate_headersrS      s      )%G .%G -%G %G (%G +%G +%G !*>?GNr.   c              #   Z   K   | D ]"  }t        |d         dk(  rt        d      | $ yw)z
    Raises a ProtocolError if any header names are empty (length 0).
    While hpack decodes such headers without errors, they are semantically
    forbidden in HTTP, see RFC 7230, stating that they must be at least one
    character long.
    r   z&Received header name with zero length.N)r   r   r   s      r"   rJ   rJ      s3      vay>Q HII    )+c              #   t   K   | D ]/  }t         j                  |d         rt        d|d   z        | 1 yw)z[
    Raises a ProtocolError if any uppercase character is found in a header
    block.
    r   z"Received uppercase header name %s.N)UPPER_REsearchr   r   s      r"   rK   rK      sB     
 ??6!9%4vay@B B	 s   68c              #      K   | D ]e  }|d   d   t         v s|d   d   t         v rt        d|d   z        |d   r-|d   d   t         v s|d   d   t         v rt        d|d   z        | g yw)zh
    Raises a ProtocolError if any header name or value is surrounded by
    whitespace characters.
    r   z0Received header name surrounded by whitespace %rr   z1Received header value surrounded by whitespace %rN)_WHITESPACEr   r   s      r"   rL   rL     s      !9Q<;&&)B-;*FBVAYNP P!96!9Q<;61IbM[(CfQiO   s   A,A.c              #   |   K   | D ]3  }|d   dv r&|d   j                         dvrt        d|d   z        | 5 yw)z
    Raises a ProtocolError if the TE header is present in a header block and
    its value is anything other than "trailers".
    r   )s   teter   )s   trailerstrailerszInvalid value for TE header: %sN)lowerr   r   s      r"   rM   rM     sU     
 !9&ay (BB#51I 
  s   :<c              #   Z   K   | D ]"  }|d   t         v rt        d|d   z        | $ yw)z[
    Raises a ProtocolError if the Connection header is present in a header
    block.
    r   z-Connection-specific header field present: %s.N)CONNECTION_HEADERSr   r   s      r"   rN   rN   *  s?     
 !9**?&)K   rU   c                 f    t        | t              r| j                  |      S | j                  |      S )z
    Given a string that might be a bytestring or a Unicode string,
    return True if it starts with the appropriate prefix.
    r4   )test_stringbytes_prefixunicode_prefixs      r"   _custom_startswithrf   8  s0    
 +u%%%l33%%n55r.   c                 2    | |v s||v st        d| z        yy)z
    Given a set of header names, checks whether the string or byte version of
    the header name is present. Raises a Protocol error with the appropriate
    error if it's missing.
    z(Header block missing mandatory %s headerNr   )string_headerbytes_header
header_sets      r"   _assert_header_in_setrl   C  s1     Z'<:+E6F
 	
 ,F'r.   c              #     K   t               }d}d}| D ]  }t        |d   dd      r|d   |v rt        d|d   z        |j                  |d          |rt        d|d   z        |d   t        vrt        d|d   z        |d   d	v r0t        |d
   t              s|d
   j                  d      }n|d
   }nd}|  t        |||       yw)a   
    Raises a ProtocolError if duplicate pseudo-header fields are found in a
    header block or if a pseudo-header field appears in a block after an
    ordinary header field.

    Raises a ProtocolError if pseudo-header fields are found in trailers.
    FNr   r0   r2   z)Received duplicate pseudo-header field %sz0Received pseudo-header field out of sequence: %sz&Received custom pseudo-header field %sr%   r   r&   T)	setrf   r   add_ALLOWED_PSEUDO_HEADER_FIELDSr(   r)   r*   (_check_pseudo_header_field_acceptability)r   r    seen_pseudo_header_fieldsseen_regular_headermethodr!   s         r"   rO   rO   O  s     !$FfQit4ay55#?&)K  &))&)4"#F1I 
 ay ==#<vayH  ay44!&)U3#AY--g6F#AYF #'; @ -!6+?s   C
Cc                    |j                   r| rt        d| z        |j                  r't        dd|        | t        z  }|rt        d|z        y|j                  sm|j                   s`t        dd|        t        dd|        t        d	d
|        | t
        z  }|rt        d|z        |dk7  r| t        z  }|rt        d|z        yyyy)z
    Given the set of pseudo-headers present in a header block and the
    validation flags, confirms that RFC 7540 allows them.
    z$Received pseudo-header in trailer %sr   r   z#Encountered request-only headers %sr   r   r   r   r   r   z$Encountered response-only headers %ss   CONNECTz+Encountered connect-request-only headers %sN)rF   r   rG   rl   _REQUEST_ONLY_HEADERS_RESPONSE_ONLY_HEADERS_CONNECT_REQUEST_ONLY_HEADERS)pseudo_headersrt   r    invalid_response_headersinvalid_request_headersinvalid_headerss         r"   rq   rq     s    &&>2^C
 	
 ..j*nE#14I#I #5()  $
 #55"-- 	h.Aj*nEj*nE"03I"I"6'(  Z,/LLO#A#$     . 6r.   c              #      K   d}d}| D ]  }|d   dv r|d   }n|d   dv r|d   }| ! |du}|du}|s|st        d      |r|r||k7  rt        d|d|      yyyw)	a  
    Given the :authority and Host headers from a request block that isn't
    a trailer, check that:
     1. At least one of these headers is set.
     2. If both headers are set, they match.

    :param headers: The HTTP header set.
    :raises: ``ProtocolError``
    Nr   rB   r   )s   hosthostz@Request header block does not have an :authority or Host header.zARequest header block has mismatched :authority and Host headers: z / rh   )r   authority_header_valhost_header_valr!   authority_presenthost_presents         r"   _validate_host_authority_headerr     s     "  O!966#)!9 AY,,$QiO  .T9#4/L \N
 	

 \?2 (:  3 *s   AAc                 T    |j                   xs |j                  }|r| S t        |       S )z
    Raises a ProtocolError if a header block arrives that does not contain an
    :authority or a Host header, or if a header block contains both fields,
    but their values do not match.
    rG   rF   r   r   r    skip_validations      r"   rP   rP     5     	// 	(''  *733r.   c                 X      fd}|j                   xs |j                  }|r S  |       S )zm
    Raise a ProtocolError if a header block arrives or is sent that contains an
    empty :path header.
    c               3   R   K   D ]  } | d   dv r| d   st        d      |   y w)Nr   )r   r   r   z"An empty :path header is forbiddenrh   )r!   r   s    r"   innerz!_check_path_header.<locals>.inner  s6     Fay00ay'(LMML s   $')rG   rF   )r   r    r   r   s   `   r"   rQ   rQ     s7    
 	// 	(''  wr.   c              #      K   | D ]U  }t        |t              r)|j                  |d   j                         |d          <|d   j                         |d   f W yw)z
    Given an iterable of header two-tuples, rebuilds that iterable with the
    header names lowercased. This generator produces tuples that preserve the
    original type of the header tuple for tuple and any ``HeaderTuple``.
    r   r   N)r(   r   	__class__r_   r   s      r"   _lowercase_header_namesr     sX      fk*""6!9??#4fQi@@!9??$fQi00	 s   AAc              #      K   | D ]q  }t        |t              r7|j                  |d   j                         |d   j                                J|d   j                         |d   j                         f s yw)a  
    Given an iterable of header two-tuples, strip both leading and trailing
    whitespace from both header names and header values. This generator
    produces tuples that preserve the original type of the header tuple for
    tuple and any ``HeaderTuple``.
    r   r   N)r(   r   r   stripr   s      r"   _strip_surrounding_whitespacer     sf      fk*""6!9??#4fQioo6GHH!9??$fQioo&788	 s   A8A:c              #   :   K   | D ]  }|d   t         vs|  yw)uA   
    Strip any connection headers as per RFC7540 § 8.1.2.2.
    r   N)ra   r   s      r"   _strip_connection_headersr   +  s$      !9..L s   c                 T    |j                   xs |j                  }|r| S t        |       S )z
    Raises an InvalidHeaderBlockError if we try to send a header block
    that does not contain an :authority or a Host header, or if
    the header block contains both fields, but their values do not match.
    r   r   s      r"   !_check_sent_host_authority_headerr   4  r   r.   c              #      K   g }| D ]#  }|d   dk(  r|j                  |d           | % |r dj                  |      }t        d|       yyw)us  
    RFC 7540 § 8.1.2.5 allows HTTP/2 clients to split the Cookie header field,
    which must normally appear only once, into multiple fields for better
    compression. However, they MUST be joined back up again when received.
    This normalization step applies that transform. The side-effect is that
    all cookie fields now appear *last* in the header block.
    r   r   r   s   ; N)appendjoinr   )r   r    cookiesr!   
cookie_vals        r"   _combine_cookie_fieldsr   G  s]      G!9	!NN6!9%L	 
 ZZ(
%i<< s   AAc                 f    t        | |      } t        | |      } t        | |      } t        | |      } | S )z
    Normalizes a header sequence that we are about to send.

    :param headers: The HTTP header set.
    :param hdr_validation_flags: An instance of HeaderValidationFlags.
    )r   r   r   r#   rR   s     r"   normalize_outbound_headersr   ^  s=     &g/CDG+G5IJG'1EFGg';<GNr.   c                     t        | |      } | S )z
    Normalizes a header sequence that we have received.

    :param headers: The HTTP header set.
    :param hdr_validation_flags: An instance of HeaderValidationFlags
    )r   rR   s     r"   normalize_inbound_headersr   m  s     %W.BCGNr.   c                 ~    t        | |      } t        | |      } t        | |      } t        | |      } t	        | |      } | S )z
    Validates and normalizes a header sequence that we are about to send.

    :param headers: The HTTP header set.
    :param hdr_validation_flags: An instance of HeaderValidationFlags.
    )rM   rN   rO   r   rQ   rR   s     r"   validate_outbound_headersr   x  s^     %G (%G +%G 0%G !*>?GNr.   c                   .     e Zd Z fdZ fdZd Z xZS )SizeLimitDictc                 z    |j                  dd       | _        t        t        |   |i | | j                          y )N
size_limit)pop_size_limitsuperr   __init___check_size_limit)selfargskwargsr   s      r"   r   zSizeLimitDict.__init__  s6    !::lD9mT+T<V< r.   c                 N    t         t        |   ||       | j                          y )N)r   r   __setitem__r   )r   keyvaluer   s      r"   r   zSizeLimitDict.__setitem__  s     mT.sE: r.   c                     | j                   Et        |       | j                   kD  r,| j                  d       t        |       | j                   kD  r+y y y )NF)last)r   r   popitem)r   s    r"   r   zSizeLimitDict._check_size_limit  sG    'd)d...%( d)d... (r.   )__name__
__module____qualname__r   r   r   __classcell__)r   s   @r"   r   r     s    !!
)r.   r   )5__doc__collectionsrestringr   hpackr   r   
exceptionsr   r   compilerW   	frozensetra   rp   r   rv   rw   rx   mapordr[   r#   r-   r:   r@   rC   
namedtuplerD   rS   rJ   rK   rL   rM   rN   rf   rl   rO   rq   r   rP   rQ   r   r   r   r   r   r   r   r   OrderedDictr    r.   r"   <module>r      s]    	  6 72::h      !* + !     " #   #J
#;< 
 !*<*F G  C,-6	1B02 /..H 'T
	, 6	
.b.b/d4&4
194&=.0)K++ )r.   