§
    …ßjý  ã                   óH   — d dl mZmZ d dlmZmZmZ dZ G d„ d¦  «        ZdS )é    )ÚLengthReaderÚBody)ÚInvalidUWSGIHeaderÚUnsupportedModifierÚForbiddenUWSGIRequestiè  c                   óJ   — 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dS )Ú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                             |¦  «         |                      ¦   «          d S )NÚ )r
   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         úI/var/www/html/venv/lib/python3.11/site-packages/gunicorn/uwsgi/message.pyÚ__init__zUWSGIRequest.__init__   s  € ØˆŒØ ˆŒØ"ˆŒØ$ˆÔØ$ˆŒð ˆŒØˆŒØˆŒ	ØˆŒ
ØˆŒØˆŒØˆŒØˆŒØˆŒ	Ø!$¤Ð7�g�g°ˆŒØˆŒð ˆŒØˆŒØˆŒð $(ˆÔ ð ',ˆÔ#ð 	×ÒÑ Ô Ð ð —’˜DœMÑ*Ô*ˆØŒ×Ò˜VÑ$Ô$Ð$Ø×ÒÑÔÐÐÐó    c                 óÌ   — t          | j        dddg¦  «        }t          | j        t          ¦  «        sdS d|v rdS | j        d         |vrt          | j        d         ¦  «        ‚dS )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   sw   € å˜DœHÐ&7¸+ÀuÐ9MÑNÔNˆ	õ ˜$œ.­%Ñ0Ô0ð 	ØˆFð �)ÐÐØˆFàŒ>˜!Ô IÐ-Ð-Ý'¨¬°qÔ(9Ñ:Ô:Ð:ð .Ð-r-   c                 ó   — d| _         dS )z1Force the connection to close after this request.TN)r   )r)   s    r+   Úforce_closezUWSGIRequest.force_closeU   s   € àˆŒˆˆr-   c                 óü  — |                       |d¦  «        }t          |¦  «        dk     rt          d¦  «        ‚|d         | _        t                               |dd…         d¦  «        }|d         | _        | j        dk    rt          | j        ¦  «        ‚|dk    rM|                       ||¦  «        }t          |¦  «        |k     rt          d¦  «        ‚|                      |¦  «         |  	                    ¦   «          dS )	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Ð9à œˆŒÝ—>’> &¨¨1¨¤+¨xÑ8Ô8ˆØ œˆŒð Œ>˜QÒÐÝ% d¤nÑ5Ô5Ð5ð �aŠ<ˆ<Ø×(Ò(¨°8Ñ<Ô<ˆIÝ�9‰~Œ~ Ò(Ð(Ý(Ð)@ÑAÔAÐAØ×Ò˜YÑ'Ô'Ð'ð 	×"Ò"Ñ$Ô$Ð$àˆsr-   c                 ó,   — |                      |¦  «        S )z*Read exactly size bytes from the unreader.)Úread)r)   r   Úsizes      r+   r;   zUWSGIRequest._read_exactt   s   € à�}Š}˜TÑ"Ô"Ð"r-   c                 ó  — d}d}|t          |¦  «        k     �rs|t          k    rt          d¦  «        ‚|dz   t          |¦  «        k    rt          d¦  «        ‚t                               |||dz   …         d¦  «        }|dz  }||z   t          |¦  «        k    rt          d¦  «        ‚||||z   …                              d¦  «        }||z  }|dz   t          |¦  «        k    rt          d¦  «        ‚t                               |||dz   …         d¦  «        }|dz  }||z   t          |¦  «        k    rt          d	¦  «        ‚||||z   …                              d¦  «        }||z  }|| j        |<   |d
z  }|t          |¦  «        k     �°qdS dS )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   s¢  € ð
 ˆØˆ	à•C˜‘I”IŠo‰oØ�NÒ*Ð*Ý(Ð)=Ñ>Ô>Ð>ð �Q‰w�˜T™œÒ"Ð"Ý(Ð)=Ñ>Ô>Ð>Ý—~’~ d¨3¨s°Q©w¨;Ô&7¸ÑBÔBˆHØ�1‰HˆCð �X‰~¥ D¡	¤	Ò)Ð)Ý(¨Ñ9Ô9Ð9Ø�s˜3 ™>Ð)Ô*×1Ò1°)Ñ<Ô<ˆCØ�8‰OˆCð �Q‰w�˜T™œÒ"Ð"Ý(Ð)?Ñ@Ô@Ð@Ý—~’~ d¨3¨s°Q©w¨;Ô&7¸ÑBÔBˆHØ�1‰HˆCð �X‰~¥ D¡	¤	Ò)Ð)Ý(Ð):Ñ;Ô;Ð;Ø˜˜S 8™^Ð+Ô,×3Ò3°IÑ>Ô>ˆEØ�8‰OˆCà#(ˆDŒO˜CÑ Ø˜‰NˆIð; •C˜‘I”IŠo‰oˆoˆoˆoˆor-   c                 ó&  — | j                              dd¦  «        | _        | j                              dd¦  «        | _        | j                              dd¦  «        | _        | j        r| j        ›d| j        ›�| _        n| j        | _        | j                              dd¦  «                             ¦   «         d	v rd
| _        nd| j         v r| j         d         | _        | j                              ¦   «         D ]š\  }}| 	                    d¦  «        r;|dd…          
                    dd¦  «        }| j                             ||f¦  «         ŒU|dk    r| j                             d|f¦  «         Œx|dk    r| j                             d|f¦  «         Œ›dS )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×)Ò)Ð*:¸EÑBÔBˆŒð ”O×'Ò'¨°SÑ9Ô9ˆŒ	Ø”_×(Ò(¨¸Ñ<Ô<ˆŒ
ð Œ:ð 	!Ø"&¤) ) )¨T¬Z¨ZÐ8ˆDŒHˆHà”yˆDŒHð Œ?×Ò˜w¨Ñ+Ô+×1Ò1Ñ3Ô3Ð7JÐJÐJØ!ˆDŒKˆKØ $¤/Ð1Ð1Øœ/Ð*;Ô<ˆDŒKð œ/×/Ò/Ñ1Ô1ð 	?ð 	?‰JˆC�Ø�~Š~˜gÑ&Ô&ð ?à! ! " "œgŸošo¨c°3Ñ7Ô7�Ø”×#Ò# [°%Ð$8Ñ9Ô9Ð9Ð9Ø˜Ò&Ð&Ø”×#Ò# ^°UÐ$;Ñ<Ô<Ð<Ð<ØÐ(Ò(Ð(Ø”×#Ò#Ð%5°uÐ$=Ñ>Ô>Ð>øð	?ð 	?r-   c                 óâ   — d}d| j         v r<	 t          t          | j         d         ¦  «        d¦  «        }n# t          $ r d}Y nw xY wt	          t          | j        |¦  «        ¦  «        | _        dS )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Ö   s�   € àˆð ˜tœÐ.Ð.ð#Ý!$¥S¨¬Ð9IÔ)JÑ%KÔ%KÈQÑ!OÔ!O��øÝð #ð #ð #Ø!"���ð#øøøõ � d¤m°^ÑDÔDÑEÔEˆŒ	ˆ	ˆ	s   �(6 ¶AÁAc                 ó’   — | j         rdS | j                             dd¦  «                             ¦   «         }|dk    rdS |dk    rdS dS )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ã   s^   € àŒ?ð 	Ø�4ð ”_×(Ò(Ð):¸BÑ?Ô?×EÒEÑGÔGˆ
Ø˜Ò Ð Ø�4Ø˜<Ò'Ð'Ø�5ð ˆur-   N)r
   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r,   r%   r6   r&   r;   r?   r@   r(   rr   © r-   r+   r	   r	      s°   € € € € € ðð ð%ð %ð %ð %ðN;ð ;ð ;ðð ð ðð ð ð6#ð #ð #ð%ð %ð %ðN5?ð 5?ð 5?ðnFð Fð Fðð ð ð ð r-   r	   N)	Úgunicorn.http.bodyr   r   Úgunicorn.uwsgi.errorsr   r   r   rI   r	   rw   r-   r+   ú<module>rz      s”   ðð
 2Ð 1Ð 1Ð 1Ð 1Ð 1Ð 1Ð 1ðð ð ð ð ð ð ð ð ð ð €ð_ð _ð _ð _ð _ñ _ô _ð _ð _ð _r-   