U
    c                     @   s\   d 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 dd Z	G dd dej
jZdS )	z9Tornado websocket handler to serve a terminal interface.
    N)gen)run_on_executorc                 C   s   t | tr| dS | S )Nzutf-8)
isinstancebytesdecode)s r   2lib/python3.8/site-packages/terminado/websocket.py_cast_unicode   s    

r
   c                       s   e Zd ZdZdd ZdddZd fdd	Zd	d
 Zdd Ze	j
dd Zdd Zdd ZdeddddZedddd Z  ZS )
TermSocketz Handler for a terminal websocketc                 C   sN   || _ d| _d| _d | _|j| _tt| _	d| _
ttdddk| _d S )N )NNZLOG_TERMINAL_OUTPUTZfalsetrue)term_manager	term_namesizeterminalZblocking_io_executor_blocking_io_executorloggingZ	getLogger__name___logger_user_commandstrlowerosgetenv_enable_output_logging)selfr   r   r   r	   
initialize   s    zTermSocket.initializeNc                 C   s   |  |p| jjdS )z1Deprecated: backward-compat for terminado <= 0.5.ZOrigin)Zcheck_originZrequestZheadersget)r   originr   r   r	   origin_check&   s    zTermSocket.origin_checkc                    s   t  | | jd| t|}|p(d| _| j|| _| jj	
|  | di g | jd| j d}| jj }|s|q| }||7 }qv|r| | dS )zWebsocket connection opened.

        Call our terminal manager to get a terminal, and connect to it as a
        client.
        zTermSocket.open: %sZttyZsetupzTermSocket.open: Opened %sr   N)superopenr   infor
   r   r   Zget_terminalr   clientsappendsend_json_messageZread_buffercopypoplefton_pty_read)r   Zurl_componentZbufferedZpreopen_bufferr   	__class__r   r	   r"   *   s     

zTermSocket.openc                 C   s   |  d|g dS )z$Data read from pty; send to frontendstdoutN)r&   r   textr   r   r	   r)   G   s    zTermSocket.on_pty_readc                 C   sL   t |}| | | jrH|d dkrHt|d trH| d|d   d S )Nr   r,      zSTDOUT: )jsondumpsZwrite_messager   r   r   log_terminal_output)r   ZcontentZjson_msgr   r   r	   r&   K   s
    

zTermSocket.send_json_messagec                 c   s   t |}|d }| jdk	s t|dkrx| |d V  | jr|d dkrd| d| j  d| _q|  j|d 7  _n |dkr|dd	 | _| j	  dS )
zHandle incoming websocket message

        We send JSON arrays, where the first element is a string indicating
        what kind of message this is. Data associated with the message follows.
        r   Nstdinr/   zSTDIN: r   Zset_size   )
r0   loadsr   AssertionErrorstdin_to_ptyprocr   r2   r   r   resize_to_smallest)r   messageZcommandZmsg_typer   r   r	   
on_messageS   s    
zTermSocket.on_messagec                 C   s:   | j d | jr*| jj|  | j  | j|  dS )zHandle websocket closing.

        Disconnect from our terminal, and tell the terminal manager we're
        disconnecting.
        zWebsocket closedN)r   r#   r   r$   remover9   r   Zclient_disconnectedr   r   r   r	   on_closej   s
    
zTermSocket.on_closec                 C   s    |  ddg |   d| _dS )z9Terminal closed: tell the frontend, and close the socket.Z
disconnectr/   N)r&   closer   r=   r   r   r	   on_pty_diedv   s    zTermSocket.on_pty_diedr   )logreturnc                 C   s   | j | dS )zg
        Logs the terminal input/output
        :param log: log line to write
        :return:
        N)r   debug)r   rA   r   r   r	   r2   |   s    zTermSocket.log_terminal_outputr   )executorc                 C   s   | j dk	r| j j| dS )a   Handles stdin messages sent on the websocket.

        This is a blocking call that should NOT be performed inside the
        server primary event loop thread. Messages must be handled
        asynchronously to prevent blocking on the PTY buffer.
        N)r   Zptyprocwriter-   r   r   r	   r8      s    
zTermSocket.stdin_to_ptyproc)N)N)r   )r   
__module____qualname____doc__r   r    r"   r)   r&   r   	coroutiner;   r>   r@   r   r2   r   r8   __classcell__r   r   r*   r	   r      s   

r   )rH   r0   r   r   Ztornado.websocketZtornador   Ztornado.concurrentr   r
   Z	websocketZWebSocketHandlerr   r   r   r   r	   <module>   s   