Ë
    ×Õ°j“  ã                   ó:   — d Z ddlmZ ddlmZmZ  G d„ de«      Zy)z€Async uWSGI protocol parser for ASGI workers.

Reuses the parsing logic from gunicorn/uwsgi/message.py, only async I/O differs.
é    )ÚUWSGIRequest)ÚInvalidUWSGIHeaderÚUnsupportedModifierc                   óP   — e Zd ZdZdd„Zedd„«       Zd„ Zd„ Zd„ Z	dd„Z
d„ Zd	„ Zy
)ÚAsyncUWSGIRequestaR  Async version of UWSGIRequest.

    Reuses all parsing logic from the sync version, only async I/O differs.
    The following methods are reused from the parent class:
    - _parse_vars() - pure parsing, no I/O
    - _extract_request_info() - pure transformation
    - _check_allowed_ip() - no I/O
    - should_close() - simple logic
    c                 ób  — || _         || _        || _        || _        || _        d | _        d | _        d | _        d | _        d| _	        d| _
        g | _        g | _        d | _        |j                  rdnd| _        d| _        i | _        d| _        d| _        d | _        d| _        d| _        d| _        y )NÚ )é   r
   ÚhttpsÚhttpFr   )ÚcfgÚunreaderÚ	peer_addrÚremote_addrÚ
req_numberÚmethodÚuriÚpathÚqueryÚfragmentÚversionÚheadersÚtrailersÚbodyÚis_sslÚschemeÚ
must_closeÚ
uwsgi_varsÚ	modifier1Ú	modifier2Úproxy_protocol_infoÚcontent_lengthÚchunkedÚ_body_remaining)Úselfr   r   r   r   s        úI/var/www/mission/venv/lib/python3.12/site-packages/gunicorn/asgi/uwsgi.pyÚ__init__zAsyncUWSGIRequest.__init__   sµ   € ð ˆŒØ ˆŒØ"ˆŒØ$ˆÔØ$ˆŒð ˆŒØˆŒØˆŒ	ØˆŒ
ØˆŒØˆŒØˆŒØˆŒØˆŒ	Ø!$§¢‘g°ˆŒØˆŒØˆŒØˆŒØˆŒØ#'ˆÔ ð  ˆÔØˆŒØ ˆÕó    c              ƒ   óx   K  —  | ||||«      }|j                  «        |j                  «       ƒ d{  –—†  |S 7 Œ­w)a  Parse a uWSGI request asynchronously.

        Args:
            cfg: gunicorn config object
            unreader: AsyncUnreader instance
            peer_addr: client address tuple
            req_number: request number on this connection (for keepalive)

        Returns:
            AsyncUWSGIRequest: Parsed request object

        Raises:
            InvalidUWSGIHeader: If the uWSGI header is malformed
            UnsupportedModifier: If modifier1 is not 0
            ForbiddenUWSGIRequest: If source IP is not allowed
        N)Ú_check_allowed_ipÚ_async_parse)Úclsr   r   r   r   Úreqs         r&   ÚparsezAsyncUWSGIRequest.parse@   s@   è ø€ ñ$ �#�x ¨JÓ7ˆØ×ÑÔØ×ÑÓ × Ð Øˆ
ð 	!ús   ‚/:±8²:c              ƒ   óê  K  — | j                  d«      ƒ d{  –—† }t        |«      dk  rt        d«      ‚|d   | _        t        j                  |dd d«      }|d   | _        | j                  dk7  rt        | j                  «      ‚|dkD  rC| j                  |«      ƒ d{  –—† }t        |«      |k  rt        d«      ‚| j                  |«       | j                  «        | j                  «        y7 Œ×7 ŒQ­w)	z=Async version of parse() - reads data then uses sync parsing.é   Nzincomplete headerr   r
   é   Úlittlezincomplete vars block)Ú_async_read_exactÚlenr   r   ÚintÚ
from_bytesr    r   Ú_parse_varsÚ_extract_request_infoÚ_set_body_reader)r%   ÚheaderÚdatasizeÚ	vars_datas       r&   r+   zAsyncUWSGIRequest._async_parseW   sÞ   è ø€ ð ×-Ñ-¨aÓ0×0ˆÜˆv‹;˜Š?Ü$Ð%8Ó9Ð9à ™ˆŒÜ—>‘> &¨¨1 +¨xÓ8ˆØ ™ˆŒà�>‰>˜QÒÜ% d§n¡nÓ5Ð5ð �aŠ<Ø"×4Ñ4°XÓ>×>ˆIÜ�9‹~ Ò(Ü(Ð)@ÓAÐAØ×Ñ˜YÔ'à×"Ñ"Ô$Ø×ÑÕð' 1øð ?ús#   ‚C3—C/˜BC3ÂC1Â AC3Ã1C3c              ƒ   ó  K  — t        «       }t        |«      |k  r]| j                  j                  |t        |«      z
  «      ƒ d{  –—† }|s	 t        |«      S |j	                  |«       t        |«      |k  rŒ]t        |«      S 7 Œ=­w)z'Read exactly size bytes asynchronously.N)Ú	bytearrayr4   r   ÚreadÚextendÚbytes)r%   ÚsizeÚbufÚchunks       r&   r3   z#AsyncUWSGIRequest._async_read_exacto   ss   è ø€ ä‹kˆÜ�#‹h˜ŠoØŸ-™-×,Ñ,¨T´C¸³H©_Ó=×=ˆEÙØä�S‹zÐð �J‰J�uÔô	 �#‹h˜‹oô
 �S‹zÐð	 >ús   ‚ABÁBÁ1BÁ8Bc                 ó¨   — d}d| j                   v r#	 t        t        | j                   d   «      d«      }|| _        || _        y# t        $ r d}Y Œw xY w)z$Set up body state for async reading.r   ÚCONTENT_LENGTHN)r   Úmaxr5   Ú
ValueErrorr"   r$   )r%   r"   s     r&   r9   z"AsyncUWSGIRequest._set_body_readery   s[   € àˆØ˜tŸ™Ñ.ð#Ü!$¤S¨¯©Ð9IÑ)JÓ%KÈQÓ!O�ð -ˆÔØ-ˆÕøô ò #Ø!"’ð#ús   ’"A ÁAÁAc              ƒ   óä   K  — | j                   dk  ryt        || j                   «      }| j                  j                  |«      ƒ d{  –—† }|r| xj                   t	        |«      z  c_         |S 7 Œ&­w)z²Read body chunk asynchronously.

        Args:
            size: Maximum bytes to read

        Returns:
            bytes: Body data, empty bytes when body is exhausted
        r   r(   N)r$   Úminr   r?   r4   )r%   rB   Úto_readÚdatas       r&   Ú	read_bodyzAsyncUWSGIRequest.read_body„   sd   è ø€ ð ×Ñ 1Ò$ØÜ�d˜D×0Ñ0Ó1ˆØ—]‘]×'Ñ'¨Ó0×0ˆÙØ× Ò ¤C¨£IÑ-Õ Øˆð 1ús   ‚AA0ÁA.Á'A0c              ƒ   óˆ   K  — | j                   dkD  r-| j                  d«      ƒ d{  –—† }|sy| j                   dkD  rŒ,yy7 Œ­w)zcDrain unread body data.

        Should be called before reusing connection for keepalive.
        r   é    N)r$   rM   )r%   rL   s     r&   Ú
drain_bodyzAsyncUWSGIRequest.drain_body•   s@   è ø€ ð
 ×"Ñ" QÒ&ØŸ™¨Ó-×-ˆDÙØð ×"Ñ" QÕ&Ø-ús   ‚$A¦A §A¾Ac                 ó^   — |j                  «       }| j                  D ]  \  }}||k(  sŒ|c S  y)z«Get header by name (case-insensitive).

        Args:
            name: Header name to look up

        Returns:
            Header value if found, None otherwise
        N)Úupperr   )r%   ÚnameÚhÚvs       r&   Ú
get_headerzAsyncUWSGIRequest.get_headerŸ   s7   € ð �z‰z‹|ˆØ—L‘Lò 	‰DˆAˆqØ�D‹yØ’ð	ð r(   N)r
   )rO   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r'   Úclassmethodr.   r+   r3   r9   rM   rP   rV   © r(   r&   r   r      s?   „ ñó!ðF òó ðò, ò0ò	.óò"ór(   r   N)rZ   Úgunicorn.uwsgi.messager   Úgunicorn.uwsgi.errorsr   r   r   r\   r(   r&   ú<module>r_      s"   ðñ
õ
 0÷ô[˜õ [r(   