Ë
    ×Õ°jý  ã                   ó@   — d dl mZmZ d dlmZmZmZ dZ G d„ d«      Zy)é    )ÚLengthReaderÚBody)ÚInvalidUWSGIHeaderÚUnsupportedModifierÚForbiddenUWSGIRequestiè  c                   óH   — e Zd ZdZdd„Zd„ Zd„ Zd„ Zd„ Zd„ Z	d„ Z
d	„ Zd
„ Zy)ÚUWSGIRequestaù  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                 óò  — || _         || _        || _        || _        || _        d | _        d | _        d | _        d | _        d| _	        d| _
        g | _        g | _        d | _        |j                  rdnd| _        d| _        i | _        d| _        d| _        d | _        d| _        | j-                  «        | j/                  | j                  «      }| j                  j1                  |«       | j3                  «        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Ú_expected_100_continueÚ_check_allowed_ipÚparseÚunreadÚset_body_reader)Úselfr   r   r   r   Úunuseds         úL/var/www/mission/venv/lib/python3.12/site-packages/gunicorn/uwsgi/message.pyÚ__init__zUWSGIRequest.__init__   sè   € ØˆŒØ ˆŒØ"ˆŒØ$ˆÔØ$ˆŒð ˆŒØˆŒØˆŒ	ØˆŒ
ØˆŒØˆŒØˆŒØˆŒØˆŒ	Ø!$§¢‘g°ˆŒØˆŒð ˆŒØˆŒØˆŒð $(ˆÔ ð ',ˆÔ#ð 	×ÑÔ ð —‘˜DŸM™MÓ*ˆØ�‰×Ñ˜VÔ$Ø×ÑÕó    c                 óÈ   — t        | j                  dddg«      }t        | j                  t        «      syd|v ry| j                  d   |vrt        | j                  d   «      ‚y)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%   zUWSGIRequest._check_allowed_ipF   sd   € ä˜DŸH™HÐ&7¸+ÀuÐ9MÓNˆ	ô ˜$Ÿ.™.¬%Ô0Øð �)ÑØà�>‰>˜!Ñ IÑ-Ü'¨¯©°qÑ(9Ó:Ð:ð .r-   c                 ó   — d| _         y)z1Force the connection to close after this request.TN)r   )r)   s    r+   Úforce_closezUWSGIRequest.force_closeU   s	   € àˆ�r-   c                 óž  — | j                  |d«      }t        |«      dk  rt        d«      ‚|d   | _        t        j                  |dd d«      }|d   | _        | j                  dk7  rt        | j                  «      ‚|dkD  r<| j                  ||«      }t        |«      |k  rt        d«      ‚| j                  |«       | j                  «        y)	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&   zUWSGIRequest.parseY   sÈ   € ð ×!Ñ! (¨AÓ.ˆÜˆv‹;˜Š?Ü$Ð%8Ó9Ð9à ™ˆŒÜ—>‘> &¨¨1 +¨xÓ8ˆØ ™ˆŒð �>‰>˜QÒÜ% d§n¡nÓ5Ð5ð �aŠ<Ø×(Ñ(¨°8Ó<ˆIÜ�9‹~ Ò(Ü(Ð)@ÓAÐAØ×Ñ˜YÔ'ð 	×"Ñ"Ô$àr-   c                 ó$   — |j                  |«      S )z*Read exactly size bytes from the unreader.)Úread)r)   r   Úsizes      r+   r;   zUWSGIRequest._read_exactt   s   € à�}‰}˜TÓ"Ð"r-   c                 óp  — d}d}|t        |«      k  �r#|t        k\  rt        d«      ‚|dz   t        |«      kD  rt        d«      ‚t        j	                  |||dz    d«      }|dz  }||z   t        |«      kD  rt        d«      ‚||||z    j                  d«      }||z  }|dz   t        |«      kD  rt        d«      ‚t        j	                  |||dz    d«      }|dz  }||z   t        |«      kD  rt        d	«      ‚||||z    j                  d«      }||z  }|| j                  |<   |d
z  }|t        |«      k  r�Œ"yy)z‚Parse 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   r=   r>   Údecoder    )r)   ÚdataÚposÚ	var_countÚkey_sizeÚkeyÚval_sizeÚvalues           r+   r?   zUWSGIRequest._parse_varsx   sX  € ð
 ˆØˆ	à”C˜“I‹oØœNÒ*Ü(Ð)=Ó>Ð>ð �Q‰wœ˜T›Ò"Ü(Ð)=Ó>Ð>Ü—~‘~ d¨3¨s°Q©wÐ&7¸ÓBˆHØ�1‰HˆCð �X‰~¤ D£	Ò)Ü(¨Ó9Ð9Ø�s˜3 ™>Ð*×1Ñ1°)Ó<ˆCØ�8‰OˆCð �Q‰wœ˜T›Ò"Ü(Ð)?Ó@Ð@Ü—~‘~ d¨3¨s°Q©wÐ&7¸ÓBˆHØ�1‰HˆCð �X‰~¤ D£	Ò)Ü(Ð):Ó;Ð;Ø˜˜S 8™^Ð,×3Ñ3°IÓ>ˆEØ�8‰OˆCà#(ˆD�O‰O˜CÑ Ø˜‰NˆIð; ”C˜“IŽor-   c                 óJ  — | j                   j                  dd«      | _        | j                   j                  dd«      | _        | j                   j                  dd«      | _        | j                  r!| j                  ›d| j                  ›�| _        n| j                  | _        | j                   j                  dd«      j                  «       d	v rd
| _        n"d| j                   v r| j                   d   | _        | j                   j                  «       D ]�  \  }}|j                  d«      r3|dd j                  dd«      }| j                  j                  ||f«       ŒJ|dk(  r| j                  j                  d|f«       Œm|dk(  sŒs| j                  j                  d|f«       Œ‘ y)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)   rO   rQ   Úheader_names       r+   r@   z"UWSGIRequest._extract_request_infoŸ   s[  € ð2 —o‘o×)Ñ)Ð*:¸EÓBˆŒð —O‘O×'Ñ'¨°SÓ9ˆŒ	Ø—_‘_×(Ñ(¨¸Ó<ˆŒ
ð �:Š:Ø"&§)£)¨T¯ZªZÐ8ˆD�Hà—y‘yˆDŒHð �?‰?×Ñ˜w¨Ó+×1Ñ1Ó3Ð7JÑJØ!ˆD�KØ $§/¡/Ñ1ØŸ/™/Ð*;Ñ<ˆDŒKð Ÿ/™/×/Ñ/Ó1ò 	?‰JˆC�Ø�~‰~˜gÔ&à! ! "˜gŸo™o¨c°3Ó7�Ø—‘×#Ñ# [°%Ð$8Õ9Ø˜Ò&Ø—‘×#Ñ# ^°UÐ$;Õ<ØÐ(Ó(Ø—‘×#Ñ#Ð%5°uÐ$=Õ>ñ	?r-   c                 óÔ   — d}d| j                   v r#	 t        t        | j                   d   «      d«      }t	        t        | j                  |«      «      | _        y# t        $ r d}Y Œ2w xY w)z/Set up the body reader based on CONTENT_LENGTH.r   rb   N)r    Úmaxr=   Ú
ValueErrorr   r   r   r   )r)   Úcontent_lengths     r+   r(   zUWSGIRequest.set_body_readerÖ   sd   € àˆð ˜tŸ™Ñ.ð#Ü!$¤S¨¯©Ð9IÑ)JÓ%KÈQÓ!O�ô œ d§m¡m°^ÓDÓEˆ�	øô ò #Ø!"’ð#ús   ’"A ÁA'Á&A'c                 óŠ   — | j                   ry| j                  j                  dd«      j                  «       }|dk(  ry|dk(  ryy)z@Determine if the connection should be closed after this request.TÚHTTP_CONNECTIONr   Úclosez
keep-aliveF)r   r    rc   rd   )r)   Ú
connections     r+   Úshould_closezUWSGIRequest.should_closeã   sI   € à�?Š?Øð —_‘_×(Ñ(Ð):¸BÓ?×EÑEÓGˆ
Ø˜Ò ØØ˜<Ò'Øð r-   N)r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r,   r%   r6   r&   r;   r?   r@   r(   rr   © r-   r+   r	   r	      s8   „ ñó%òN;òòò6#ò%òN5?ònFór-   r	   N)	Úgunicorn.http.bodyr   r   Úgunicorn.uwsgi.errorsr   r   r   rI   r	   rw   r-   r+   ú<module>rz      s'   ð÷
 2÷ñ ð €÷_ò _r-   