
     i                     :    S r SSKJr  SSKJrJr   " S S\5      rg)zAsync uWSGI protocol parser for ASGI workers.

Reuses the parsing logic from gunicorn/uwsgi/message.py, only async I/O differs.
    )UWSGIRequest)InvalidUWSGIHeaderUnsupportedModifierc                   ^    \ rS rSrSrSS jr\SS j5       rS rS r	S r
SS jrS	 rS
 rSrg)AsyncUWSGIRequest   a6  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   Xl         X l        X0l        X0l        X@l        S U l        S U l        S U l        S U l        SU l	        SU l
        / U l        / U l        S U l        UR                  (       a  SOSU l        SU l        0 U l        SU l        SU l        S U l        SU l        SU l        SU l        g )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        E/var/www/ias/venv/lib/python3.13/site-packages/gunicorn/asgi/uwsgi.py__init__AsyncUWSGIRequest.__init__   s      "$$ 	
	!$g#'        c                 t   #    U " XX45      nUR                  5         UR                  5       I Sh  vN   U$  N7f)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'   parseAsyncUWSGIRequest.parse@   s;     $ #7   
 	!s   -868c                   #    U R                  S5      I Sh  vN n[        U5      S:  a  [        S5      eUS   U l        [        R                  USS S5      nUS   U l        U R                  S:w  a  [        U R                  5      eUS:  aD  U R                  U5      I Sh  vN n[        U5      U:  a  [        S5      eU R                  U5        U R                  5         U R                  5         g N NR7f)	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-   AsyncUWSGIRequest._async_parseW   s      --a00v;?$%899>>&1+x8>>Q%dnn55 a<"44X>>I9~(()@AAY'""$' 1 ?s#   C7C3B
C7"C5#AC75C7c                   #    [        5       n[        U5      U:  aY  U R                  R                  U[        U5      -
  5      I Sh  vN nU(       d  O"UR	                  U5        [        U5      U:  a  MY  [        U5      $  N97f)z'Read exactly size bytes asynchronously.N)	bytearrayr7   r   readextendbytes)r&   sizebufchunks       r'   r6   #AsyncUWSGIRequest._async_read_exacto   sf     k#ho--,,TCH_==EJJu	 #ho
 Sz	 >s   ABB ,B5Bc                     SnSU R                   ;   a#   [        [        U R                   S   5      S5      nXl        Xl        g! [         a    Sn Nf = f)z$Set up body state for async reading.r   CONTENT_LENGTHN)r   maxr8   
ValueErrorr#   r%   )r&   r#   s     r'   r<   "AsyncUWSGIRequest._set_body_readery   sW    t.#!$S9I)J%KQ!O --  #!"#s   "A AAc                    #    U R                   S::  a  g[        XR                   5      nU R                  R                  U5      I Sh  vN nU(       a  U =R                   [	        U5      -  sl         U$  N+7f)zRead body chunk asynchronously.

Args:
    size: Maximum bytes to read

Returns:
    bytes: Body data, empty bytes when body is exhausted
r   r*   N)r%   minr   rC   r7   )r&   rF   to_readdatas       r'   	read_bodyAsyncUWSGIRequest.read_body   sa      1$d001]]''00  CI-  1s   AA5A3,A5c                    #    U R                   S:  a4  U R                  S5      I Sh  vN nU(       d  gU R                   S:  a  M3  gg N 7f)zSDrain unread body data.

Should be called before reusing connection for keepalive.
r       N)r%   rS   )r&   rR   s     r'   
drain_bodyAsyncUWSGIRequest.drain_body   s?     
 ""Q&--D ""Q&-s   %A
AA
A
c                 `    UR                  5       nU R                   H  u  p#X!:X  d  M  Us  $    g)zGet 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_headerAsyncUWSGIRequest.get_header   s.     zz|LLDAy ! r*   )r%   r   r   r$   r#   r   r   r   r    r!   r   r   r   r"   r   r   r   r   r   r   r   r   r   N)r   )rV   )__name__
__module____qualname____firstlineno____doc__r(   classmethodr0   r-   r6   r<   rS   rW   r^   __static_attributes__ r*   r'   r   r      s?    !F  , 0	."r*   r   N)rd   gunicorn.uwsgi.messager   gunicorn.uwsgi.errorsr   r   r   rg   r*   r'   <module>rj      s"   

 0[ [r*   