a h&@sddlZddlZddlZddlZddlmZmZmZmZm Z m Z m Z m Z e eZGdddeZGdddeZGdd d ejZGd d d eZdS) N) JsonError JsonObject JsonValue create_objectget_intget_strget_str_or_none typecheckedcsFeZdZUdZeed<d ededdfdd Zedd d Z Z S) CockpitProblemaA 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. attrsNJsonObject | None)problemmsgkwargsreturnc s.||d<t|||_tt|jd|dS)Nrmessage)rr super__init__r)selfrrr __class__4/usr/lib/python3.9/site-packages/cockpit/protocol.pyr*s zCockpitProblem.__init__rcCsD|jddkr:|jdur:t|jt|jj|j|jjdS|jSdS)Nrzinternal-error)cause)r __cause__dict tracebackformat_exceptionr __traceback__rrrr get_attrs/s  zCockpitProblem.get_attrs)N) __name__ __module__ __qualname____doc__r__annotations__strrrr" __classcell__rrrrr s  r cs&eZdZdeedfdd ZZS)CockpitProtocolErrorprotocol-error)rrcstj||ddS)N)r)rr)rrrrrrr9szCockpitProtocolError.__init__)r+)r#r$r%r(rr)rrrrr*8sr*c@s8eZdZUdZdZded<dZdZeed<dZ ded <dd d d Z d ddddZ e e ddddZe e e ddddZe eddddZeddddZeddddZeedd d!Zejdd"d#d$Zd ddd%d&Zd4d ddd'd(Ze edd)d*d+Zd5d,edd-d.d/Zeddd0d1Zed d2d3ZdS)6CockpitProtocolzA naive implementation of the Cockpit frame protocol We need to use this because Python's SelectorEventLoop doesn't supported buffered protocols. Nzasyncio.Transport | None transportF_closedzasyncio.Future[None] | None_communication_donercCsdSNrr!rrrdo_readyHszCockpitProtocol.do_readyzException | None)excrcCsdSr1rrr3rrr do_closedKszCockpitProtocol.do_closedcommandrrcCstdSr1NotImplementedErrorrr7rrrrtransport_control_receivedNsz*CockpitProtocol.transport_control_received)channelr7rrcCstdSr1r8)rr<r7rrrrchannel_control_receivedQsz(CockpitProtocol.channel_control_received)r<datarcCstdSr1r8)rr<r>rrrchannel_data_receivedTsz%CockpitProtocol.channel_data_received)framercCsP|d\}}}|dkrB|d}tdt|||||n ||dS)N r.asciiz.data received: %d bytes of data for channel %s) partitiondecodeloggerdebuglenr?control_received)rr@header_r>r<rrrframe_receivedWs  zCockpitProtocol.frame_received)r>rc Cszftt|t}t|d}t|dd}|durLtd|||||ntd||||Wn:tj t fy}zt d||WYd}~n d}~00dS)Nr7r<zchannel control received %sztransport control received %szcontrol message: ) r jsonloadsrrrErFr=r;ZJSONDecodeErrorrr*)rr>rr7r<r3rrrrHbs    z CockpitProtocol.control_receivedc Csz|d}WnRty`}z:t|dkrBt|dWYd}~Std|WYd}~n d}~00zt|d|}Wn.ty}ztd|WYd}~n d}~00|d}||}|t|krt||S|||||S)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. rA Nzsize line is too longzframe size is not an integerr)index ValueErrorrGr*intrK)rr>newliner3lengthstartendrrrconsume_one_framers      z!CockpitProtocol.consume_one_frame)r-rcCs6td|||_||jr2td|dS)Nzconnection_made(%s)z; but the protocol already was closed, so closing transport)rErFr-r2r/close)rr-rrrconnection_mades   zCockpitProtocol.connection_madecCstdd|_||dS)Nconnection_lost)rErFr-rWr4rrrrYs zCockpitProtocol.connection_lostcCs.|jr dSd|_|jr |j||dS)NT)r/r-rWr5r4rrrrWs  zCockpitProtocol.close)r<payloadrcCsbt|dt|}|d|dd}|jdurTtd|j|j||n tddS)z0Send a given payload (bytes) on channel (string) rBNzwriting to transport %sz cannot write to closed transport)rGencoder-rErFwrite)rr<rZZ frame_lengthrIrrrwrite_channel_datas  z"CockpitProtocol.write_channel_datar )rrrcKs:td||tjt||ddd}|d|dS)zCWrite a control message. See jsonutil.create_object() for details.zsending control message %r %r)indentr[N)rErFrLdumpsrr^r\)rrrZprettyrrr write_controlszCockpitProtocol.write_controlc CsxzD|j|7_|jrB||j}|dkr0WdS|j|d|_qWn.tyr}z||WYd}~n d}~00dS)Nr)bufferrVr*rW)rr>resultr3rrr data_receiveds zCockpitProtocol.data_receivedcCsdS)NFrr!rrr eof_receivedszCockpitProtocol.eof_received)N)N) r#r$r%r&r-r'rdr/boolr0r2r5r(rr;r=bytesr?rKrHrQrVasyncioZ BaseTransportrXrYrWr^rrcrfrgrrrrr,=s(         r,c@seZdZUdZded<dZded<dZdddd Zedd d d Z ddedd ddZ e eddddZ ddddZ de deedddZde dee dddZedd ddZdS)CockpitProtocolServerNz str | None init_hostz,dict[str, asyncio.Future[JsonObject]] | NoneauthorizationsrrcCstdSr1r8r!rrr do_send_initsz"CockpitProtocolServer.do_send_init)rrcCsdSr1r)rrrrrdo_initszCockpitProtocolServer.do_init)hostgrouprrcCstdSr1r8)rrprqrrrrdo_killszCockpitProtocolServer.do_killr6cCs|dkr6t|ddkrtdt|d|_||nL|dkr^|t|ddt|dd|n$|dkrr||ntd |d dS) Ninitversionrzincorrect version numberrpkillrq authorizezunexpected control message z received)rr*rrlrorrr do_authorizer:rrrr;s    z0CockpitProtocolServer.transport_control_receivedcCs |dSr1)rnr!rrrr2szCockpitProtocolServer.do_readyz int | None) challengetimeoutrrc s|jduri|_t|j}|jd7_t}zB||j|<|jdd||d|t||IdHW|j|S|j|0dS)Nrrv)r7rxcookie)N) rmr( next_auth_idrjZget_running_loopZ create_futurercwait_forpop)rrxryrrzZfuturerrrrequest_authorization_objects     z2CockpitProtocolServer.request_authorization_objectcs t|j||fi|IdHdS)NZresponse)rr~)rrxryrrrrrequest_authorizationsz+CockpitProtocolServer.request_authorizationcCs@t|d}|jdus||jvr,tddS|j||dS)Nrzzno matching authorize request)rrmrEZwarningZ set_result)rrrzrrrrws   z"CockpitProtocolServer.do_authorize)N)N)r#r$r%rlr'rmr{rnrrorrr(r;r2rr~rrwrrrrrks&      rk)rjrLZloggingrZjsonutilrrrrrrr r Z getLoggerr#rE Exceptionr r*Protocolr,rkrrrrs(