U
    g@4                     @  sZ  d dl mZ d dlZd dlZd dlZd dlZd dlZd dlmZm	Z	 ddl
mZ ddlmZ ddlmZ dd	d
dgZdjej Zejdde de Zejdde de ZeejddZeejddZeejddZdddddZedZedZej G dd
 d
Z!ej G dd dZ"d d!d"d#d$Z#d d%d"d&d'Z$dS )(    )annotationsN)Callable	Generator   )Headers)SecurityError)versionSERVER
USER_AGENTRequestResponsez{}.{}ZWEBSOCKETS_USER_AGENTzPython/z websockets/ZWEBSOCKETS_SERVERZWEBSOCKETS_MAX_NUM_HEADERSZ128ZWEBSOCKETS_MAX_LINE_LENGTHZ8192ZWEBSOCKETS_MAX_BODY_SIZEZ	1_048_576bytesstr)valuereturnc                 C  s   | j ddS )zG
    Decode a bytestring for interpolating into an error message.

    backslashreplace)errors)decode)r    r   5/tmp/pip-unpacked-wheel-dx_q7dq3/websockets/http11.pyd,   s    r   s   [-!#$%&\'*+.^_`|~0-9a-zA-Z]+s   [\x09\x20-\x7e\x80-\xff]*c                   @  sb   e Zd ZU dZded< ded< dZded< edd	d
dZedddddZ	dd	ddZ
dS )r   z
    WebSocket handshake request.

    Attributes:
        path: Request path, including optional query.
        headers: Request headers.
    r   pathr   headersNException | None
_exceptionr   c                 C  s   t dt | jS )NzIRequest.exception is deprecated; use ServerProtocol.handshake_exc insteadwarningswarnDeprecationWarningr   selfr   r   r   	exceptionX   s
    zRequest.exception-Callable[[int], Generator[None, None, bytes]]zGenerator[None, None, Request]	read_liner   c           	   
   c  s   zt |E dH }W n, tk
r> } ztd|W 5 d}~X Y nX z|dd\}}}W n( tk
r~   tdt| dY nX |dkrtdt| |dkrtd	t| |d
d}t|E dH }d|krtdd|krtd| ||S )a  
        Parse a WebSocket handshake request.

        This is a generator-based coroutine.

        The request path isn't URL-decoded or validated in any way.

        The request path and headers are expected to contain only ASCII
        characters. Other characters are represented with surrogate escapes.

        :meth:`parse` doesn't attempt to read the request body because
        WebSocket handshake requests don't have one. If the request contains a
        body, it may be read from the data stream after :meth:`parse` returns.

        Args:
            read_line: Generator-based coroutine that reads a LF-terminated
                line or raises an exception if there isn't enough data

        Raises:
            EOFError: If the connection is closed without a full HTTP request.
            SecurityError: If the request exceeds a security limit.
            ValueError: If the request isn't well formatted.

        Nz1connection closed while reading HTTP request line       zinvalid HTTP request line:    HTTP/1.1)unsupported protocol; expected HTTP/1.1: s   GETz+unsupported HTTP method; expected GET; got asciisurrogateescapeTransfer-Encoding!transfer codings aren't supportedContent-Lengthzunsupported request body)
parse_lineEOFErrorsplit
ValueErrorr   r   parse_headersNotImplementedError)	clsr%   Zrequest_lineexcmethodraw_pathprotocolr   r   r   r   r   parsea   s*    #zRequest.parser   c                 C  s$   d| j  d }|| j 7 }|S )z;
        Serialize a WebSocket handshake request.

        zGET z HTTP/1.1
)r   encoder   	serialize)r!   requestr   r   r   r<      s    zRequest.serialize)__name__
__module____qualname____doc____annotations__r   propertyr"   classmethodr:   r<   r   r   r   r   r   H   s   
?c                   @  sz   e Zd ZU dZded< ded< ded< dZd	ed
< dZded< eddddZe	dddddddZ
ddddZdS )r   z
    WebSocket handshake response.

    Attributes:
        status_code: Response code.
        reason_phrase: Response reason.
        headers: Response headers.
        body: Response body, if any.

    intstatus_coder   reason_phraser   r   Nzbytes | Nonebodyr   r   r   c                 C  s   t dt | jS )NzJResponse.exception is deprecated; use ClientProtocol.handshake_exc insteadr   r    r   r   r   r"      s
    zResponse.exceptionr#   zGenerator[None, None, Response])r%   
read_exactread_to_eofr   c              
   c  s$  zt |E dH }W n, tk
r> } ztd|W 5 d}~X Y nX z|dd\}}}W n( tk
r~   tdt| dY nX |dkrtdt| zt|}	W n( tk
r   tdt| dY nX d	|	  krd
k sn tdt| t|stdt| |dd}
t	|E dH }d|krBt
dd	|	  krZdk spn |	dksp|	dkrvd}nz|d }W n tk
r   d}Y n
X t|}|dkrz|tE dH }W n& tk
r   tdt dY nX n*|tkrtd| dn||E dH }| |	|
||S )a  
        Parse a WebSocket handshake response.

        This is a generator-based coroutine.

        The reason phrase and headers are expected to contain only ASCII
        characters. Other characters are represented with surrogate escapes.

        Args:
            read_line: Generator-based coroutine that reads a LF-terminated
                line or raises an exception if there isn't enough data.
            read_exact: Generator-based coroutine that reads the requested
                bytes or raises an exception if there isn't enough data.
            read_to_eof: Generator-based coroutine that reads until the end
                of the stream.

        Raises:
            EOFError: If the connection is closed without a full HTTP response.
            SecurityError: If the response exceeds a security limit.
            LookupError: If the response isn't well formatted.
            ValueError: If the response isn't well formatted.

        Nz0connection closed while reading HTTP status liner&   r'   zinvalid HTTP status line: r(   r)   z+invalid status code; expected integer; got d   iX  u-   invalid status code; expected 100–599; got zinvalid HTTP reason phrase: r*   r+   r,   r-         i0  r.   zbody too large: over z byteszbody too large: )r/   r0   r1   r2   r   rE   	_value_re	fullmatchr   r3   r4   KeyErrorMAX_BODY_SIZERuntimeErrorr   )r5   r%   rI   rJ   Zstatus_liner6   r9   Zraw_status_codeZ
raw_reasonrF   reasonr   rH   Zraw_content_lengthcontent_lengthr   r   r   r:      s\     
.


zResponse.parser   c                 C  s@   d| j  d| j d }|| j 7 }| jdk	r<|| j7 }|S )z<
        Serialize a WebSocket handshake response.

        z	HTTP/1.1  z
N)rF   rG   r;   r   r<   rH   )r!   responser   r   r   r<   (  s
    

zResponse.serialize)r>   r?   r@   rA   rB   rH   r   rC   r"   rD   r:   r<   r   r   r   r   r      s   
]r#   zGenerator[None, None, Headers]r$   c           	      c  s  t  }ttd D ]}zt| E dH }W n, tk
rT } ztd|W 5 d}~X Y nX |dkrd qz|dd\}}W n( tk
r   tdt| dY nX t	|stdt| |
d}t	|std	t| |d
}|d
d}|||< qtd|S )a  
    Parse HTTP headers.

    Non-ASCII characters are represented with surrogate escapes.

    Args:
        read_line: Generator-based coroutine that reads a LF-terminated line
            or raises an exception if there isn't enough data.

    Raises:
        EOFError: If the connection is closed without complete headers.
        SecurityError: If the request exceeds a security limit.
        ValueError: If the request isn't well formatted.

    r   Nz,connection closed while reading HTTP headers       :zinvalid HTTP header line: zinvalid HTTP header name: s    	zinvalid HTTP header value: r*   r+   ztoo many HTTP headers)r   rangeMAX_NUM_HEADERSr/   r0   r1   r2   r   	_token_rerO   striprN   r   r   )	r%   r   _liner6   Zraw_name	raw_valuenamer   r   r   r   r3   6  s,    




r3   zGenerator[None, None, bytes]c                 c  sN   z| t E dH }W n tk
r.   tdY nX |dsBtd|dd S )ao  
    Parse a single line.

    CRLF is stripped from the return value.

    Args:
        read_line: Generator-based coroutine that reads a LF-terminated line
            or raises an exception if there isn't enough data.

    Raises:
        EOFError: If the connection is closed without a CRLF.
        SecurityError: If the response exceeds a security limit.

    Nzline too longs   
zline without CRLF)MAX_LINE_LENGTHrR   r   endswithr0   )r%   r^   r   r   r   r/   i  s    
r/   )%
__future__r   Zdataclassesosresysr   typingr   r   Zdatastructuresr   
exceptionsr   r   Zwebsockets_version__all__formatversion_infoPYTHON_VERSIONenvirongetr
   r	   rE   rZ   rb   rQ   r   compiler[   rN   Z	dataclassr   r   r3   r/   r   r   r   r   <module>   s@   

d 	3