B
    `;                 @   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mZmZmZ d	d
l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)
BadRequestRequestEntityTooLargeRequestHeaderFieldsTooLargeServerNotImplementedfind_double_newline   )HEADER_FIELDc             C   s   t | dS )Nzlatin-1)r   decode)Z
bytestring r   W/home/kop/projects/devel/pgwui/test_venv/lib/python3.7/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 )TransferEncodingNotImplementedN)r   r   r   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   Nz1.0c             C   s   i | _ || _dS )z/
        adj is an Adjustments object.
        N)headersadj)selfr   r   r   r   __init__I   s    zHTTPRequestParser.__init__c          
   C   s<  | j r
dS t|}| j}|dkr| jj}| j| }t|}d}|dkrh|  j|7  _|t||  }n|  j|7  _|}| j|kr| d t	d| | _
d| _ |S |dkr|d| }| }|sd| _d| _ ny| | W nr tk
r }	 zt|	jd | _
d| _ W dd}	~	X Y n tk
rV }	 zt|	jd | _
d| _ W dd}	~	X Y nHX | jdkrjd| _ | 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 r4d| _ | jr4t| | 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+   R   sx    





zHTTPRequestParser.receivedc          	   C   s  | d}|dkr4|d|  }||d d }ntdd|ksLd|krTtd|| _t|}| j}x|D ]}t|}|std	|d
d\}}	d|krqn|		d}	|
 ddd}
y||
  d|	 d7  < W qn tk
r   |	d||
< Y qnX qnW t|\}}}|d}|d}|| _|| _t|\| _| _| _| _| _| jj| _|dd}|dkr| dkrd| _|dkrB|dd}dd |dD }x |D ]}|dkrtdqW |r|d dkrd| _t | jj!}t"|| _#n|rtd|dd }|d k| _$| d!krBd| _| jsyt%|d"d}W n t&k
r|   td#Y nX || _'|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).
        s   
r   N   zHTTP message header invalid      
z#Bare CR or LF found in HTTP messagezInvalid headernamevalue   _s    	   -zlatin-1s   , Z
CONNECTION z1.0z
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>,>   r-   z-Transfer-Encoding requested is not supported.r-   ZEXPECTz100-continuecloser   zContent-Length is invalid))findrstripr   
first_lineget_header_linesr   r   matchgroupr>   upperreplacer   KeyErrorcrack_first_linecommandversion	split_uriproxy_schemeZproxy_netlocpathqueryfragmentr   
url_schemegetr?   connection_closepopsplitr   r-   r   Zinbuf_overflowr   r!   expect_continueint
ValueErrorr)   r   )r   r"   r3   rH   headerlinesr   linekeyr:   key1rP   urirQ   
connectionte	encodingsrA   bufexpectZclr   r   r   r$      sz    










	


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_streamH  s    z!HTTPRequestParser.get_body_streamc             C   s   | j }|d k	r|   d S )N)r!   ZgetbufrE   )r   r!   r   r   r   rE   P  s    zHTTPRequestParser.close)r   r   r   __doc__r   r'   r\   r*   r"   r-   r)   r#   r,   r!   rQ   r%   rY   r   r+   r$   rk   rE   r   r   r   r   r   1   s&   	wr   c             C   s   d } } } }}| d d dkrZ| }d|kr@| dd\}}d|kr| dd\}}n6yt| \}}}}}W n tk
r   tdY nX |d|dt||d|dfS )	Nr   r6   s   //   #r      ?zBad URIzlatin-1)r[   r   urlsplitUnicodeErrorr   r   r   )rd   schemenetlocrT   rU   rV   r   r   r   rR   W  s     	rR   c             C   s   g }|  d}xp|D ]h}|sqd|ks.d|kr@tdt|d |drr|s`tdt|d |d  |7  < q|| qW |S )	zL
    Splits the header into lines, putting multi-line headers together.
    s   
r7   r8   z'Bare CR or LF found in header line "%s"zlatin-1)       	zMalformed header line "%s"rD   )r[   r   r.   
startswithappend)r_   rr`   ra   r   r   r   rI   {  s    


rI   sL   ([^ ]+) ((?:[^ :?#]+://[^ ?#/]*(?:[0-9]{1,5})?)?[^ ]+)(( HTTP/([0-9.]+))$|$)c             C   s   t | }|d k	rx| t| krx|dr8|d}nd}|d}|| krdtdt|d |d}|||fS dS d S )	N      r   r   zMalformed HTTP method "%s"zlatin-1r6   )r   r   r   )first_line_rerJ   endr    rK   rL   r   r.   )ra   mrQ   methodrd   r   r   r   rO     s    




rO   )rl   ior   reurllibr   urllib.parser   Zwaitress.buffersr   Zwaitress.receiverr   r   Zwaitress.utilitiesr   r	   r
   r   r   Zrfc7230r   r   	Exceptionr   r   r   rR   rI   compilerz   rO   r   r   r   r   <module>   s&     ($