U
    h<                     @   s   d Z ddlmZ ddlZddlmZ ddlmZ ddlm	Z	 ddl
mZmZ ddlmZmZ dd	lmZmZmZmZmZ d
d ZG dd deZG dd deZG dd dZdd Zdd ZedZdd ZdS )zwHTTP Request Parser

This server uses asyncore to accept connections and do initial
processing but threads to do work.
    )BytesION)parse)unquote_to_bytes)OverflowableBuffer)ChunkedReceiverFixedStreamReceiver)HEADER_FIELD_REONLY_DIGIT_RE)
BadRequestRequestEntityTooLargeRequestHeaderFieldsTooLargeServerNotImplementedfind_double_newlinec                 C   s   t | dS )Nlatin-1)r   decode)
bytestring r   A/var/www/html/venv/lib/python3.8/site-packages/waitress/parser.pyunquote_bytes_to_wsgi$   s    r   c                   @   s   e Zd ZdS )ParsingErrorN__name__
__module____qualname__r   r   r   r   r   (   s   r   c                   @   s   e Zd ZdS )TransferEncodingNotImplementedNr   r   r   r   r   r   ,   s   r   c                   @   sl   e Zd ZdZdZdZdZdZdZdZ	dZ
dZdZdZdZdZdZdd Zd	d
 Zdd Zdd Zdd ZdS )HTTPRequestParserzA structure that collects the HTTP request.

    Once the stream is completed, the instance is passed to
    a server task constructor.
    F    r   N1.0c                 C   s   i | _ || _dS )z/
        adj is an Adjustments object.
        N)headersadj)selfr   r   r   r   __init__H   s    zHTTPRequestParser.__init__c              
   C   s4  | j r
dS t|}| j}|dkr| jj}| j| }t|}d}|dkr`|| _|t||  }n|  j|7  _|}| j|kr| d t	d| | _
d| _ |S |dkr|d| }| }|sd| _d| _ nz| | W nr tk
r }	 zt|	jd | _
d| _ W 5 d}	~	X Y n tk
rN }	 zt|	jd | _
d| _ W 5 d}	~	X Y nHX | jdkrbd| _ | jdkr| jj}
| j|
krtd|
 | _
d| _ d| _|S || _|S ||}|  j|7  _| jj}
| j|
krtd|
 | _
d| _ n@|j
r|j
| _
d| _ n(|j r,d| _ | jr,t| | jd< |S dS )z
        Receives the HTTP stream for one request.  Returns the number of
        bytes consumed.  Sets the completed flag once both the header and the
        body have been received.
        r   Ns   GET / HTTP/1.0
zexceeds max_header of %sTzexceeds max_body of %sCONTENT_LENGTH)	completedlenbody_rcvr   Zmax_request_header_sizeheader_plusr   header_bytes_receivedparse_headerr   errorlstripemptyr   r
   argsr   r   content_lengthZmax_request_body_sizer   headers_finishedreceivedbody_bytes_receivedchunkedstr__len__r   )r    dataZdatalenbrZ
max_headersindexconsumedr&   eZmax_bodyr   r   r   r/   Q   s|    





zHTTPRequestParser.receivedc              	   C   s  | d}|dkr4|d|  }||d d }ntdd|ksLd|krTtd|| _t|}| j}|D ]}t|}|std	|d
d\}}	d|krql|		d}	|
 ddd}
z||
  d|	 d7  < W ql tk
r   |	d||
< Y qlX qlt|\}}}||  kr8|  kr8dkrDn ntd|d| _|d}|d}|| _|| _t|\| _| _| _| _| _| jj| _|dd}|dkr| dkrd| _|dkrv|dd}dd |dD }|D ]}|dkrtdq|r:|d d kr:d| _ t!| jj"}t#|| _$n|rHtd|d!d }|d"k| _%| d#krvd| _| j s|d$d%}t&|'dstd&t(|}|| _)|dkrt!| jj"}t*||| _$dS )'zp
        Parses the header_plus block of text (the headers plus the
        first line of the request).
           
r   N   zHTTP message header invalid      
z#Bare CR or LF found in HTTP messagezInvalid headernamevalue   _s    	   -r   s   , r   zStart line is invalidZ
CONNECTION r   z
keep-aliveTz1.1ZTRANSFER_ENCODINGc                 S   s   g | ]}|r| d  qS )z 	)striplower).0encodingr   r   r   
<listcomp>   s     z2HTTPRequestParser.parse_header.<locals>.<listcomp>,>   r1   z-Transfer-Encoding requested is not supported.r1   ZEXPECTz100-continuecloser"   0zContent-Length is invalid)+findrstripr   
first_lineget_header_linesr   r   matchgrouprC   upperreplacer   KeyErrorcrack_first_linerequest_uricommandversion	split_uriproxy_schemeZproxy_netlocpathqueryfragmentr   
url_schemegetrD   connection_closepopsplitr   r1   r   Zinbuf_overflowr   r%   expect_continuer	   encodeintr-   r   )r    r&   r7   rN   headerlinesr   linekeyr?   key1rW   urirX   
connectionte	encodingsrF   bufexpectclr   r   r   r(      s    


(




		


zHTTPRequestParser.parse_headerc                 C   s    | j }|d k	r| S t S d S N)r%   getfiler   r    r%   r   r   r   get_body_streamN  s    z!HTTPRequestParser.get_body_streamc                 C   s   | j }|d k	r|   d S rr   )r%   ZgetbufrJ   rt   r   r   r   rJ   V  s    zHTTPRequestParser.close)r   r   r   __doc__r#   r+   rc   r.   r&   r1   r-   r'   r0   r%   rX   r)   r`   r!   r/   r(   ru   rJ   r   r   r   r   r   0   s(   	w r   c                 C   s   d } } } }}| d d dkrZ| }d|kr@| dd\}}d|kr| dd\}}n6zt| \}}}}}W n tk
r   tdY nX |d|dt||d|dfS )	Nr   r;   s   //   #      ?zBad URIr   )rb   r   urlsplitUnicodeErrorr   r   r   )rk   schemenetlocr[   r\   r]   r   r   r   rY   ]  s"    	rY   c                 C   s   g }|  d}|D ]h}|sqd|ks,d|kr>tdt|d |drp|s^tdt|d |d  |7  < q|| q|S )	zL
    Splits the header into lines, putting multi-line headers together.
    r:   r<   r=   z'Bare CR or LF found in header line "%s"r   )       	zMalformed header line "%s"rI   )rb   r   r2   
startswithappend)rf   rrg   rh   r   r   r   rO     s    

rO   s   (?P<method>[!#$%&'*+\-.^_`|~0-9A-Za-z]+) (?P<uri>(?:[^ :?#]+://[^ ?#/]*(?:[0-9]{1,5})?)?[^ ]+)(?: HTTP/(?P<version>[0-9]\.[0-9]))?c                 C   sZ   t | }|d krdS |d p d}|d }|d }|| krPtdt|d |||fS )N)r   r   r   rX   r   methodrk   zMalformed HTTP method "%s"r   )first_line_re	fullmatchrR   r   r2   )rh   mrX   r   rk   r   r   r   rU     s    
rU   ) rv   ior   reurllibr   urllib.parser   Zwaitress.buffersr   Zwaitress.receiverr   r   Zwaitress.rfc7230r   r	   Zwaitress.utilitiesr
   r   r   r   r   r   	Exceptionr   r   r   rY   rO   compiler   rU   r   r   r   r   <module>   s(   	  /$