
     i                     @    S SK JrJr  S SKJrJrJr  Sr " S S5      rg)    )LengthReaderBody)InvalidUWSGIHeaderUnsupportedModifierForbiddenUWSGIRequesti  c                   R    \ rS rSrSrSS jrS rS rS rS r	S r
S	 rS
 rS rSrg)UWSGIRequest   a  uWSGI protocol request parser.

The uWSGI protocol uses a 4-byte binary header:
- Byte 0: modifier1 (packet type, 0 = WSGI request)
- Bytes 1-2: datasize (16-bit little-endian, size of vars block)
- Byte 3: modifier2 (additional flags, typically 0)

After the header:
1. Vars block (datasize bytes): Key-value pairs containing WSGI environ
   - Each pair: 2-byte key_size (LE) + key + 2-byte val_size (LE) + value
2. Request body (determined by CONTENT_LENGTH in vars)
c                    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        U R-                  5         U R/                  U R                  5      nU R                  R1                  U5        U R3                  5         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_expected_100_continue_check_allowed_ipparseunreadset_body_reader)selfr   r   r   r   unuseds         H/var/www/ias/venv/lib/python3.13/site-packages/gunicorn/uwsgi/message.py__init__UWSGIRequest.__init__   s     "$$ 	
	!$g  $(  ',# 	  DMM*V$    c                     [        U R                  SSS/5      n[        U R                  [        5      (       d  gSU;   a  gU R                  S   U;  a  [        U R                  S   5      eg)z(Verify source IP is in the allowed list.uwsgi_allow_ipsz	127.0.0.1z::1N*r   )getattrr   
isinstancer   tupler   )r*   	allow_ipss     r,   r&   UWSGIRequest._check_allowed_ipF   sg    DHH&7+u9MN	 $..%00 )>>!I-'q(9:: .r/   c                     SU l         g)z1Force the connection to close after this request.TN)r    )r*   s    r,   force_closeUWSGIRequest.force_closeU   s	    r/   c                    U R                  US5      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:  a<  U R                  X5      n[        U5      U:  a  [        S5      eU R                  U5        U R                  5         g)	z)Parse uWSGI packet header and vars block.   zincomplete headerr   r      littlezincomplete vars blockr/   )
_read_exactlenr   r"   int
from_bytesr#   r   _parse_vars_extract_request_info)r*   r   headerdatasize	vars_datas        r,   r'   UWSGIRequest.parseY   s     !!(A.v;?$%899>>&1+x8 >>Q%dnn55 a<((<I9~(()@AAY' 	""$r/   c                 $    UR                  U5      $ )z*Read exactly size bytes from the unreader.)read)r*   r   sizes      r,   r?   UWSGIRequest._read_exactt   s    }}T""r/   c                 j   SnSnU[        U5      :  Ga  U[        :  a  [        S5      eUS-   [        U5      :  a  [        S5      e[        R	                  XUS-    S5      nUS-  nX$-   [        U5      :  a  [        S5      eXX$-    R                  S5      nX$-  nUS-   [        U5      :  a  [        S5      e[        R	                  XUS-    S5      nUS-  nX&-   [        U5      :  a  [        S	5      eXX&-    R                  S5      nX&-  nXpR                  U'   US
-  nU[        U5      :  a  GM  gg)zrParse uWSGI vars block into key-value pairs.

Format: key_size (2 bytes LE) + key + val_size (2 bytes LE) + value
r   ztoo many variables   ztruncated key sizer>   ztruncated keyzlatin-1ztruncated value sizeztruncated valuer   N)r@   MAX_UWSGI_VARSr   rA   rB   decoder!   )r*   datapos	var_countkey_sizekeyval_sizevalues           r,   rC   UWSGIRequest._parse_varsx   sD   
 	CIoN*()=>> QwT"()=>>~~dsQw&7BH1HC ~D	)(993>*11)<COC QwT"()?@@~~dsQw&7BH1HC ~D	)():;;S^,33I>EOC#(OOC NI; CIoor/   c                 t   U R                   R                  SS5      U l        U R                   R                  SS5      U l        U R                   R                  SS5      U l        U R                  (       a#  U R                  < SU R                  < 3U l        OU R                  U l        U R                   R                  SS5      R                  5       S	;   a  S
U l        O$SU R                   ;   a  U R                   S   U l        U R                   R                  5        H  u  pUR                  S5      (       a3  USS R                  SS5      nU R                  R                  X245        MN  US:X  a  U R                  R                  SU45        Ms  US:X  d  M{  U R                  R                  SU45        M     g)a  Extract HTTP request info from uWSGI vars.

Header Mapping (CGI/WSGI to HTTP):

The uWSGI protocol passes HTTP headers using CGI-style environment
variable naming. This method converts them back to HTTP header format:

- HTTP_* vars: Strip 'HTTP_' prefix, replace '_' with '-'
  Example: HTTP_X_FORWARDED_FOR -> X-FORWARDED-FOR
  Example: HTTP_ACCEPT_ENCODING -> ACCEPT-ENCODING

- CONTENT_TYPE: Mapped directly to CONTENT-TYPE header
  (CGI spec excludes HTTP_ prefix for this header)

- CONTENT_LENGTH: Mapped directly to CONTENT-LENGTH header
  (CGI spec excludes HTTP_ prefix for this header)

Note: The underscore-to-hyphen conversion is lossy. Headers that
originally contained underscores (e.g., X_Custom_Header) cannot be
distinguished from hyphenated headers (X-Custom-Header) after
passing through nginx/uWSGI. This is a CGI/WSGI specification
limitation, not specific to this implementation.
REQUEST_METHODGET	PATH_INFO/QUERY_STRINGr   ?HTTPS)on1truer   zwsgi.url_schemeHTTP_   N_-CONTENT_TYPEzCONTENT-TYPECONTENT_LENGTHzCONTENT-LENGTH)r!   getr   r   r   r   lowerr   items
startswithreplacer   append)r*   rU   rW   header_names       r,   rD   "UWSGIRequest._extract_request_info   sU   2 oo))*:EB OO''S9	__((<
 ::"&))TZZ8DHyyDH ??w+1137JJ!DK$//1//*;<DK ////1JC~~g&&!!"gooc37##[$89&##^U$;<((##%5u$=> 2r/   c                     SnSU R                   ;   a#   [        [        U R                   S   5      S5      n[	        [        U R                  U5      5      U l        g! [         a    Sn N3f = f)z/Set up the body reader based on CONTENT_LENGTH.r   ri   N)r!   maxrA   
ValueErrorr   r   r   r   )r*   content_lengths     r,   r)   UWSGIRequest.set_body_reader   sd     t.#!$S9I)J%KQ!O dmm^DE	  #!"#s   "A A*)A*c                     U R                   (       a  gU R                  R                  SS5      R                  5       nUS:X  a  gUS:X  a  gg)z@Determine if the connection should be closed after this request.THTTP_CONNECTIONr   closez
keep-aliveF)r    r!   rj   rk   )r*   
connections     r,   should_closeUWSGIRequest.should_close   sI    ?? __(():B?EEG
 <' r/   )r%   r   r   r   r   r   r"   r#   r    r   r   r$   r   r   r   r   r   r   r   r!   r   N)r   )__name__
__module____qualname____firstlineno____doc__r-   r&   r9   r'   r?   rC   rD   r)   r{   __static_attributes__ r/   r,   r	   r	      s8    %N;6#%N5?nFr/   r	   N)	gunicorn.http.bodyr   r   gunicorn.uwsgi.errorsr   r   r   rO   r	   r   r/   r,   <module>r      s'   
 2  _ _r/   