
    AҐix_                        d dl mZ d dlZd dlZd dlZd dlZd dlmZmZm	Z	m
Z
 d dlmZmZmZmZmZmZmZmZmZmZmZ d dlmZmZmZ d dlmZ d dlmZmZ dZ G d	 d
e      Z G d de      Z  G d de      Z!dZ"dZ#dZ$dZ% ejL                  d ejN                  e%      z        Z( ejL                  d      Z) ejL                  d      Z* ejL                  d      Z+d Z, G d d      Z- G d de-      Z.y)    )IntEnumN)ChunkedReaderLengthReader	EOFReaderBody)InvalidHeaderInvalidHeaderName
NoMoreDataInvalidRequestLineInvalidRequestMethodInvalidHTTPVersionLimitRequestLineLimitRequestHeadersUnsupportedTransferCodingObsoleteFoldingExpectationFailed)InvalidProxyLineInvalidProxyHeaderForbiddenProxyRequest)InvalidSchemeHeaders)bytes_to_strsplit_request_uris   

 
QUIT
c                       e Zd ZdZdZdZy)	PPCommandzPROXY protocol v2 commands.r      N)__name__
__module____qualname____doc__LOCALPROXY     N/var/www/descvideos/venv/lib/python3.12/site-packages/gunicorn/http/message.pyr   r      s    %EEr#   r   c                        e Zd ZdZdZdZdZdZy)PPFamilyz#PROXY protocol v2 address families.r   r         N)r   r   r   r   UNSPECINETINET6UNIXr"   r#   r$   r&   r&   "   s    -FDEDr#   r&   c                       e Zd ZdZdZdZdZy)
PPProtocolz&PROXY protocol v2 transport protocols.r   r   r'   N)r   r   r   r   r)   STREAMDGRAMr"   r#   r$   r.   r.   *   s    0FFEr#   r.   i  i   z!#$%&'*+-.^_`|~z[%s0-9a-zA-Z]+z[a-z#]zHTTP/(\d)\.(\d)z[\0\r\n]c                 r    d|v ry	 t        j                  |       }|D ]  }||v s y y# t        $ r Y yw xY w)zCheck if IP address is in the allow list.

    Args:
        ip_str: The IP address string to check
        allow_list: The original allow list (strings, may contain "*")
        networks: Pre-computed ipaddress.ip_network objects from config
    *TF)	ipaddress
ip_address
ValueError)ip_str
allow_listnetworksipnetworks        r$   _ip_in_allow_listr;   >   sX     j!!&)  =   s   * 	66c                   2    e Zd Zd Zd Zd ZddZd Zd Zy)	Messagec                 t   || _         || _        || _        || _        d | _        g | _        g | _        d | _        |j                  rdnd| _	        d| _
        d| _        |j                  | _        | j                  dk  s| j                  t        kD  rt        | _        |j                  | _        | j                  dk  rt        | _        | j                  xs t        }| j                  |dz   z  dz   | _        | j#                  | j                        }| j                  j%                  |       | j'                          y )NhttpshttpFr   r'      )cfgunreader	peer_addrremote_addrversionheaderstrailersbodyis_sslscheme
must_close_expected_100_continuelimit_request_fieldsMAX_HEADERSlimit_request_field_sizeDEFAULT_MAX_HEADERFIELD_SIZEmax_buffer_headersparseunreadset_body_reader)selfrB   rC   rD   max_header_field_sizeunuseds         r$   __init__zMessage.__init__S   s    "$	!$g&+# %($<$<!%%*,,{:(3D%(+(D(D%((1,,HD) !% = = ]A]"&";";"Q&#(*+#, DMM*V$r#   c                     d| _         y )NT)rL   rV   s    r$   force_closezMessage.force_closer   s	    r#   c                     t               N)NotImplementedError)rV   rC   s     r$   rS   zMessage.parseu   s    !##r#   c                    | j                   }g }|j                  d      D cg c]  }t        |       }}d}i }g }	|rndt        | j                  t
              r2t        | j                  d   |j                  |j                               r|j                  }|j                  }	|rt        |      | j                  k\  rt        d      |j                  d      }
t        |
      t        d      z   }|
j                  d      dk  rt!        |
      |
j                  dd      \  }}| j                   j"                  r|j%                  d      }t&        j)                  |      st+        |      |j-                         }|j/                  d      g}|r|d   j1                  d	      r| j                   j2                  st5        |      |j                  d      }
|t        |
      t        d      z   z  }|| j6                  cxkD  rdkD  rt        d
       |j9                  |
j/                  d             |r|d   j1                  d	      rdj;                  |      }t<        j?                  |      rt!        |      || j6                  cxkD  rdkD  rt        d
       |s;|dk(  r6|jA                         dk(  r| jB                  dk  rnd| _"        ntG        |      ||v r2|||   k(  }|rdnd}|r|| jH                  k7  rtK               d}|| _$        d|v rI||	v sd|	v rn@| j                   jL                  dk(  rn&| j                   jL                  dk(  rt+        |      |j9                  ||f       |r|S c c}w )N   
Fr   zlimit request headers fieldsz
:r    	) 	z!limit request headers fields sizez	 rd   EXPECTz100-continuer   r   Tr?   r@   _r2   	dangerousdrop)'rB   splitr   
isinstancerD   tupler;   forwarded_allow_ipsforwarded_allow_networkssecure_scheme_headersforwarder_headerslenrN   r   popfindr   strip_header_spacesrstripTOKEN_RE	fullmatchr	   upperstrip
startswithpermit_obsolete_foldingr   rP   appendjoin!RFC9110_5_5_INVALID_AND_DANGEROUSsearchlowerrF   rM   r   rK   r   
header_map)rV   datafrom_trailerrB   rG   linelinesscheme_headerrp   rq   currheader_lengthnamevaluesecurerK   s                   r$   parse_headerszMessage.parse_headersx   s[   hh 15

70CDd#DD  " T^^U3"4>>!#4c6M6M#&#?#?#AC$'$=$=! # 5 5 7|t888)*HII 99Q<DIF3Myy~"#D))**S!,KD%xx++{{5)%%d+'-- ::<D[['(E E!H//<xx77)$//yy|TS[!88 4#@#@D1D- /< = = E TZZ./ E!H//< HHUOE077>#D))t<<@q@)*MNN A  DH$4 ;;=N2||f, 6:3 ,E22,,"7"==$* ,244$(M"(DK d{,,7H0HXX((K7XX((F2  ,D11NND%=)o r W Es   M3c                    d}d }| j                   D ]  \  }}|dk(  r|t        d|       |}|dk(  s#|j                  d      D cg c]  }|j                          }}|D ]  }|j	                         dk(  r|rt        d|       d}(|j	                         dk(  r|s>t        d|       |j	                         d	v r |rt        d|       | j                          }t        |        |rP| j                  d
k  rt        d|       |t        d|       t        t        | | j                              | _        y |k	 t        |      j                         rt        |      }nt        d|       	 |dk  rt        d|       t        t!        | j                  |            | _        y t        t#        | j                              | _        y c c}w # t        $ r t        d|       w xY w)NFzCONTENT-LENGTH)reqzTRANSFER-ENCODING,chunkedTidentity)compressdeflategziprg   r   )rG   r   rk   rz   r   r\   r   rF   r   r   rC   rI   str	isnumericintr5   r   r   )rV   r   content_lengthr   r   vvalsvals           r$   rU   zMessage.set_body_reader   s   !\\ 	?MT5''!-'(8dCC!&,, ,1;;s+;<a	<< ?Cyy{i/""/0C"NN"&
2 #"/0C"NN(GG""/0C"NN((*7>>#?	?8  ||f$#$7TBB) $$4$??]4?@DI'@~&002%(%8N'(8dCC # !#$4$??\$--HIDIYt}}56DI] =L  @#$4$??@s   G2G G,c                     | j                   ry| j                  D ]9  \  }}|dk(  s|j                         j                  d      }|dk(  r y|dk(  r y n | j                  dk  S )NT
CONNECTIONrc   closez
keep-aliveFr   r   )rL   rG   r   rz   rF   )rV   hr   s      r$   should_closezMessage.should_close&  sh    ??ll 	FQL GGIOOE*<,& 	 ||v%%r#   NF)	r   r   r   rY   r\   rS   r   rU   r   r"   r#   r$   r=   r=   R   s#    >$pd:7x&r#   r=   c                   l     e Zd Zd fd	ZddZd ZddZddZd Zd Z	d Z
d	 Zd
 Zd Z fdZ xZS )Requestc                    d | _         d | _        d | _        d | _        d | _        |j
                  | _        | j
                  dk  s| j
                  t        k\  rt        | _        || _        d | _        t        | )  |||       y Nr   )methoduripathqueryfragmentlimit_request_lineMAX_REQUEST_LINE
req_numberproxy_protocol_infosuperrY   )rV   rB   rC   rD   r   	__class__s        r$   rY   zRequest.__init__5  s{    	
 #&"8"8##a'**.>>&6D#$#' h	2r#   c                     |j                         }|s%|r
t               t        |j                               |j	                  |       y r^   )readStopIterationr
   getvaluewriterV   rC   bufstopr   s        r$   get_datazRequest.get_dataF  s7    }}#o%S\\^,,		$r#   c                    t               }| j                  ||d       | j                  j                  }|dk7  r"| j                  dk(  r| j                  |||      }| j                  ||| j                        \  }}| j                  |       t        |      }|d d dk(  }	 |j                  d      }|d d dk(  }|dk  rB|s@| j                  ||       t        |      }t        |      | j                  kD  rt        d	      nb|r| j                  j                  |dd         y
| j!                  |d | d      | _        ||dz   d  }|S )NT)r   offr   r'   ra   s   

r   zmax buffer headersr#   F)r   rA   )	bytearray	read_intorB   proxy_protocolr   _handle_proxy_protocol	read_liner   parse_request_linebytesrt   rr   rR   r   rC   rT   r   rG   )	rV   rC   r   moder   r   doneidxrets	            r$   rS   zRequest.parseN  sQ   kx40 xx&&5=T__1--hTBC NN8S$2I2IJ	c% SzBQx7"))K(C8w&DQwtx-Szt9t666-.BCC  MM  ab*))$t*5)I378n
r#   c                     |j                         }|s |r
t               t        t        |            |j	                  |       y)z7Read data from unreader and append to bytearray buffer.N)r   r   r
   r   extendr   s        r$   r   zRequest.read_intou  s6    }}#o%U3Z((

4r#   c                 B   t        |      }	 |j                  d      }|dk\  r||cxkD  rdkD  rn nt        ||      nMt        |      dz
  |cxkD  rdkD  rn nt        t        |      |      | j	                  ||       t        |      }~|d| t        ||dz   d       fS )z<Read a line from buffer, returning (line, remaining_buffer).ra   r   r'   N)r   rt   r   rr   r   r   )rV   rC   r   limitr   r   s         r$   r   zRequest.read_line~  s    Sz))G$Cax??*3664y1}u(q(&s4y%88NN8S):D  Tc
$sQwx.)+ 	+r#   c                     t        |      |k  r!| j                  ||       t        |      |k  r!t        |d|       t        ||d       fS )z.Read exactly count bytes from buffer/unreader.N)rr   r   r   r   )rV   rC   r   counts       r$   
read_byteszRequest.read_bytes  sK    #hNN8S) #hS%[!9S[#999r#   c                 $   t        |      dk  r!| j                  ||       t        |      dk  r!|dv r.|dd t        k(  r"| j                          | j	                  ||      S |dv r*|dd dk(  r"| j                          | j                  ||      S |S )ztHandle PROXY protocol detection and parsing.

        Returns the buffer with proxy protocol data consumed.
           )v2autoN)v1r      s   PROXY )rr   r   PP_V2_SIGNATUREproxy_protocol_access_check_parse_proxy_protocol_v2_parse_proxy_protocol_v1)rV   rC   r   r   s       r$   r   zRequest._handle_proxy_protocol  s     #hmNN8S) #hm >!c#2h/&A,,.003?? >!c"1g&:,,.003?? 
r#   c                     t        | j                  t              r_t        | j                  d   | j                  j
                  | j                  j                               st        | j                  d         yy)z2Check if proxy protocol is allowed from this peer.r   N)rl   rD   rm   r;   rB   proxy_allow_ipsproxy_allow_networksr   r[   s    r$   r   z#Request.proxy_protocol_access_check  s_    t~~u-%dnnQ&79Q9Q&*hh&C&C&EG'q(9::G .r#   c                    t        |      }d|vr"| j                  ||       t        |      }d|vr"|j                  d      }t        |d|       }t	        ||dz   d       }|j                  d      }t        |      dk7  rt        |      |d   }|d   }	|d   }
|dvrt        d	|z        |d
k(  rJ	 t        j                  t        j                  |	       t        j                  t        j                  |
       nN|dk(  rI	 t        j                  t        j                  |	       t        j                  t        j                  |
       	 t        |d         }t        |d         }d|cxk  rdk  rn nd|cxk  rdk  sn t        d|z        ||	||
|d| _        |S # t        $ r t        |      w xY w# t        $ r t        |      w xY w# t        $ r t        d|z        w xY w)z`Parse PROXY protocol v1 (text format).

        Returns buffer with v1 header consumed.
        ra   Nr'   rd   r   r   r(   )TCP4TCP6zprotocol '%s' not supportedr   r   rA      zinvalid port %sr   i  r   client_addrclient_port
proxy_addr
proxy_port)r   r   rt   r   r   rk   rr   r   socket	inet_ptonAF_INETOSErrorAF_INET6r   r5   r   )rV   rC   r   r   r   r   	remainingbitsprotos_addrd_addrs_portd_ports                r$   r   z Request._parse_proxy_protocol_v1  s    SzT!NN8S):D T! ii D#J'd378n-	zz#t9>"4(( Qaa (("#@5#HIIF?-  8  8 f_-  &9  &9	=a\Fa\F f%%A,@5,@"#4t#;<< $!!  $
  7  -&t,,-  -&t,,-  	="#4t#;<<	=s&   3AF AF7 G F47GG'c                    t        |      dk  r!| j                  ||       t        |      dk  r!|d   }|d   }t        j                  dt	        |dd             d   }|dz  dz	  }|d	k7  rt        d
|z        |dz  }|t        j                  t        j                  fvrt        d|z        d|z   }t        |      |k  r!| j                  ||       t        |      |k  r!|t        j                  k(  rdddddd| _	        t        ||d       S |dz  dz	  }	|dz  }
|
t        j                  k7  rt        d      t	        |dd|z          }|	t        j                  k(  r|dk  rt        d      t        j                   t        j"                  |dd       }t        j                   t        j"                  |dd       }t        j                  d|dd       d   }t        j                  d|dd       d   }d}n|	t        j$                  k(  r|dk  rt        d      t        j                   t        j&                  |dd       }t        j                   t        j&                  |dd       }t        j                  d|dd       d   }t        j                  d|dd       d   }d}n<|	t        j(                  k(  rdddddd| _	        t        ||d       S t        d|	z        |||||d| _	        t        ||d       S )zbParse PROXY protocol v2 (binary format).

        Returns buffer with v2 header consumed.
           r      z>H   r      rA   r'   zunsupported version %d   zunsupported command %dr    Nr   zonly TCP protocol is supportedz"insufficient address data for IPv4   
   r   $   z"insufficient address data for IPv6    "   r   r)   zunsupported address family %d)rr   r   structunpackr   r   r   r    r!   r   r   r.   r/   r&   r*   r   	inet_ntopr   r+   r   r)   )rV   rC   r   ver_cmd	fam_protolengthrF   commandtotal_header_sizefamilyprotocol	addr_datar   r   r   r   r   s                    r$   r   z Request._parse_proxy_protocol_v2  s    #hmNN8S) #hm b'G	tU3r":%67: T>a'a<$%=%GHH D.9??IOO<<$%=%GHH K#h**NN8S) #h** ioo%")##""(D$ S!2!3455 d"q(t# z((($%EFF#bf-.	X]]"{()MNN%%fnni!nEF%%fnni!nEF]]41R9!<F]]42b)9:1=FEx~~%{()MNN%%fooy2GF%%fooyB7GHF]]42b)9:1=F]]42b)9:1=FEx& #+##""(D$ S!2!3455 %%Dv%MNN $!!  $
  ./011r#   c                    |j                  dd      D cg c]  }t        |       }}t        |      dk7  rt        t        |            |d   | _        | j
                  j                  sbt        j                  | j                        rt        | j                        dt        |d         cxk  rdk  sn t        | j                        t        j                  | j                        st        | j                        | j
                  j                  r| j                  j                         | _        |d   | _        t        | j                        dk(  rt        t        |            	 t        | j                        }|j"                  xs d| _        |j$                  xs d| _        |j&                  xs d| _        t(        j                  |d         }|t+        |d         t-        |j/                  d            t-        |j/                  d            f| _        d| j0                  cxk  rd	k  s.n | j
                  j2                  st+        | j0                        y y c c}w # t         $ r t        t        |            w xY w)
N    r'   r(   r      r    r   )r'   r   )rk   r   rr   r   r   rB   !permit_unconventional_http_methodMETHOD_BADCHAR_REr   r   rw   rx   casefold_http_methodry   r   r   r5   r   r   r   
VERSION_REr   r   grouprF   "permit_unconventional_http_version)rV   
line_bytesbitr   partsmatchs         r$   r   zRequest.parse_request_lineN  s   -7-=-=dA-FGcS!GGt9>$\*%=>> 1g xx99 ''4*4;;77DG***4;;77!!$++.&t{{33 88((++++-DK 7 txx=A$\*%=>>	?%dhh/E JJ$"	[[&B
," $$T!W-=$T!W--EKKN+SQ-@A..88>>(66 ? /c HL  	?$\*%=>>	?s   I&-I+ +J	c                     t         |           t        | j                  j                  t
              r%t        t        | j                  d            | _        y y r   )	r   rU   rl   rI   readerr   r   r   rC   )rV   r   s    r$   rU   zRequest.set_body_reader  s>    !dii&&	2\$--;<DI 3r#   )r   r   )r   )r   r   r   rY   r   rS   r   r   r   r   r   r   r   r   rU   __classcell__)r   s   @r$   r   r   4  sI    3"%N+&:,;;z[2z57n= =r#   r   )/enumr   r3   rer   r   gunicorn.http.bodyr   r   r   r   gunicorn.http.errorsr   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   gunicorn.utilr   r   r   r   r&   r.   r   rO   rQ   RFC9110_5_6_2_TOKEN_SPECIALScompileescaperw   r  r  r   r;   r=   r   r"   r#   r$   <module>r!     s   
   	   K K    ] \ 5 9 F w    #   2 2::'92995Q+RSTBJJx( RZZ*+
$.BJJ{$; !(_& _&DT=g T=r#   