
=\•j÷8  ã               @   sã   d  Z  d d l Z d d l 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	 d d l
 m Z m Z d d l Td d l m Z d g Z Gd	 d
 „  d
 ƒ Z Gd d „  d ƒ Z Gd d „  d e ƒ Z d S)z

é    Né   )ÚABNF)Ú	WebSocketÚgetdefaulttimeout)Ú*)Ú_loggingÚWebSocketAppc               @   s.   e  Z d  Z d Z d d „  Z d d „  Z d S)Ú
Dispatcherz
    Dispatcher
    c             C   s   | |  _  | |  _ d  S)N)ÚappÚping_timeout)Úselfr
   r   © r   ú:/tmp/pip-build-jxowagp5/websocket-client/websocket/_app.pyÚ__init__/   s    	zDispatcher.__init__c             C   s^   xW |  j  j rY t j |  j  j j f f  f  |  j ƒ \ } } } | rO | ƒ  sO P| ƒ  q Wd  S)N)r
   Úkeep_runningÚselectÚsockr   )r   r   Úread_callbackÚcheck_callbackÚrÚwÚer   r   r   Úread3   s    *	zDispatcher.readN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r   r   r	   +   s   r	   c               @   s:   e  Z d  Z d Z d d „  Z d d „  Z d d „  Z d S)	ÚSSLDispatcherz
    SSLDispatcher
    c             C   s   | |  _  | |  _ d  S)N)r
   r   )r   r
   r   r   r   r   r   A   s    	zSSLDispatcher.__init__c             C   s:   x3 |  j  j r5 |  j ƒ  } | r+ | ƒ  s+ P| ƒ  q Wd  S)N)r
   r   r   )r   r   r   r   r   r   r   r   r   E   s    	zSSLDispatcher.readc             C   sM   |  j  j j } | j ƒ  r" | g St j | f f  f  |  j ƒ \ } } } | S)N)r
   r   Úpendingr   r   )r   r   r   r   r   r   r   r   r   M   s
    'zSSLDispatcher.selectN)r   r   r   r   r   r   r   r   r   r   r   r   =   s   r   c               @   sÐ   e  Z d  Z d Z d d d d d d d d d d d d d d d „ Z e j d d „ Z d d	 „  Z d
 d „  Z	 d d d d d d d d d d d d d d d d d „ Z
 d d „  Z d d „  Z d d „  Z d S)r   z_
    Higher level of APIs are provided. The interface is like JavaScript WebSocket object.
    NTc             C   s¯   | |  _  | d k	 r | n g  |  _ | |  _ | |  _ | |  _ | |  _ | |  _ | |  _ | |  _ | |  _	 |	 |  _
 d |  _ | |  _ d |  _ d |  _ d |  _ | |  _ d S)a4	  
        WebSocketApp initialization

        Parameters
        ----------
        url: <type>
            websocket url.
        header: list or dict
            custom header for websocket handshake.
        on_open: <type>
            callable object which is called at opening websocket.
            this function has one argument. The argument is this class object.
        on_message: <type>
            callable object which is called when received data.
            on_message has 2 arguments.
            The 1st argument is this class object.
            The 2nd argument is utf-8 string which we get from the server.
        on_error: <type>
            callable object which is called when we get error.
            on_error has 2 arguments.
            The 1st argument is this class object.
            The 2nd argument is exception object.
        on_close: <type>
            callable object which is called when closed the connection.
            this function has one argument. The argument is this class object.
        on_cont_message: <type>
            callback object which is called when receive continued
            frame data.
            on_cont_message has 3 arguments.
            The 1st argument is this class object.
            The 2nd argument is utf-8 string which we get from the server.
            The 3rd argument is continue flag. if 0, the data continue
            to next frame data
        on_data: <type>
            callback object which is called when a message received.
            This is called before on_message or on_cont_message,
            and then on_message or on_cont_message is called.
            on_data has 4 argument.
            The 1st argument is this class object.
            The 2nd argument is utf-8 string which we get from the server.
            The 3rd argument is data type. ABNF.OPCODE_TEXT or ABNF.OPCODE_BINARY will be came.
            The 4th argument is continue flag. if 0, the data continue
        keep_running: <type>
            this parameter is obsolete and ignored.
        get_mask_key: func
            a callable to produce new mask keys,
            see the WebSocket.set_mask_key's docstring for more information
        cookie: str
            cookie value.
        subprotocols: <type>
            array of available sub protocols. default is None.
        NFr   )ÚurlÚheaderÚcookieÚon_openÚ
on_messageÚon_dataÚon_errorÚon_closeÚon_pingÚon_pongÚon_cont_messager   Úget_mask_keyr   Úlast_ping_tmÚlast_pong_tmÚsubprotocols)r   r   r    r"   r#   r%   r&   r'   r(   r)   r   r*   r!   r-   r$   r   r   r   r   [   s"    ;															zWebSocketApp.__init__c             C   s5   |  j  s% |  j  j | | ƒ d k r1 t d ƒ ‚ d S)a  
        send message

        Parameters
        ----------
        data: <type>
            Message to send. If you set opcode to OPCODE_TEXT,
            data must be utf-8 string or unicode.
        opcode: <type>
            Operation code of data. default is OPCODE_TEXT.
        r   zConnection is already closed.N)r   ÚsendZ"WebSocketConnectionClosedException)r   ÚdataÚopcoder   r   r   r.   ©   s    %zWebSocketApp.sendc             K   s/   d |  _  |  j r+ |  j j | �  d |  _ d S)z-
        Close websocket connection.
        FN)r   r   Úclose)r   Úkwargsr   r   r   r1   º   s    		zWebSocketApp.closec             C   s…   x~ | j  | ƒ s€ t j ƒ  |  _ |  j r y |  j j | ƒ Wq t k
 r| } z t j d j | ƒ ƒ PWYd  d  } ~ Xq Xq Wd  S)Nz send_ping routine terminated: {})	ÚwaitÚtimer+   r   ZpingÚ	Exceptionr   ÚwarningÚformat)r   ÚintervalÚeventÚpayloadÚexr   r   r   Ú
_send_pingÃ   s    	zWebSocketApp._send_pingr   Ú Fc                s…  ˆ d k	 r ˆ d k r d ‰ ˆ rB | rB | ˆ k rB t  d ƒ ‚ | sN g  } | sZ i  } ˆ j ro t  d ƒ ‚ d ‰ d ˆ _ d ˆ _ d ˆ _ d ‡  ‡ ‡ f d d † ‰ ykt ˆ j d | d	 | d
 ˆ j d k	 d |
 d | rç d n d ƒˆ _ ˆ j j t	 ƒ  ƒ ˆ j j
 ˆ j d ˆ j d ˆ j d | d | d | d |	 d ˆ j d | d | d | d | ƒ| syˆ j ˆ ƒ } ˆ j ˆ j ƒ | rÒt j ƒ  ‰  t j d ˆ j d | ˆ  | f ƒ ‰ d ˆ _ ˆ j ƒ  ‡ ‡ f d d †  } ‡ ‡ f d d †  } | j ˆ j j | | ƒ Wnh t t t f k
 r€} z? ˆ j ˆ j | ƒ t | t ƒ rY‚  ˆ ƒ  t | t ƒ SWYd d } ~ Xn Xd S)aË  
        Run event loop for WebSocket framework.

        This loop is an infinite loop and is alive while websocket is available.

        Parameters
        ----------
        sockopt: tuple
            values for socket.setsockopt.
            sockopt must be tuple
            and each element is argument of sock.setsockopt.
        sslopt: dict
            optional dict object for ssl socket option.
        ping_interval: int or float
            automatically send "ping" command
            every specified period (in seconds)
            if set to 0, not send automatically.
        ping_timeout: int or float
            timeout (in seconds) if the pong message is not received.
        ping_payload: str
            payload message to send with each ping.
        http_proxy_host: <type>
            http proxy host name.
        http_proxy_port: <type>
            http proxy port. If not set, set to 80.
        http_no_proxy: <type>
            host names, which doesn't use proxy.
        skip_utf8_validation: bool
            skip utf8 validation.
        host: str
            update host header.
        origin: str
            update origin header.
        dispatcher: <type>
            customize reading data from socket.
        suppress_origin: bool
            suppress outputting origin header.

        Returns
        -------
        teardown: bool
            False if caught KeyboardInterrupt, True if other exception was raised during a loop
        Nr   z#Ensure ping_interval > ping_timeoutzsocket is already openedTc                sƒ   ˆ r& ˆ j  ƒ  r& ˆ  j ƒ  ˆ j ƒ  d ˆ _ ˆ j rE ˆ j j ƒ  ˆ j |  rZ |  j n d ƒ } ˆ j ˆ j	 | Œ d ˆ _ d S)z³
            Tears down the connection.

            If close_frame is set, we will invoke the on_close handler with the
            statusCode and reason from there.
            FN)
Úis_aliveÚsetÚjoinr   r   r1   Ú_get_close_argsr/   Ú	_callbackr&   )Zclose_frameZ
close_args)r9   r   Úthreadr   r   Úteardown  s    

		z*WebSocketApp.run_forever.<locals>.teardownÚsockoptÚssloptZfire_cont_frameÚskip_utf8_validationZenable_multithreadFr    r!   Úhttp_proxy_hostÚhttp_proxy_portÚhttp_no_proxyÚhttp_proxy_authr-   ÚhostÚoriginÚsuppress_originÚ
proxy_typeÚtargetÚargsc                 s\  ˆ  j  s ˆ ƒ  Sˆ  j j d ƒ \ }  } |  t j k rA ˆ | ƒ S|  t j k ri ˆ  j ˆ  j | j ƒ nï |  t j	 k r  t
 j
 ƒ  ˆ  _ ˆ  j ˆ  j | j ƒ n¸ |  t j k rù ˆ  j rù ˆ  j ˆ  j | j | j | j ƒ ˆ  j ˆ  j | j | j ƒ n_ | j } t j r)|  t j k r)| j d ƒ } ˆ  j ˆ  j | | j d ƒ ˆ  j ˆ  j | ƒ d S)NTzutf-8)r   r   Zrecv_data_framer   ZOPCODE_CLOSEZOPCODE_PINGrB   r'   r/   ZOPCODE_PONGr4   r,   r(   ZOPCODE_CONTr)   r$   r0   ZfinÚsixÚPY3ÚOPCODE_TEXTÚdecoder#   )Zop_codeÚframer/   )r   rD   r   r   r   <  s*    	
	z&WebSocketApp.run_forever.<locals>.readc                 sv   ˆ  rr t  j  ƒ  ˆ j ˆ  k }  ˆ j ˆ j d k  } ˆ j ˆ j ˆ  k } ˆ j rr |  rr | sf | rr t d ƒ ‚ d S)Nr   zping/pong timed outT)r4   r+   r,   ZWebSocketTimeoutException)Zhas_timeout_expiredZ$has_pong_not_arrived_after_last_pingZhas_pong_arrived_too_late)r   r   r   r   ÚcheckV  s    	z'WebSocketApp.run_forever.<locals>.check)ZWebSocketExceptionr   r   r+   r,   r   r*   r)   Ú
settimeoutr   Úconnectr   r    r!   r-   Úcreate_dispatcherrB   r"   Ú	threadingÚEventÚThreadr<   ÚdaemonÚstartr   r5   ÚKeyboardInterruptÚ
SystemExitr%   Ú
isinstance)r   rE   rF   Zping_intervalr   Zping_payloadrH   rI   rJ   rK   rG   rL   rM   Z
dispatcherrN   rO   r   rW   r   r   )r9   r   r   rD   rC   r   Úrun_foreverÍ   s^    4							
zWebSocketApp.run_foreverc             C   s5   | p	 d } |  j  j ƒ  r( t |  | ƒ St |  | ƒ S)Né
   )r   Zis_sslr   r	   )r   r   Útimeoutr   r   r   rZ   k  s    zWebSocketApp.create_dispatcherc             C   sé   t  j d k  rA |  j s: t t j |  j ƒ j ƒ d k rp g  Sn/ |  j sl t t j |  j ƒ j ƒ d k rp g  S| rß t | ƒ d k rß d t j	 | d d … ƒ t j	 | d d … ƒ } | d d … j
 d ƒ } | | g Sd d g S)	z—
        _get_close_args extracts the code, reason from the close body
        if they exists, and if the self.on_close except three arguments
        é   r   é   é   r   Nzutf-8)rf   r   )ÚsysÚversion_infor&   ÚlenÚinspectZ
getargspecrQ   ZgetfullargspecrR   Úbyte2intrU   )r   r/   ÚcodeÚreasonr   r   r   rA   r  s    ++4
zWebSocketApp._get_close_argsc             G   sŠ   | r† y | |  | Œ Wnl t  k
 r… } zL t j d j | | ƒ ƒ t j ƒ  rs t j ƒ  \ } } } t j | ƒ WYd  d  } ~ Xn Xd  S)Nzerror from callback {}: {})	r5   r   Úerrorr7   ZisEnabledForDebugri   Úexc_infoÚ	tracebackÚprint_tb)r   ÚcallbackrQ   r   Ú_Útbr   r   r   rB   †  s    zWebSocketApp._callback)r   r   r   r   r   r   rT   r.   r1   r<   rc   rZ   rA   rB   r   r   r   r   r   V   s,   			H	
	—)r   rl   r   ri   r[   r4   rr   rR   Z_abnfr   Z_corer   r   Ú_exceptionsr=   r   Ú__all__r	   r   Úobjectr   r   r   r   r   Ú<module>   s   
	