ó {fc@sÖdZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl Z ddl Z ddlZd„Zd„Ze je jeeƒddZdZdejfd „ƒYZiZe j d ƒZe j d ƒZd efd „ƒYZd efd„ƒYZd„Zdefd„ƒYZdejefd„ƒYZdefd„ƒYZ defd„ƒYZ!d„Z"d„Z#defd„ƒYZ$dS(sRPC Implementation, originally written for the Python Idle IDE For security reasons, GvR requested that Idle's Python execution server process connect to the Idle process, which listens for the connection. Since Idle has only one client per server, this was not a limitation. +---------------------------------+ +-------------+ | SocketServer.BaseRequestHandler | | SocketIO | +---------------------------------+ +-------------+ ^ | register() | | | unregister()| | +-------------+ | ^ ^ | | | | + -------------------+ | | | | +-------------------------+ +-----------------+ | RPCHandler | | RPCClient | | [attribute of RPCServer]| | | +-------------------------+ +-----------------+ The RPCServer handler class is expected to provide register/unregister methods. RPCHandler inherits the mix-in class SocketIO, which provides these methods. See the Idle run.main() docstring for further information on how this was accomplished in Idle. iÿÿÿÿNcCs+tj|ƒ}t|tjƒs't‚|S(N(tmarshaltloadst isinstancettypestCodeTypetAssertionError(tmstco((s#/usr/lib64/python2.7/idlelib/rpc.pyt unpickle_code-scCs4t|tjƒst‚tj|ƒ}t|ffS(N(RRRRRtdumpsR(RR((s#/usr/lib64/python2.7/idlelib/rpc.pyt pickle_code2siis 127.0.0.1t RPCServercBs8eZdd„Zd„Zd„Zd„Zd„ZRS(cCs/|dkrt}ntjj|||ƒdS(N(tNonet RPCHandlert SocketServert TCPServert__init__(tselftaddrt handlerclass((s#/usr/lib64/python2.7/idlelib/rpc.pyRGs  cCsdS(s@Override TCPServer method, no bind() phase for connecting entityN((R((s#/usr/lib64/python2.7/idlelib/rpc.pyt server_bindLscCs|jj|jƒdS(sÎOverride TCPServer method, connect() instead of listen() Due to the reversed connection, self.server_address is actually the address of the Idle Client to which we are connecting. N(tsockettconnecttserver_address(R((s#/usr/lib64/python2.7/idlelib/rpc.pytserver_activatePscCs|j|jfS(s:Override TCPServer method, return already connected socket(RR(R((s#/usr/lib64/python2.7/idlelib/rpc.pyt get_requestYscCsÂy‚Wn´tk r‚n¡tj}|dddIJ|dIJ|dtjƒjƒIJ|dI|IJ|dIt|ƒIJtjd|ƒ|d IJ|ddIJt j d ƒnXd S( sÜOverride TCPServer method Error message goes to __stderr__. No error message if exiting normally or socket raised EOF. Other exceptions not handled in server code will cause os._exit. s t-i(sUnhandled server exception!s Thread: %ssClient Address: s Request: tfiles# *** Unrecoverable, server exiting!iN( t SystemExittsyst __stderr__t threadingt currentThreadtgetNametreprt tracebackt print_exctost_exit(Rtrequesttclient_addressterf((s#/usr/lib64/python2.7/idlelib/rpc.pyt handle_error]s    N(t__name__t __module__R RRRRR*(((s#/usr/lib64/python2.7/idlelib/rpc.pyR Es    itSocketIOcBseZdZddd„Zd„Zd„Zd„Zd„Zd„Z d„Z d„Z d „Z d „Z d „Zd „Zd „Zd„Zd„Zd„Zd„Zd„Zd„Zd„ZdZdZdZd„Zd„Zd„Zd„Zd„Zd„Z d„Z!RS(icCsdtjƒ|_|dk r'||_n||_|dkrEt}n||_i|_i|_ dS(N( RR t sockthreadR t debuggingtsockt objecttabletobjtablet responsestcvars(RR0R2R/((s#/usr/lib64/python2.7/idlelib/rpc.pyR€s       cCs/|j}d|_|dk r+|jƒndS(N(R0R tclose(RR0((s#/usr/lib64/python2.7/idlelib/rpc.pyR5‹s   cCstjdƒdS(s!override for specific exit actioniN(R%R&(R((s#/usr/lib64/python2.7/idlelib/rpc.pytexithook‘scGsf|js dS|jdttjƒjƒƒ}x"|D]}|dt|ƒ}q7Wtj|IJdS(Nt (R/tlocationtstrRR R!RR(Rtargststa((s#/usr/lib64/python2.7/idlelib/rpc.pytdebug•s  # cCs||j|((s#/usr/lib64/python2.7/idlelib/rpc.pyt unregister s cCsÛ|jd|ƒy|\}\}}}}Wntk r@dSX||jkradd|ffS|j|}|dkr—i} t|| ƒd| fS|dkrÀi} t|| ƒd| fSt||ƒsàdd|ffSt||ƒ} y�|d kr5| ||Ž} t| tƒr+t | ƒ} nd| fS|d krat j || ||ffƒdSdd |fSWndt k r†‚nQtjk rœ‚n;d } tj| || |fIJtjdtjƒdSXdS(Ns localcall:tERRORsBad request formatsUnknown object id: %rt __methods__tOKt__attributes__sUnsupported method name: %rtCALLtQUEUEtQUEUEDsUnsupported message type: %ssU*** Internal Error: rpc.py:SocketIO.localcall() Object: %s Method: %s Args: %s Rt EXCEPTION(RCsBad request format(RIN(RJN(R=t TypeErrorR2t _getmethodst_getattributesthasattrtgetattrRt RemoteObjectt remotereft request_queuetputR RRterrorRRR#R$(RtseqR'thowR>t methodnameR:tkwargstobjtmethodst attributestmethodtrettmsg((s#/usr/lib64/python2.7/idlelib/rpc.pyt localcall¦sL            cCs8|jd||ƒ|j||||ƒ}|j|ƒS(Nsremotecall:asynccall: (R=t asynccallt asyncreturn(RR>RWR:RXRU((s#/usr/lib64/python2.7/idlelib/rpc.pyt remotecallÐscCs8|jd||ƒ|j||||ƒ}|j|ƒS(Nsremotequeue:asyncqueue: (R=t asyncqueueRa(RR>RWR:RXRU((s#/usr/lib64/python2.7/idlelib/rpc.pyt remotequeueÕscCs‰d||||ff}|jƒ}tjƒ|jkrUtjƒ}||j|RWR:RXR'RUtcvar((s#/usr/lib64/python2.7/idlelib/rpc.pyR`Ús  cCs‰d||||ff}|jƒ}tjƒ|jkrUtjƒ}||j|RWR:RXR'RURh((s#/usr/lib64/python2.7/idlelib/rpc.pyRcäs  cCsG|jd|ƒ|j|ddƒ}|jd||ƒ|j|ƒS(Ns#asyncreturn:%d:call getresponse(): twaitgš™™™™™©?sasyncreturn:%d:response: (R=t getresponsetdecoderesponse(RRUtresponse((s#/usr/lib64/python2.7/idlelib/rpc.pyRaîscCs«|\}}|dkr|S|dkr,dS|dkrI|jdƒdS|dkrp|jdƒ|jƒdS|dkr˜|jd|ƒt|‚nt||f‚dS( NRERIRJsdecoderesponse: EXCEPTIONtEOFsdecoderesponse: EOFRCsdecoderesponse: Internal ERROR:(R R=tdecode_interrupthookt RuntimeErrort SystemError(RRlRVtwhat((s#/usr/lib64/python2.7/idlelib/rpc.pyRkôs           cCs t‚dS(tN(tEOFError(R((s#/usr/lib64/python2.7/idlelib/rpc.pyRnscCs@y|jddddƒWntk r;|jdƒdSXdS(s¥Listen on socket until I/O not ready or EOF pollresponse() will loop looking for seq number None, which never comes, and exit on EOFError. tmyseqRigš™™™™™©?smainloop:returnN(RjR RsR=(R((s#/usr/lib64/python2.7/idlelib/rpc.pytmainloop s   cCsU|j||ƒ}|dk rQ|\}}|dkrQ||j|ƒf}qQn|S(NRE(t _getresponseR t_proxify(RRtRiRlRVRq((s#/usr/lib64/python2.7/idlelib/rpc.pyRjs    cCsEt|tƒrt||jƒSt|tjƒrAt|j|ƒS|S(N(Rt RemoteProxytRPCProxyR>RtListTypetmapRw(RRY((s#/usr/lib64/python2.7/idlelib/rpc.pyRws cCsÒ|jd|ƒtjƒ|jkrQx¦|j||ƒ}|dk r(|Sq(Wn}|j|}|jƒx||jkr‡|j ƒqkW|j|}|jd||fƒ|j|=|j|=|j ƒ|SdS(Ns_getresponse:myseq:s-_getresponse:%s: thread woke up: response: %s( R=RR R.t pollresponseR R4tacquireR3Ritrelease(RRtRiRlRh((s#/usr/lib64/python2.7/idlelib/rpc.pyRv's"         cCs|jd|_}|S(Ni(tnextseq(RRU((s#/usr/lib64/python2.7/idlelib/rpc.pyRe=scCsÿ|jd|dƒytj|ƒ}Wn0tjk rZtjdIt|ƒIJ‚nXtjdt |ƒƒ|}x�t |ƒdkrúy>t j g|j ggƒ\}}}|j j |t ƒ}Wn ttfk rìtd‚nX||}qzWdS(Nsputmessage:%d:isCannot pickle:s}|j|}|jƒd|j|<|jƒ|jƒq!W|jƒdS(s+action taken upon link being closed by peerR RmN(RmN( tEOFhookR=R4R}R R3R¡R~R6(RtkeyR¤((s#/usr/lib64/python2.7/idlelib/rpc.pyR Ës      cCsdS(sBClasses using rpc client/server can override to augment EOF actionN((R((s#/usr/lib64/python2.7/idlelib/rpc.pyR¥ØsN("R+R,RR RR5R6R=R@RBR_RbRdR`RcRaRkRnRuRjRwRvReRgR�R‘R–R•R�R”R›R|R R¥(((s#/usr/lib64/python2.7/idlelib/rpc.pyR-|s>      *               I RPcBseZRS((R+R,(((s#/usr/lib64/python2.7/idlelib/rpc.pyRPÞscCs t|ƒ}|t|((s#/usr/lib64/python2.7/idlelib/rpc.pyRQâs  RxcBseZd„ZRS(cCs ||_dS(N(R>(RR>((s#/usr/lib64/python2.7/idlelib/rpc.pyRés(R+R,R(((s#/usr/lib64/python2.7/idlelib/rpc.pyRxçsR cBs/eZeZdZd„Zd„Zd„ZRS(s#ScCs6||_tj||ƒtjj||||ƒdS(N(tcurrent_handlerR-RRtBaseRequestHandler(RR0Rtsvr((s#/usr/lib64/python2.7/idlelib/rpc.pyRñs cCs|jƒdS(s(handle() method required by SocketServerN(Ru(R((s#/usr/lib64/python2.7/idlelib/rpc.pythandleöscCs t||ƒS(N(Ry(RR>((s#/usr/lib64/python2.7/idlelib/rpc.pytget_remote_proxyús(R+R,tFalseR/R8RR«R¬(((s#/usr/lib64/python2.7/idlelib/rpc.pyR ìs   t RPCClientcBsAeZeZdZdZejejd„Z d„Z d„Z RS(s#CicCs9tj||ƒ|_|jj|ƒ|jjdƒdS(Ni(Rtlistening_socktbindtlisten(Rtaddresstfamilyttype((s#/usr/lib64/python2.7/idlelib/rpc.pyRscCsw|jjƒ\}}|jr4tjdI|IJn|dtkrWtj||ƒntjdI|IJtj ‚dS(Ns****** Connection request from is** Invalid host: ( R¯tacceptR/RRt LOCALHOSTR-RRRT(Rt working_sockR²((s#/usr/lib64/python2.7/idlelib/rpc.pyRµ s cCs t||ƒS(N(Ry(RR>((s#/usr/lib64/python2.7/idlelib/rpc.pyR¬s( R+R,R­R/R8RRtAF_INETt SOCK_STREAMRRµR¬(((s#/usr/lib64/python2.7/idlelib/rpc.pyR®ýs  RycBs8eZdZdZd„Zd„Zd„Zd„ZRS(cCs||_||_dS(N(tsockioR>(RRºR>((s#/usr/lib64/python2.7/idlelib/rpc.pyRs cCs¡|jdkr|jƒn|jj|ƒrDt|j|j|ƒS|jdkr`|jƒn||jkr”|jj |jd|fiƒ}|St |‚dS(Nt__getattribute__( t_RPCProxy__methodsR t_RPCProxy__getmethodsR�t MethodProxyRºR>t_RPCProxy__attributest_RPCProxy__getattributesRbRˆ(Rtnametvalue((s#/usr/lib64/python2.7/idlelib/rpc.pyt __getattr__s  cCs%|jj|jddiƒ|_dS(NRF((RºRbR>R¿(R((s#/usr/lib64/python2.7/idlelib/rpc.pyt__getattributes-scCs%|jj|jddiƒ|_dS(NRD((RºRbR>R¼(R((s#/usr/lib64/python2.7/idlelib/rpc.pyt __getmethods1sN( R+R,R R¼R¿RRÃRÀR½(((s#/usr/lib64/python2.7/idlelib/rpc.pyRys    cCs§x?t|ƒD]1}t||ƒ}t|dƒr d||RÁ(RRºR>RÁ((s#/usr/lib64/python2.7/idlelib/rpc.pyRJs  cOs%|jj|j|j||ƒ}|S(N(RºRbR>RÁ(RR:RXRÂ((s#/usr/lib64/python2.7/idlelib/rpc.pyRÆOs!(R+R,RRÆ(((s#/usr/lib64/python2.7/idlelib/rpc.pyR¾Hs (%t__doc__RR%RR…RR‚tcPickleR€RRžR#tcopy_regRRRR RR‡R¶RR R1RRRœR?R-RPRQRxR©R R®RyRLRMR¾(((s#/usr/lib64/python2.7/idlelib/rpc.pytsB                2ÿc