
    i#                         d dl Z d dlZd dlZd dlZddlmZmZmZmZm	Z	m
Z
mZmZ  ej                  e      Z G d de      Z G d de      Z G d d	e j&                        Z G d
 de      Zy)    N   )	JsonError
JsonObject	JsonValuecreate_objectget_intget_strget_str_or_nonetypecheckedc            	       N     e Zd ZU dZeed<   ddedddeddf fd	Zdefd
Z	 xZ
S )CockpitProblema  A type of exception that carries a problem code and a message.

    Depending on the scope, this is used to handle shutting down:

      - an individual channel (sends problem code in the close message)
      - peer connections (sends problem code in close message for each open channel)
      - the main stdio interaction with the bridge

    It is usually thrown in response to some violation of expected protocol
    when parsing messages, connecting to a peer, or opening a channel.
    attrsNproblemmsgJsonObject | Nonekwargsreturnc                 z    ||d<   t        ||      | _        t        |   t	        | j                  d|             y )Nr   message)r   r   super__init__r	   )selfr   r   r   	__class__s       2/usr/lib/python3/dist-packages/cockpit/protocol.pyr   zCockpitProblem.__init__   s5    #y"3/
Y@A    c                    | j                   d   dk(  rj| j                  ^t        | j                   t        j                  | j                  j
                  | j                  | j                  j                              S | j                   S )Nr   zinternal-error)cause)r   	__cause__dict	tracebackformat_exceptionr   __traceback__r   s    r   	get_attrszCockpitProblem.get_attrs#   sh    ::i $449S

)*D*D(($..$..:V:V+   ::r   N)__name__
__module____qualname____doc__r   __annotations__strr   r   r$   __classcell__r   s   @r   r   r      sE    
 B B*= BPY B^b B
: r   r   c                   *     e Zd Zddedef fdZ xZS )CockpitProtocolErrorr   r   c                 (    t         |   ||       y )N)r   )r   r   )r   r   r   r   s      r   r   zCockpitProtocolError.__init__-   s    '2r   )zprotocol-error)r&   r'   r(   r+   r   r,   r-   s   @r   r/   r/   ,   s    3 3c 3 3r   r/   c                   <   e Zd ZU dZdZded<   dZdZeed<   dZ	ded	<   d#dZ
d$dZdeded
dfdZdededed
dfdZdeded
dfdZded
dfdZded
dfdZded
efdZdej.                  d
dfdZd$dZd%d$dZdeded
dfdZd%ddded
dfd Zded
dfd!Zd
efd"Zy)&CockpitProtocolzA naive implementation of the Cockpit frame protocol

    We need to use this because Python's SelectorEventLoop doesn't supported
    buffered protocols.
    Nzasyncio.Transport | None	transportr   F_closedzasyncio.Future[None] | None_communication_doner   c                      y r%    r#   s    r   do_readyzCockpitProtocol.do_ready<       r   c                      y r%   r7   r   excs     r   	do_closedzCockpitProtocol.do_closed?   r9   r   commandr   c                     t         r%   NotImplementedErrorr   r>   r   s      r   transport_control_receivedz*CockpitProtocol.transport_control_receivedB       !!r   channelc                     t         r%   r@   )r   rE   r>   r   s       r   channel_control_receivedz(CockpitProtocol.channel_control_receivedE   rD   r   datac                     t         r%   r@   )r   rE   rH   s      r   channel_data_receivedz%CockpitProtocol.channel_data_receivedH   rD   r   framec                     |j                  d      \  }}}|dk7  rD|j                  d      }t        j                  dt	        |      |       | j                  ||       y | j                  |       y )N   
r   asciiz.data received: %d bytes of data for channel %s)	partitiondecodeloggerdebuglenrJ   control_received)r   rK   header_rH   rE   s         r   frame_receivedzCockpitProtocol.frame_receivedK   sa    //%04S=mmG,GLLI3t9V]^&&w5 !!$'r   c                    	 t        t        j                  |      t              }t	        |d      }t	        |dd       }|*t
        j                  d|       | j                  |||       y t
        j                  d|       | j                  ||       y # t        j                  t        f$ r}t        d|      |d }~ww xY w)Nr>   rE   zchannel control received %sztransport control received %szcontrol message: )r   jsonloadsr   r	   rQ   rR   rG   rC   JSONDecodeErrorr   r/   )r   rH   r   r>   rE   r<   s         r   rT   z CockpitProtocol.control_receivedV   s    	M!$**T"2D9Ggy1Ggy$7G":GD--gwH<gF//A$$i0 	M&):3''BCL	Ms   A'B *(B C ,B;;C c                 r   	 |j                  d      }	 t	        |d|       }|dz   }||z   }|t        |      kD  rt        |      |z
  S | j                  |||        |S # t        $ r2}t        |      dk  rt        |      dz
  cY d}~S t        d      |d}~ww xY w# t        $ r}t        d      |d}~ww xY w)zConsumes a single frame from view.

        Returns positive if a number of bytes were consumed, or negative if no
        work can be done because of a given number of bytes missing.
        rM   
   Nzsize line is too longzframe size is not an integerr   )index
ValueErrorrS   r/   intrW   )r   rH   newliner<   lengthstartends          r   consume_one_framez!CockpitProtocol.consume_one_framef   s    	Ijj'G	Phw(F !fnT?t9s?" 	DsO,
)  	I4y2~4y2~%&'>?SH		I  	P&'EFCO	Ps:   A B 	B'BBBB	B6%B11B6c                     t         j                  d|       t        |t        j                        sJ || _        | j                          | j                  r&t         j                  d       |j                          y y )Nzconnection_made(%s)z;  but the protocol already was closed, so closing transport)	rQ   rR   
isinstanceasyncio	Transportr3   r8   r4   close)r   r3   s     r   connection_madezCockpitProtocol.connection_made   sZ    *I6)W%6%6777"<<LLVWOO r   c                 z    t         j                  d       | j                  J d | _        | j                  |       y )Nconnection_lost)rQ   rR   r3   rj   r;   s     r   rm   zCockpitProtocol.connection_lost   s1    &'~~)))

3r   c                     | j                   ry d| _         | j                  r| j                  j                          | j                  |       y )NT)r4   r3   rj   r=   r;   s     r   rj   zCockpitProtocol.close   s6    <<>>NN  "sr   payloadc                 &   t        |dz         t        |      z   }| d| dj                  d      }| j                  ?t        j	                  d| j                         | j                  j                  ||z          yt        j	                  d       y)z0Send a given payload (bytes) on channel (string)
rN   Nzwriting to transport %sz cannot write to closed transport)rS   encoder3   rQ   rR   write)r   rE   ro   frame_lengthrU   s        r   write_channel_dataz"CockpitProtocol.write_channel_data   sy     7T>*S\9 >G9B/66w?>>%LL2DNNCNN  '!12LL;<r   r   r   r   c                     t         j                  d||       t        j                  t	        ||      d      dz   }| j                  d|j                                y)zCWrite a control message.  See jsonutil.create_object() for details.zsending control message %r %r   )indentrq    N)rQ   rR   rY   dumpsr   ru   rr   )r   r   r   prettys       r   write_controlzCockpitProtocol.write_control   sE    4c6BM#v6qADHFMMO4r   c                    	 | xj                   |z  c_         | j                   rC| j                  | j                         }|dk  ry | j                   |d  | _         | j                   rBy y # t        $ r}| j                  |       Y d }~y d }~ww xY w)Nr   )bufferre   r/   rj   )r   rH   resultr<   s       r   data_receivedzCockpitProtocol.data_received   st    	KK4K++//<Q;"kk&'2	 ++
 $ 	JJsOO	s   AA'  A' '	B0BBc                      y)NFr7   r#   s    r   eof_receivedzCockpitProtocol.eof_received   s    r   r   N)r<   zException | Noner   Nr%   ) r&   r'   r(   r)   r3   r*   r~   r4   boolr5   r8   r=   r+   r   rC   rG   bytesrJ   rW   rT   r`   re   rh   BaseTransportrk   rm   rj   ru   r   r|   r   r   r7   r   r   r2   r2   1   sC   
 -1I)0FGT9=6="# "
 "t "" "c "J "[_ ""S " "$ "	(E 	(d 	(MU Mt M e  >)>)> 4 	=# 	= 	=$ 	=5!4 5y 5UY 5	% 	D 	d r   r2   c            	           e Zd ZU dZded<   dZded<   dZddZd	eddfd
Z	ddddd	eddfdZ
ded	eddfdZddZ	 ddedddedefdZ	 ddedddedefdZd	eddfdZy)CockpitProtocolServerNz
str | None	init_hostz,dict[str, asyncio.Future[JsonObject]] | Noneauthorizationsr   r   c                     t         r%   r@   r#   s    r   do_send_initz"CockpitProtocolServer.do_send_init   rD   r   r   c                      y r%   r7   )r   r   s     r   do_initzCockpitProtocolServer.do_init   r9   r   hostgroupc                     t         r%   r@   )r   r   r   r   s       r   do_killzCockpitProtocolServer.do_kill   rD   r   r>   c                 0   |dk(  r=t        |d      dk7  rt        d      t        |d      | _        | j	                  |       y |dk(  r*| j                  t        |dd       t        |dd       |       y |dk(  r| j                  |       y t        d	| d
      )Ninitversionr   zincorrect version numberr   killr   	authorizezunexpected control message z	 received)r   r/   r	   r   r   r   r
   do_authorizerB   s      r   rC   z0CockpitProtocolServer.transport_control_received   s    fw	*a/*+EFF$Wf5DNLL!LL&$?QXZacgAhjqr#g&&)DWIY'WXXr   c                 $    | j                          y r%   )r   r#   s    r   r8   zCockpitProtocolServer.do_ready   s    r   	challengetimeoutz
int | Noner   c                   K   | j                   i | _         t        | j                        }| xj                  dz  c_        t        j                         j                         }	 || j                   |<    | j                  dd||d| t        j                  ||       d {   | j                   j                  |       S 7 # | j                   j                  |       w xY ww)Nr   r   )r>   r   cookier%   )	r   r+   next_auth_idrh   get_running_loopcreate_futurer|   wait_forpop)r   r   r   r   r   futures         r   request_authorization_objectz2CockpitProtocolServer.request_authorization_object   s      &"$DT&&'Q))+99;	,*0D'Dg[IV\g`fg ))&'::##F+ ;##F+s0   A C##>C !C"C %C#C C  C#c                 Z   K   t         | j                  ||fi | d {   d      S 7 	w)Nresponse)r	   r   )r   r   r   r   s       r   request_authorizationz+CockpitProtocolServer.request_authorization   s2      >T>>y'\U[\\^hii\s   +)
+c                     t        |d      }| j                  || j                  vrt        j                  d       y | j                  |   j	                  |       y )Nr   zno matching authorize request)r	   r   rQ   warning
set_result)r   r   r   s      r   r   z"CockpitProtocolServer.do_authorize   sP    (+&&8K8K*KNN:;F#..w7r   r   r%   )r&   r'   r(   r   r*   r   r   r   r   r   r   r+   rC   r8   r   r   r   r   r7   r   r   r   r      s    "I|"EINBIL"z d "L " "
 "W[ "Y# Y
 Yt Y
 7;,,'3,FO,	,  7;jj'3jFOj	j
8J 84 8r   r   )rh   rY   loggingr    jsonutilr   r   r   r   r   r	   r
   r   	getLoggerr&   rQ   	Exceptionr   r/   Protocolr2   r   r7   r   r   <module>r      sg        u u u			8	$Y 83> 3
Kg&& K^:8O :8r   