U
    gl,                     @  sR  d dl m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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 ddlmZ ddlm Z  ddl!m"Z" dddgZ#G dd de Z$dddddddeddddddddddddddd ddd!d!d"d#d$d%dd&d'dZ%d*ddd%dd(d)dZ&dS )+    )annotationsN)AnySequence   )ClientProtocol)HeadersLike)ClientExtensionFactory) enable_client_permessage_deflate)validate_subprotocols)
USER_AGENTResponse)
CONNECTINGEvent)
LoggerLikeOriginSubprotocol)	parse_uri   )
Connection)Deadlineconnectunix_connectClientConnectionc                      st   e Zd ZdZddddddd fd	d
ZdedfdddddddZddd fddZdd fddZ  Z	S )r   a  
    :mod:`threading` implementation of a WebSocket client connection.

    :class:`ClientConnection` provides :meth:`recv` and :meth:`send` methods for
    receiving and sending messages.

    It supports iteration to receive messages::

        for message in websocket:
            process(message)

    The iterator exits normally when the connection is closed with close code
    1000 (OK) or 1001 (going away) or without a close code. It raises a
    :exc:`~websockets.exceptions.ConnectionClosedError` when the connection is
    closed with any other code.

    Args:
        socket: Socket connected to a WebSocket server.
        protocol: Sans-I/O connection.
        close_timeout: Timeout for closing the connection in seconds.

    
   close_timeoutzsocket.socketr   float | NoneNone)socketprotocolr   returnc                  s$   |  t  | _t j|||d d S )Nr   )	threadingr   response_rcvdsuper__init__)selfr   r   r   	__class__ :/tmp/pip-unpacked-wheel-dx_q7dq3/websockets/sync/client.pyr$   1   s    
zClientConnection.__init__NHeadersLike | None
str | None)additional_headersuser_agent_headertimeoutr    c              	   C  s   | j tdJ | j | _|dk	r0| jj| |dk	rD|| jjd< | j| j W 5 Q R X | j	|spt
d| jjdk	r| jjdS )z1
        Perform the opening handshake.

        )Zexpected_stateNz
User-Agentztimed out during handshake)Zsend_contextr   r   r   requestheadersupdatesend_requestr"   waitTimeoutErrorZhandshake_exc)r%   r,   r-   r.   r(   r(   r)   	handshake@   s    
zClientConnection.handshaker   )eventr    c                   s:   | j dkr*t|tst|| _ | j  nt | dS )z.
        Process one incoming event.

        N)response
isinstancer   AssertionErrorr"   setr#   process_event)r%   r6   r&   r(   r)   r;   \   s
    
zClientConnection.process_event)r    c                   s    zt   W 5 | j   X dS )zI
        Read incoming data from the socket and process events.

        N)r"   r:   r#   recv_events)r%   r&   r(   r)   r<   j   s    zClientConnection.recv_events)
__name__
__module____qualname____doc__r$   r   r5   r;   r<   __classcell__r(   r(   r&   r)   r      s   deflater   i   )socksslserver_hostnameorigin
extensionssubprotocolsr,   r-   compressionopen_timeoutr   max_sizeloggercreate_connectionstrzsocket.socket | Nonezssl_module.SSLContext | Noner+   zOrigin | Nonez'Sequence[ClientExtensionFactory] | NonezSequence[Subprotocol] | Noner*   r   z
int | NonezLoggerLike | Noneztype[ClientConnection] | Noner   )urirC   rD   rE   rF   rG   rH   r,   r-   rI   rJ   r   rK   rL   rM   kwargsr    c                K  sX  |dkr&d|kr&| d}tdt t| }|jsD|dk	rDtd| dd}| dd}|r|dkrz|dkrztdn|dk	r|dk	rtd	|dk	rt| |	d
krt|}n|	dk	rt	d|	 t
|
}|dkrt}z|dkrZ|r*ttjtj}||  |dk	st|| n&|d|  tj|j|jff|}|d |sr|tjtjd |jr|dkrt }|dkr|j}||  |j||d}|d t||||||d}||||d}W n* tk
r   |dk	r
|   Y nX z| |||  W n* tk
rR   |!  |j"#   Y nX |S )a
  
    Connect to the WebSocket server at ``uri``.

    This function returns a :class:`ClientConnection` instance, which you can
    use to send and receive messages.

    :func:`connect` may be used as a context manager::

        from websockets.sync.client import connect

        with connect(...) as websocket:
            ...

    The connection is closed automatically when exiting the context.

    Args:
        uri: URI of the WebSocket server.
        sock: Preexisting TCP socket. ``sock`` overrides the host and port
            from ``uri``. You may call :func:`socket.create_connection` to
            create a suitable TCP socket.
        ssl: Configuration for enabling TLS on the connection.
        server_hostname: Host name for the TLS handshake. ``server_hostname``
            overrides the host name from ``uri``.
        origin: Value of the ``Origin`` header, for servers that require it.
        extensions: List of supported extensions, in order in which they
            should be negotiated and run.
        subprotocols: List of supported subprotocols, in order of decreasing
            preference.
        additional_headers (HeadersLike | None): Arbitrary HTTP headers to add
            to the handshake request.
        user_agent_header: Value of  the ``User-Agent`` request header.
            It defaults to ``"Python/x.y.z websockets/X.Y"``.
            Setting it to :obj:`None` removes the header.
        compression: The "permessage-deflate" extension is enabled by default.
            Set ``compression`` to :obj:`None` to disable it. See the
            :doc:`compression guide <../../topics/compression>` for details.
        open_timeout: Timeout for opening the connection in seconds.
            :obj:`None` disables the timeout.
        close_timeout: Timeout for closing the connection in seconds.
            :obj:`None` disables the timeout.
        max_size: Maximum size of incoming messages in bytes.
            :obj:`None` disables the limit.
        logger: Logger for this client.
            It defaults to ``logging.getLogger("websockets.client")``.
            See the :doc:`logging guide <../../topics/logging>` for details.
        create_connection: Factory for the :class:`ClientConnection` managing
            the connection. Set it to a wrapper or a subclass to customize
            connection handling.

    Any other keyword arguments are passed to :func:`~socket.create_connection`.

    Raises:
        InvalidURI: If ``uri`` isn't a valid WebSocket URI.
        OSError: If the TCP connection fails.
        InvalidHandshake: If the opening handshake fails.
        TimeoutError: If the opening handshake times out.

    Nssl_contextzssl_context was renamed to sslz-ssl argument is incompatible with a ws:// URIunixFpathzmissing path argumentz(path and sock arguments are incompatiblerB   zunsupported compression: r.   T)rE   )rF   rG   rH   rK   rL   r   )$popwarningswarnDeprecationWarningr   secure	TypeErrorr
   r	   
ValueErrorr   r   r   AF_UNIXSOCK_STREAM
settimeoutr.   r9   r   
setdefaultrM   hostport
setsockoptIPPROTO_TCPTCP_NODELAY
ssl_modulecreate_default_contextwrap_socketr   	Exceptioncloser5   Zclose_socketZrecv_events_threadjoin)rO   rC   rD   rE   rF   rG   rH   r,   r-   rI   rJ   r   rK   rL   rM   rP   ZwsurirR   rS   deadliner   
connectionr(   r(   r)   r   v   s    W










)rS   rO   rP   r    c                 K  sD   |dkr.| ddkr*| ddkr*d}nd}tf |d| d|S )a  
    Connect to a WebSocket server listening on a Unix socket.

    This function accepts the same keyword arguments as :func:`connect`.

    It's only available on Unix.

    It's mainly useful for debugging servers listening on Unix sockets.

    Args:
        path: File system path to the Unix socket.
        uri: URI of the WebSocket server. ``uri`` defaults to
            ``ws://localhost/`` or, when a ``ssl`` is provided, to
            ``wss://localhost/``.

    NrD   rQ   zws://localhost/zwss://localhost/T)rO   rR   rS   )getr   )rS   rO   rP   r(   r(   r)   r   5  s
    )NN)'
__future__r   r   rD   rd   r!   rU   typingr   r   clientr   Zdatastructuresr   Zextensions.baser   Zextensions.permessage_deflater	   r0   r
   Zhttp11r   r   r   r   r   r   r   r   rO   r   rk   r   utilsr   __all__r   r   r   r(   r(   r(   r)   <module>   sJ   
a2 A  