o
    NK&huS                     @  s   d dl mZ d dlmZmZ erd dlmZ d dlmZ d dl	m
Z
mZ d dlmZ d dlmZ d dlmZmZmZmZmZmZ d d	lmZ d d
lmZ d dlmZ d dlmZ d dlm Z m!Z!m"Z" d dl#m$Z$ dZ%G dd dee$dZ&dS )    )annotations)TYPE_CHECKINGOptional)Request)BaseHTTPResponse)CancelledErrorsleep)perf_counter)Header)
BadRequestExpectationFailedPayloadTooLargeRequestCancelledServerErrorServiceUnavailable)format_http1_response)has_message_body)Stage)Stream)access_loggererror_loggerlogger)TouchUpMetas   HTTP/1.1 100 Continue

c                   @  s   e Zd ZdZdZdZdZg dZdd Zdd	 Z	d
d Z
dd Zdd Zd<ddZd<ddZd<ddZd<ddZd=d d!Zd>d"d#Zd>d$d%Zd&d' Zd?d)d*Zd@d-d.Zed/d0 ZedAd3d4ZedBdCd9d:Zd;S )DHttpa   "Internal helper for managing the HTTP/1.1 request/response cycle.

    Raises:
        BadRequest: If the request body is malformed.
        Exception: If the request is malformed.
        ExpectationFailed: If the request is malformed.
        PayloadTooLarge: If the request body exceeds the size limit.
        RuntimeError: If the response status is invalid.
        ServerError: If the handler does not produce a response.
        ServerError: If the response is bigger than the content-length.
    i @  r   )http1_request_headerhttp1_response_headerread)_send_receive_moredispatchrecv_bufferprotocolexpecting_continuestage
keep_alive	head_onlyrequest	exceptionurlrequest_bodyrequest_bytesrequest_bytes_leftresponseresponse_funcresponse_sizeresponse_bytes_leftupgrade_websocketperft0c                 C  s<   |j | _|j| _|j| _|| _d| _tj| _	| jj
j| _d S )NT)sendr   receive_morer   r    r!   r$   r   IDLEr#   appr   )selfr!    r7   C/var/www/html/venv/lib/python3.10/site-packages/sanic/http/http1.py__init__M   s   zHttp.__init__c                 C  sP   d| _ d| _d| _d| _d| _d| _| jj| _d| _d| _	d| _
d| _d| _dS )z%Init/reset all per-request variables.NF)r'   r"   r%   r)   r*   r+   r!   request_max_sizer&   r,   r0   r(   r1   r6   r7   r7   r8   init_for_requestV   s   

zHttp.init_for_requestc                 C  s   | j tjtjfv S )z'Test if request handling is in progress)r#   r   HANDLERRESPONSEr;   r7   r7   r8   __bool__e   s   zHttp.__bool__c              
     sX  | j r&| jtju r(|   | js|  I dH  tj| _zB| j| _	| 
 I dH  tj| _t | _| jj| j_| j| jI dH  | jtju rO| jsOtd| jtju r_| jjddI dH  W na ty } z<| jjstd| jj d| jj d W Y d}~dS | jjjrt n| jp|}d| _d| _ |  |I dH  W Y d}~nd}~w t!y } z|  |I dH  W Y d}~nd}~ww | j"r
| jrd	| jj#  krd
k rn n	t$%| j d t&| j'| jj'| _'z| 2 z3 dH W }q6 W n t(y	   t)dI dH  d| _ Y nw | jrd| j_*| jrd| j_*| j r*| jtju sdS dS dS dS )zHTTP 1.1 connection handlerNzHandler produced no responseT)
end_streamz	Request:  z stopped. Transport is closed.F   i,  z body not consumed.gMbP?)+r$   r#   r   r4   r<   r    r   REQUESTr   r-   r   r=   r	   r1   r!   	conn_infor&   request_handlerr0   r   r>   r,   r2   r   	transportr   infomethodr(   lostr   r'   error_response	Exceptionr)   statusr   errorminr:   r   r   stream)r6   exce_r7   r7   r8   http1i   sn   "

	$z
Http.http1c              	     s  | j }d}	 |d|}|dkrntdt|d }|| jkr!n|  I dH  q|| jkr2tdz|d| }|jdd	}|d
^}}|d\}| _	}| j
dddt|idI dH  |dkrfd| _n
|dkrnd| _nt| dk| _d}	g }
dd |D D ]-\}}| | f \}}}|dv r|	rtdd}	n|dkr| dk| _|
| qW n ty   tdw t|
}|dd dk| _z| j	d}W n ty   tdw | jj||t||dd || jj| jjd }| jjj| | j
d!dd"|idI dH  d | _ | _!|	rc|j"}
|
d#d}|dur5| d$kr.d| _#nt$d%| |
d&dd'krFd'| _%|d(8 }nd| _%z| &|
d)  | _ | _!W n tyb   td*w |d|d+ = || | _'|_(| jj)d,  d-7  < dS ).z3Receive and parse request header into self.request.r   Ts   

   Nz%Request header exceeds the size limitsurrogateescapeerrorsz
rA   zhttp.lifecycle.read_headheadinlinecontextzHTTP/1.1zHTTP/1.0FHEADc                 s  s    | ]	}| d dV  qdS ):   N)split).0hr7   r7   r8   	<genexpr>   s    z,Http.http1_request_header.<locals>.<genexpr>)content-lengthtransfer-encodingz-Duplicate Content-Length or Transfer-Encoding
connection
keep-alivezBad Requestupgrade 	websocketASCIIz)URL may only contain US-ASCII characters.   )	url_bytesheadersrY   versionrH   rF   r5   zhttp.lifecycle.requestr&   expectz100-continuezUnknown Expect: re   chunked   rd   zBad content-length   requests_countr_   )*r    findmaxlenHEADER_MAX_SIZEr   r   decoder`   r(   r   bytesr$   rK   upperr%   lowerlstrip
ValueErrorappendr   r
   getoner0   encodeUnicodeEncodeErrorr!   request_classrF   r5   _currentsetr+   r*   rn   r"   r   r)   	_safe_intr&   rO   state)r6   bufposrY   raw_headersreqlinesplit_headersrH   r!   r)   rn   namevaluerb   headers_instancerm   r&   rp   r7   r7   r8   r      s   



	

zHttp.http1_request_headerdatarz   r@   boolreturnNonec                   s  | j }|st|ddr|jd}}t|}|j}|j}|| _t|tr(|dk r/t	d|t
|sbd| _|sB|rBd|v sBd|v rad\}}}|dd |dd td	| jj d
| d n9| jrmd|v rmd| _n.|rw||d< d| _n$d|v rt|d | | _| j| _nd|d< |rd||f nd}| j| _| jrd}| j| _| jrdnd|d< d|d< t||j}|r||7 }| jrd| _|dkrt| }| jjr|   | |I dH  |rtj | _"dS tj!| _"dS )z#Format response header and send it.bodyNTrB   zInvalid response status rd   re   )    r   Tz Message body set in response on z. A z) response may only have headers, no body.rq      %x
%b
r   rg   closerf   ri   zalt-svcFi  )#r,   getattrr   rw   rn   rL   r.   
isinstanceintRuntimeErrorr   r-   popr   warningr&   pathr%   r/   http1_response_normalhttp1_response_chunkedhead_response_ignoredr$   r   processed_headersr"   HTTP_CONTINUEr!   
access_loglog_responser   r   r4   r>   r#   )r6   r   r@   ressizern   rL   retr7   r7   r8   r   $  sl   

zHttp.http1_response_headerc                 C  s   |rd| _ tj| _dS dS )z*HEAD response: body data silently ignored.N)r-   r   r4   r#   )r6   r   r@   r7   r7   r8   r   s  s   zHttp.head_response_ignoredc                   sd   t |}|r | |rd||f ndI dH  d| _tj| _dS |r0| d||f I dH  dS dS )z3Format a part of response body in chunked encoding.s   %x
%b
0

s   0

Nr   )rw   r   r-   r   r4   r#   )r6   r   r@   r   r7   r7   r8   r   y  s   
zHttp.http1_response_chunkedc                   sn   | j t| }|dkr$|dk rtd| |I dH  d| _tj| _n|r*td| |I dH  || _ dS )z,Format / keep track of non-chunked response.r   z'Response was bigger than content-lengthNz(Response was smaller than content-length)r/   rw   r   r   r-   r   r4   r#   )r6   r   r@   
bytes_leftr7   r7   r8   r     s   

zHttp.http1_response_normalr'   rK   c              
     s   | j tjur
d| _| j tju rtj| _ | j tju r\| jj}| jdu r'|   t	|t
tf }z|| j||I dH  W dS  ty[ } z|| j|dI dH  W Y d}~dS d}~ww dS )z*Handle response when exception encounteredFN)r#   r   r=   r$   rC   r!   r5   r&   create_empty_requestr   r   r   handle_exceptionrK   )r6   r'   r5   request_middlewarerQ   r7   r7   r8   rJ     s*   
$zHttp.error_responsec                 C  sZ   | j r| j jddjddddnd}| jj|ti dd| jj| jjd| _| | j_	d	S )
a  Create an empty request object for error handling use.

        Current error handling code needs a request object that won't exist
        if an error occurred during before a request was received. Create a
        bogus response for error handling use.
        rV   rW   rk   backslashreplace   *z1.1NONE)rm   rn   ro   rH   rF   r5   N)
r(   r   ry   r!   r   r
   rF   r5   r&   rO   )r6   rm   r7   r7   r8   r     s    	zHttp.create_empty_requestc                 C  s   | j | j}}t|dd|jddkr|jddndt| jjddd d	 d
| jdur<ddt	 | j  ddndd}|j
 }rO| d|j |d< |j d|j |d< tjd|d dS )znHelper method provided to enable the logging of responses in case if the `HttpProtocol.access_log` is enabled.rL   r   re   rq   rd   XrT   unxnilNrA   i  z.1fmsri   )rL   bytehostr&   durationr^   r   r&   )extra)r&   r,   r   rn   getidr!   rF   r1   r	   	client_ipportrH   r(   r   rG   )r6   reqr   r   ipr7   r7   r8   r     s   


zHttp.log_responsec                 C s.   | j r|  I dH }|r|V  | j sdS dS )z Async iterate over request body.N)r)   r   )r6   r   r7   r7   r8   	__aiter__  s   zHttp.__aiter__Optional[bytes]c                   s  | j rd| _ | tI dH  | j}| jdkr| jdkr	 |dd}|dkr(nt|d	kr5d| _t	d
| 
 I dH  qz|d| ddd  }| |d}W n tya   d| _t	d
w |dkrd| _|dk rtd| _t	d
|d7 }t||k r| 
 I dH  t||k s~|d|= dS |d|d = || _|  j|7  _| j| jkrd| _td| jsd| _dS |s| 
 I dH  t|d| j }t|}|d|= |  j|8  _| jddd|idI dH  |S )z Read some bytes of request body.FNr   rq   Ts   
rU   rT   @   zBad chunked encodingrr      ;r_      rs   z#Request body exceeds the size limitzhttp.lifecycle.read_bodyr   rZ   )r"   r   r   r    r+   r)   ru   rw   r$   r   r   r`   ry   r   rK   r*   r:   r   rz   r   )r6   r   r   rawr   r   r7   r7   r8   r     sl   

z	Http.readr,   r   c                 C  s@   | j tjurtj| _ td| jdurd| j_|| | _|_|S )zInitiate new streaming response.

        Nothing is sent until the first send() call on the returned object, and
        calling this function multiple times will just alter the response to be
        given.
        zResponse already startedN)r#   r   r=   FAILEDr   r,   rO   )r6   r,   r7   r7   r8   respondF  s   
zHttp.respondc                 C  s   | j S N)r-   r;   r7   r7   r8   r2   Y  s   z	Http.sendsizesr   c                 G  s   t g || jR  | _d S r   )rN   HEADER_CEILINGrx   )clsr   r7   r7   r8   set_header_max_size]  s
   zHttp.set_header_max_size
   r   strbasec                 C  s&   d| v sd| v sd| v rt t| |S )N-+rR   )r~   r   )r   r   r7   r7   r8   r   d  s   
zHttp._safe_intN)r   rz   r@   r   r   r   )r'   rK   r   r   )r   r   )r   r   )r,   r   r   r   )r   r   )r   )r   r   r   r   r   r   )__name__
__module____qualname____doc__r   rx   __touchup__	__slots__r9   r<   r?   rS   r   r   r   r   r   rJ   r   r   r   r   r   propertyr2   classmethodr   staticmethodr   r7   r7   r7   r8   r   !   s6    	G
t
O






S
r   )	metaclassN)'
__future__r   typingr   r   sanic.requestr   sanic.responser   asyncior   r   timer	   sanic.compatr
   sanic.exceptionsr   r   r   r   r   r   sanic.headersr   sanic.helpersr   sanic.http.constantsr   sanic.http.streamr   	sanic.logr   r   r   sanic.touchupr   r   r   r7   r7   r7   r8   <module>   s"     