U
    c^0                     @   s   d dl Z d dlZd dlZd dlmZ d dlm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 d dlmZmZ d dlmZ d dlmZmZ d	Zd
Zd	ZedZedZ edZ!G dd de"Z#G dd de#Z$dS )    N)ENOTCONN)SocketUnreader)ChunkedReaderLengthReader	EOFReaderBody)InvalidHeaderInvalidHeaderName
NoMoreDataInvalidRequestLineInvalidRequestMethodInvalidHTTPVersionLimitRequestLineLimitRequestHeaders)InvalidProxyLineForbiddenProxyRequest)InvalidSchemeHeaders)bytes_to_strsplit_request_urii  i   z%[\x00-\x1F\x7F()<>@,;:\[\]={} \t\\\"]z[A-Z0-9$-_.]{3,20}zHTTP/(\d+)\.(\d+)c                   @   s4   e Zd Zdd Zdd Zdd Zdd Zd	d
 ZdS )Messagec                 C   s   || _ || _d | _g | _g | _d | _|jr.dnd| _|j| _| jdksP| jt	krVt	| _|j
| _
| j
dk rnt| _
| j
pvt}| j|d  d | _| | j}| j| |   d S )Nhttpshttpr         )cfgunreaderversionheadersZtrailersbodyZis_sslschemelimit_request_fieldsMAX_HEADERSlimit_request_field_sizeDEFAULT_MAX_HEADERFIELD_SIZEmax_buffer_headersparseunreadset_body_reader)selfr   r   Zmax_header_field_sizeZunused r)   ;/tmp/pip-install-u9bp_5q1/gunicorn/gunicorn/http/message.py__init__   s0    


zMessage.__init__c                 C   s
   t  d S N)NotImplementedError)r(   r   r)   r)   r*   r%   9   s    zMessage.parsec                 C   s(  | j }g }dd |dD }d}i }d|jkr8|j}n^t| jtr| jj }| jjj	t
jt
jfkr|d }||jkr|j}n| jjj	t
jkr|j}|r$t|| jkrtd|d}	t|	}
|	ddk rt|	 |	dd	\}}| j jr|d
 }n| }t|r$t|| | g }}|r|d dr|d}	|
t|	7 }
|
| j  kr~dkrn ntd||	 q8d| }|
| j  krdkrn ntd||kr||| k}|rdnd}|r
|| j krt! n
d}|| _ |||f q|S )Nc                 S   s   g | ]}t |d  qS )z
r   ).0liner)   r)   r*   
<listcomp>A   s     z)Message.parse_headers.<locals>.<listcomp>   
F*r   zlimit request headers fields:   z 	) 	z!limit request headers fields size r   r   T)"r   splitZforwarded_allow_ipssecure_scheme_headers
isinstancer   r   sockgetpeernamefamilysocketAF_INETAF_INET6AF_UNIXlenr    r   popfindr   stripZstrip_header_spacesrstripupper	HEADER_REsearchr	   lstrip
startswithr"   appendjoinr   r   )r(   datar   r   linesZscheme_headerr:   Zremote_addrremote_hostcurrheader_lengthnamevaluesecurer   r)   r)   r*   parse_headers<   s`    





zMessage.parse_headersc                 C   s   d}d }| j D ]P\}}|dkr8|d k	r2td| d|}q|dkrR| dkr^d}q|dkrd}q|rxtt| | j| _nn|d k	rzt|}W n  tk
r   td| dY nX |d	k rtd| dtt	| j|| _ntt
| j| _d S )
NFzCONTENT-LENGTH)reqzTRANSFER-ENCODINGchunkedTzSEC-WEBSOCKET-KEY1   r   )r   r   lowerr   r   r   r   int
ValueErrorr   r   )r(   rY   content_lengthrT   rU   r)   r)   r*   r'      s.    zMessage.set_body_readerc                 C   sN   | j D ]<\}}|dkr|  }|dkr0 dS |dkr> dS  qDq| jdkS )NZ
CONNECTIONcloseTz
keep-aliveF)r5   r   )r   r[   rF   r   )r(   hvr)   r)   r*   should_close   s    zMessage.should_closeN)__name__
__module____qualname__r+   r%   rW   r'   rb   r)   r)   r)   r*   r      s
   Er   c                       sf   e Zd Zd fdd	ZdddZdd Zdd
dZdd Zdd Zdd Z	dd Z
 fddZ  ZS )Requestr5   c                    s^   d | _ d | _d | _d | _d | _|j| _| jdk s:| jtkr@t| _|| _d | _t	 
|| d S Nr   )methoduripathqueryfragmentlimit_request_lineMAX_REQUEST_LINE
req_numberproxy_protocol_infosuperr+   )r(   r   r   ro   	__class__r)   r*   r+      s    
zRequest.__init__Fc                 C   s0   |  }|s"|rt t| || d S r,   )readStopIterationr
   getvaluewrite)r(   r   bufstoprO   r)   r)   r*   get_data   s    zRequest.get_datac           	      C   s>  t  }| j||dd | ||| j\}}| t|r`t  }|| | ||| j\}}| | t  }|| |	 }|
d}|d d dk}|
d}|d d dk}|dk r|s| || |	 }t|| jkrtdqqq|r| j|dd   dS | |d | | _||d	 d  }d }|S )
NT)ry   s   

r   r2   r   zmax buffer headers    r   )ioBytesIOrz   	read_linerm   proxy_protocolr   rw   parse_request_linerv   rE   rC   r$   r   r   r&   rW   r   )	r(   r   rx   r0   ZrbufrO   idxdoneretr)   r)   r*   r%      s8    





zRequest.parser   c                 C   s   |  }|d}|dkr>||  kr.dkrn qt||qt|d |  krZdkrln ntt||| || |  }q|d | ||d d  fS )Nr2   r   r   )rv   rE   r   rC   rz   )r(   r   rx   limitrO   r   r)   r)   r*   r~      s    

 

zRequest.read_linec                 C   s>   | j jsdS | jdkrdS |ds(dS |   | | dS )z        Detect, check and parse proxy protocol.

        :raises: ForbiddenProxyRequest, InvalidProxyLine.
        :return: True for proxy protocol line else False
        Fr5   ZPROXYT)r   r   ro   rL   proxy_protocol_access_checkparse_proxy_protocol)r(   r0   r)   r)   r*   r     s    


zRequest.proxy_protocolc              
   C   s   t | jtr~z| jj d }W n< tjk
r\ } z|jd tkrJt	d W 5 d }~X Y nX d| j
jkr~|| j
jkr~t	|d S )Nr   ZUNKNOWr3   )r;   r   r   r<   r=   r?   errorargsr   r   r   Zproxy_allow_ips)r(   rQ   er)   r)   r*   r     s    
z#Request.proxy_protocol_access_checkc                 C   sr  |  }t|dkrt||d }|d }|d }|dkrHtd| |dkrz ttj| ttj| W q tjk
r   t|Y qX nH|dkrz ttj| ttj| W n tjk
r   t|Y nX zt|d	 }t|d
 }W n" t	k
r   td| Y nX d|  kr2dkrPn nd|  krNdks\n td| |||||d| _
d S )N   r5   r      )TCP4TCP6zprotocol '%s' not supportedr   r   r      zinvalid port %sr   i  )r   client_addrZclient_portZ
proxy_addrZ
proxy_port)r9   rC   r   r?   	inet_ptonr@   r   rA   r\   r]   rp   )r(   r0   bitsprotoZs_addrZd_addrZs_portZd_portr)   r)   r*   r   %  sB    6zRequest.parse_proxy_protocolc                 C   s   dd | d dD }t|dkr.tt|t|d sHt|d |d  | _|d | _	zt
| j	}W n  tk
r   tt|Y nX |jpd| _|jpd| _|jpd| _t|d }|d krt|d t|dt|df| _d S )Nc                 S   s   g | ]}t |qS r)   r.   )r/   bitr)   r)   r*   r1   S  s     z.Request.parse_request_line.<locals>.<listcomp>r   r   r   r5   r8   )r9   rC   r   r   METH_REmatchr   rH   rh   ri   r   r]   rj   rk   rl   
VERSION_REr   r\   groupr   )r(   Z
line_bytesr   partsr   r)   r)   r*   r   R  s$    
zRequest.parse_request_linec                    s.   t    t| jjtr*tt| jd| _d S rg   )	rq   r'   r;   r   readerr   r   r   r   )r(   rr   r)   r*   r'   m  s    
zRequest.set_body_reader)r5   )F)r   )rc   rd   re   r+   rz   r%   r~   r   r   r   r   r'   __classcell__r)   r)   rr   r*   rf      s   
-
-rf   )%r|   rer?   errnor   Zgunicorn.http.unreaderr   Zgunicorn.http.bodyr   r   r   r   Zgunicorn.http.errorsr   r	   r
   r   r   r   r   r   r   r   r   Zgunicorn.utilr   r   rn   r!   r#   compilerI   r   r   objectr   rf   r)   r)   r)   r*   <module>   s$   (


 