Ϫf_8dZddlZddlmZddlmZmZddlmZm Z m Z m Z ddl m Z ddlmZmZddlmZdd lmZmZmZdd lmZmZdd lmZdd lmZdd lmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2ddl3m4Z4m5Z5ddl6m7Z7m8Z8m9Z9m:Z:dZ;dZ<Gdde=Z>Gdde>Z?Gdde=Z@Gdde=ZAeGddZBGdde=ZCGddeZDeeDGd d!ZEGd"d#e$ZFee5eGd$d%e)ejZHe1d&eHGd'd(ZIGd)d*eje ZKGd+d,e'ejZLe1eKeLdAd-ZMGd.d/ejZOd0ZPd1ZQGd2d3ejZSGd4d5ejZUGd6d7e ZVee!Gd8d9ZWeeWe e!Gd:d;ZXGd<d=e$eXZYee eVGd>d?e$eXZZgd@Z[y)Ba Perspective Broker "This isn't a professional opinion, but it's probably got enough internet to kill you." --glyph Introduction ============ This is a broker for proxies for and copies of objects. It provides a translucent interface layer to those proxies. The protocol is not opaque, because it provides objects which represent the remote proxies and require no context (server references, IDs) to operate on. It is not transparent because it does I{not} attempt to make remote objects behave identically, or even similarly, to local objects. Method calls are invoked asynchronously, and specific rules are applied when serializing arguments. To get started, begin with L{PBClientFactory} and L{PBServerFactory}. @author: Glyph Lefkowitz N)md5) Interface implementer) Anonymous IAnonymous ICredentialsIUsernameHashedPassword)Portal)deferprotocol)styles)failurelogreflect)cmp comparable)registerAdapter)banana) CacheableCopyableIPBRoot Jellyable NoSuchMethod Referenceable RemoteCacheRemoteCacheObserver RemoteCopyRoot SerializableViewable ViewPointcopyTagssetCopierForClasssetCopierForClassTreesetFactoryForClasssetUnjellyableFactoryForClasssetUnjellyableForClasssetUnjellyableForClassTree) IJellyable IUnjellyable) _newInstanceglobalSecurityjellyunjellyiiS"ceZdZdZy) ProtocolErrorzN This error is raised when an invalid protocol statement is received. N__name__ __module__ __qualname____doc__3/usr/lib/python3/dist-packages/twisted/spread/pb.pyr0r0Tsr7r0ceZdZdZy)DeadReferenceErrorzx This error is raised when a method is called on a dead reference (one whose broker has been disconnected). Nr1r6r7r8r:r:Zsr7r:ceZdZdZy)Errora  This error can be raised to generate known error conditions. When a PB callable method (perspective_, remote_, view_) raises this error, it indicates that a traceback should not be printed, but instead, the string representation of the exception should be sent. Nr1r6r7r8r<r<asr7r<ceZdZdZdZy) RemoteErrora This class is used to wrap a string-ified exception from the remote side to be able to reraise it. (Raising string exceptions is no longer possible in Python 2.6+) The value of this exception will be a str() representation of the remote value. @ivar remoteType: The full import path of the exception class which was raised on the remote end. @type remoteType: C{str} @ivar remoteTraceback: The remote traceback. @type remoteTraceback: C{str} @note: It's not possible to include the remoteTraceback if this exception is thrown into a generator. It must be accessed as an attribute. cLtj||||_||_yN) Exception__init__ remoteTyperemoteTraceback)selfrCvaluerDs r8rBzRemoteError.__init__s!4'$.r7Nr2r3r4r5rBr6r7r8r>r>ls &/r7r>c(eZdZdZdZdZdZdZy) RemoteMethodz> This is a translucent reference to a remote message. c ||_||_y)zT Initialize with a L{RemoteReference} and the name of this message. N)objname)rErKrLs r8rBzRemoteMethod.__init__s r7cFt|j|jf|Sr@)rrKrLrEothers r8__cmp__zRemoteMethod.__cmp__sDHHdii(%00r7cDt|j|jfSr@)hashrKrLrEs r8__hash__zRemoteMethod.__hash__sTXXtyy)**r7c|jjjd|jj|jj|j j d||S)z8 Asynchronously invoke a remote method. r7utf-8)rKbroker _sendMessage perspectiveluidrLencode)rEargskws r8__call__zRemoteMethod.__call__sRxx++  HH HHMM II  W %     r7N)r2r3r4r5rBrPrTr^r6r7r8rIrIs1+  r7rIc eZdZy)PBConnectionLostN)r2r3r4r6r7r8r`r`sr7r`ceZdZdZdZy) IPerspectivea per*spec*tive, n. : The relationship of aspects of a subject to each other and to a whole: 'a perspective of history'; 'a need to view the problem in the proper perspective'. This is a Perspective Broker-specific wrapper for an avatar. That is to say, a PB-published view on to the business logic for the system's concept of a 'user'. The concept of attached/detached is no longer implemented by the framework. The realm is expected to implement such semantics if needed. cy)a This method is called when a network message is received. @arg broker: The Perspective Broker. @type message: str @arg message: The name of the method called by the other end. @type args: list in jelly format @arg args: The arguments that were passed by the other end. It is recommend that you use the `unserialize' method of the broker to decode this. @type kwargs: dict in jelly format @arg kwargs: The keyword arguments that were passed by the other end. It is recommended that you use the `unserialize' method of the broker to decode this. @rtype: A jelly list. @return: It is recommended that you use the `serialize' method of the broker on whatever object you need to return to generate the return value. Nr6)rWmessager\kwargss r8perspectiveMessageReceivedz'IPerspective.perspectiveMessageReceivedr7Nr2r3r4r5rfr6r7r8rbrbs   r7rbceZdZdZdZy)Avatara A default IPerspective implementor. This class is intended to be subclassed, and a realm should return an instance of such a subclass when IPerspective is requested of it. A peer requesting a perspective will receive only a L{RemoteReference} to a pb.Avatar. When a method is called on that L{RemoteReference}, it will translate to a method on the remote perspective named 'perspective_methodname'. (For more information on invoking methods on other objects, see L{flavors.ViewPoint}.) c|j||}|j||}t|d|z} ||i|}|j |||||S#t$rtj|d|d|wxYw)ai This method is called when a network message is received. This will call:: self.perspective_%(message)s(*broker.unserialize(args), **broker.unserialize(kw)) to handle the method; subclasses of Avatar are expected to implement methods using this naming convention. zperspective_%sz didn't accept z and ) unserializegetattr TypeErrorrmsg serialize)rErWrdr\r]methodstates r8rfz!Avatar.perspectiveMessageReceiveds!!$-   D )/'9: D'B'EtVT2>>  GGvhodV5= >  s A(A:Nrhr6r7r8rjrjs  ?r7rjceZdZdZddZy)AsReferenceablez6 A reference directed towards another object. c,t||dz|_y)NMessageReceived)rmremoteMessageReceived)rEobject messageTypes r8rBzAsReferenceable.__init__s%,V[CT5T%U"r7N)remoterGr6r7r8rtrts Vr7rtcReZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zy )RemoteReferencea] A translucent reference to a remote object. I may be a reference to a L{flavors.ViewPoint}, a L{flavors.Referenceable}, or an L{IPerspective} implementer (e.g., pb.Avatar). From the client's perspective, it is not possible to tell which except by convention. I am a "translucent" reference because although no additional bookkeeping overhead is given to the application programmer for manipulating a reference, return values are asynchronous. See also L{twisted.internet.defer}. @ivar broker: The broker I am obtained through. @type broker: L{Broker} cJ||_||_||_||_g|_y)z(internal) Initialize me with a broker and a locally-unique ID. The ID is unique only to the particular Perspective Broker instance. N)rZrW doRefCountrYdisconnectCallbacks)rErYrWrZr~s r8rBzRemoteReference.__init__s)   $&#% r7ct|sJ|jj|t|jdk(r&|jj |j yy)z Register a callback to be called if our broker gets disconnected. @param callback: a callable which will be called with one argument, this instance. N)callablerappendlenrWnotifyOnDisconnect _disconnectedrEcallbacks r8rz"RemoteReference.notifyOnDisconnect'sV!!!   ''1 t'' (A - KK * *4+=+= > .r7c|jj||js&|jj|jyy)zu Remove a callback that was registered with notifyOnDisconnect. @param callback: a callable N)rremoverWdontNotifyOnDisconnectrrs r8rz&RemoteReference.dontNotifyOnDisconnect3s>   ''1'' KK . .t/A/A B(r7cD|jD] }|| d|_y)zN Called if we are disconnected and have callbacks registered. N)rrs r8rzRemoteReference._disconnected=s(00 H TN #' r7cx|jr.|j|jk(sJdd|jfSy)zc If I am being sent back to where I came from, serialize as a local backreference. z6Can't send references to brokers other than their own.slocal)s unpersistablezReferences cannot be serialized)invokerrWrZ)rEjelliers r8jellyForzRemoteReference.jellyForEs? ?? w. HG H.TYY& &Fr7cp|j|jj|j|dd|S)Nr)rBrunserializingPerspective)rE unjellier unjellyLists r8 unjellyForzRemoteReference.unjellyForQs7    6 6    N   r7ct|ts|jd}|jj d|j |j |||S)a Asynchronously invoke a remote method. @type _name: L{str} @param _name: the name of the remote method to invoke @param args: arguments to serialize for the remote function @param kw: keyword arguments to serialize for the remote function. @rtype: L{twisted.internet.defer.Deferred} @returns: a Deferred which will be fired when the result of this remote call is received. utf8r7) isinstancebytesr[rWrXrYrZ)rE_namer\r]s r8 callRemotezRemoteReference.callRemoteZsL%'LL(E {{'' !!499eT2  r7ct||S)zX @param key: The key. @return: A L{RemoteMethod} for this key. )rI)rEkeys r8 remoteMethodzRemoteReference.remoteMethodps D#&&r7ct|tr9|j|jk(r t|j|jSt|j|S)zM @param other: another L{RemoteReference} to compare me to. )rr|rWrrZrNs r8rPzRemoteReference.__cmp__xsD e_ -||t{{*499ejj114;;&&r7c|jS)z Hash me. )rZrSs r8rTzRemoteReference.__hash__syyr7ch|jr&|jj|jyy)zD Do distributed reference counting on finalization. N)r~rW sendDecRefrZrSs r8__del__zRemoteReference.__del__s& ?? KK " "499 - r7N)r2r3r4r5rBrrrrrrrrPrTrr6r7r8r|r|s@$ & ?C( G ,'' .r7r|rzc0eZdZdZddZdefdZdZdZy) Localz3 (internal) A reference to a local object. Nc.||_||_d|_y)z Initialize. rN)rxrYrefcount)rErxrYs r8rBzLocal.__init__s & r7returnc<d|jd|jdS)Nz )rxrrSs r8__repr__zLocal.__repr__sDKK?% a@@r7cB|jdz|_|jS)zi Increment the reference count. @return: the reference count after incrementing rrrSs r8increfz Local.incref  ) }}r7cB|jdz |_|jS)zi Decrement the reference count. @return: the reference count after decrementing rrrSs r8decrefz Local.decrefrr7r@) r2r3r4r5rBstrrrrr6r7r8rrs$A#Ar7rceZdZdZdZdZy)CopyableFailurez} A L{flavors.RemoteCopy} and L{flavors.Copyable} version of L{twisted.python.failure.Failure} for serialization. rc|jj}d|d<g|d<g|d<t|j|d<t |j t r|j |d<n1tj|j jd|d<|jr|j|d<|Sd |d<|S) z Collect state related to the exception which occurred, discarding state which cannot reasonably be serialized. NtbframesstackrFtyperV tracebackzTraceback unavailable ) __dict__copyrrFrrrrqualr[unsafeTracebacks getTraceback)rErrs r8getStateToCopyzCopyableFailure.getStateToCopys  ""$d hgTZZg dii ' IIE&M#LL3::7CE&M  !%!2!2!4E+  ";E+  r7N)r2r3r4r5rrr6r7r8rrs r7rc&eZdZdZddZdZeZeZy) CopiedFailurea A L{CopiedFailure} is a L{pb.RemoteCopy} of a L{failure.Failure} transferred via PB. @ivar type: The full import path of the exception class which was raised on the remote end. @type type: C{str} @ivar value: A str() representation of the remote value. @type value: L{CopiedFailure} or C{str} @ivar traceback: The remote traceback. @type traceback: C{str} Nc|tj}|j}t|ts|j d}|j d|j |dz|jz|j dy)NrVzTraceback from remote host -- z:  )rlogfilerrrdecodewriterF)rEfileelideFrameworkCodedetail failureTypes r8printTracebackzCopiedFailure.printTracebacksf <;;Dii +s+%,,W5K 34 ;% 23 4r7cv|jt|j|j|jS)a Throw the original exception into the given generator, preserving traceback information if available. In the case of a L{CopiedFailure} where the exception type is a string, a L{pb.RemoteError} is thrown instead. @return: The next value yielded from the generator. @raise StopIteration: If there are no more values in the generator. @raise RemoteError: The wrapped remote exception. )throwr>rrFr)rEgs r8throwExceptionIntoGeneratorz)CopiedFailure.throwExceptionIntoGenerators(ww{499djj$..IJJr7)Nrdefault)r2r3r4r5rrprintBriefTracebackprintDetailedTracebackr6r7r8rrs   K)+r7rcHtt|j}||_|Sr@)r+rrr)failrfs r8failure2Copyablers_dmm4A)A Hr7c8eZdZdZdZdZdZdefdZdZ dZ dZ d Z d Z d Zd Zd ZdZdZdZdZdZdZdZdZdZdZdZdZdZd2dZdZdZ dZ!dZ"d3dZ#d4d Z$d!Z%d"Z&d#Z'd$Z(d%Z)d&Z*d'Z+d(Z,d)Z-d*Z.d+Z/d,Z0d-Z1d.Z2d/Z3d0Z4d1Z5y)5Brokerz$ I am a broker for objects. Nrc$tjj||d|_g|_g|_g|_i|_||_g|_ d|_ d|_ d|_ i|_ i|_i|_i|_i|_i|_yNr)rBananarB disconnected disconnectsfailuresconnects localObjectssecurity pageProducerscurrentRequestIDcurrentLocalIDrluidsremotelyCachedObjectsremotelyCachedLUIDslocallyCachedObjectswaitingForAnswers _localCleanup)rEisClientrs r8rBzBroker.__init__s tX.     !(,% &("#% $&!!#  r7ctt|jdz ddD]?}|j|}|j|j r3|j|=A|js|j j yy)zM Called when the consumer attached to me runs out of buffer. rN)rangerr sendNextPage stillPaging transportunregisterProducer)rEpageridxpagers r8resumeProducingzBroker.resumeProducing7s c$"4"4592rB 1H&&x0E    $$&&&x0  1 !! NN - - /"r7cyr@r6rSs r8pauseProducingzBroker.pauseProducingD r7cyr@r6rSs r8 stopProducingzBroker.stopProducingHrr7c|jj|t|jdk(r|jj |dyy)Nrr)rrrrregisterProducer)rErs r8registerPageProducerzBroker.registerPageProducerLsB !!%( t!! "a ' NN + +D! 4 (r7ct|trV|d}t|ts|jd}d|z}t ||d}|r ||ddy|j d|yt d)z: Evaluate an expression as it's received. rrzproto_%sNrsdidNotUnderstandzNon-list expression received.)rlistrrrmsendCallr0)rEsexpcommand methodNamerqs r8expressionReceivedzBroker.expressionReceivedQss dD !1gGgs+!..0#g-JT:t4FQR! 17; ?@ @r7cX||jk7rtd|jd|y)z Protocol message: (version version-number) Check to make sure that both ends of the protocol are speaking the same version dialect. @param vnum: The version number. zVersion Incompatibility:  N)versionr0)rEvnums r8 proto_versionzBroker.proto_versiones2 4<< ";DLL>4& QR R r7c&|j|y)z Utility method to send an expression to the other side of the connection. @param exp: The expression. N) sendEncoded)rEexps r8rzBroker.sendCallrs r7c4tjd|zy)a  Respond to stock 'C{didNotUnderstand}' message. Log the command that was not understood and continue. (Note: this will probably be changed to close the connection or raise an exception in the future.) @param command: The command to log. zDidn't understand command: %rN)rro)rErs r8proto_didNotUnderstandzBroker.proto_didNotUnderstandzs /'9:r7c|jd|j|jD] } | d|_|j j|y#t$rt j YOwxYw)zF Initialize. Called after Banana negotiation is done. sversionN)rr r BaseExceptionrdeferrfactoryclientConnectionMaderEnotifiers r8connectionReadyzBroker.connectionReadysh j$,,/  H      ))$/!   sAA98A9c|jD] } | d|_y#t$rtjY4wxYwr@)rrrrrs r8connectionFailedzBroker.connectionFailedsB  H     !   s"AAc d|_d|_|jrM|jjD]0} |j t j t|2|jjD]8}|j}|j} |j|t|||:|j ddD] } | d|_d|_d|_d|_d|_ d|_d|_d|_y#t$rtjYwxYw#t$rtjYwxYw#t$rtjYwxYw)zg The connection was lost. @param reason: message to put in L{failure.Failure} rN)rrrvalueserrbackrFailurer`rrrrrxrYstoppedObservingrr localSecurityremoteSecurityrrr)rEreasondlobj cacheablerYrs r8connectionLostzBroker.connectionLostsd   ! !++224 !!IIgoo.>v.FGH ! ..557 D I**K **!4T9k!R  ((+ H     !%!"%)"#' $(! 5%!JJL!!   !   s5-DD5ED21D25EEE87E8cTt|sJ|jj|y)zQ @param notifier: callback to call when the Broker disconnects. N)rrrrs r8rzBroker.notifyOnDisconnects& !!! )r7cTt|sJ|jj|y)zT @param notifier: callback to call if the Broker fails to connect. N)rrrrs r8 notifyOnFailzBroker.notifyOnFails$ !!! X&r7ct|sJ|j |y|jj |y#t$rtjYywxYw)zN @param notifier: callback to call when the Broker connects. N)rrrrerrrrs r8notifyOnConnectzBroker.notifyOnConnectsT !!! ==    MM  *!   s?AAcZ |jj|y#t$rYywxYw)zY @param notifier: callback to remove from list of disconnect callbacks. N)rr ValueErrorrs r8rzBroker.dontNotifyOnDisconnects-      # #H -   s  **ct|tr|jd}|jj |}|y|j S)z Get a local object for a locally unique ID. @return: An object previously stored with L{registerReference} or L{None} if there is no object which corresponds to the given identifier. rN)rrr[rgetrx)rErZlobs r8localObjectForIDzBroker.localObjectForIDsD dC ;;v&D##D) ; zzr7rc|J|j}|jj|}|t|jt kDrS|j dz|_|j dkDr%|jjtdtd|j}t||j|<||j|<|S|j|j|S)z Store a persistent reference to a local object and map its id() to a generated, session-unique ID. @param object: a local object @return: the generated ID rz.Maximum PB reference count exceeded. Goodbye.z$Maximum PB reference count exceeded.) processUniqueIDrr0rrMAX_BROKER_REFSmaxBrokerRefsViolationsrloseConnectionr< newLocalIDrr)rErxpuidrZs r8registerReferencezBroker.registerReferences!!!%%'zz~~d# <4$$%7/3/K/Ka/O,//!3NN113 STTBCC??$D&+FmD  d ##DJJt     d # * * , r7c~t|tr|jd}|Jt||j|<y)z Store a special (string) ID for this object. This is how you specify a 'base' set of objects that the remote protocol can connect to. @param name: An ID. @param object: The object. rN)rrr[rr)rErLrxs r8setNameForLocalzBroker.setNameForLocals< dC ;;v&D!!!"'-$r7c`t|tr|jd}td||dS)a Returns an object from the remote name mapping. Note that this does not check the validity of the name, only creates a translucent reference for it. @param name: The name to look up. @return: An object which maps to the name. rNr)rrr[r|)rErLs r8 remoteForNamezBroker.remoteForName,s- dC ;;v&DtT433r7c|j}|jj|}||r|j|j |S)a @param instance: The instance to look up. @param incref: Flag to specify whether to increment the reference. @return: An ID that says what this instance is cached as remotely, or L{None} if it's not. )r5rr0rr)rEinstancerr:rZs r8cachedRemotelyAszBroker.cachedRemotelyAs;sL'')''++D1  6  & &t , 3 3 5 r7c4|j|jS)zk @param luid: The LUID to look up. @return: An instance which is cached remotely. )rrx)rErZs r8remotelyCachedForLUIDzBroker.remotelyCachedForLUIDKs ))$/666r7c|j}|j}t|jtkDrS|j dz|_|j dkDr%|j jtdtd||j|<t||j|j|<|S)z3 XXX @return: A new LUID. rr4z*Maximum PB cache count exceeded. Goodbye.z Maximum PB cache count exceeded.) r5r9rrr6r7rr8r<rrserializingPerspective)rErAr:rZs r8 cacheRemotelyzBroker.cacheRemotelySs '')  t)) *_ <+/+G+G!+KD (++a/--/KLL:; ;)-  &,14;V;V+W""4( r7c"||j|<y)zL(internal) Store a non-filled-out cached instance locally. NrrEcidrAs r8 cacheLocallyzBroker.cacheLocallyhs *2!!#&r7c$|j|}|Sr@rIrJs r8cachedLocallyAszBroker.cachedLocallyAsos,,S1r7c ft|tjr&|j|jd||||d|S||_||_||_||_ t||jd|d|_d|_d|_d|_S#d|_d|_d|_d|_wxYw)a Jelly an object according to the remote security rules for this broker. @param object: The object to jelly. @param perspective: The perspective. @param method: The method. @param args: Arguments. @param kw: Keyword arguments. c|Sr@r6)xs r8z"Broker.serialize..s!r7)rYrqr\r])callbackKeywordsN) rr Deferred addCallbacksrprF jellyMethod jellyArgsjellyKwr-r)rErxrYrqr\r]s r8rpzBroker.serializess fenn -   #.$  " M'2#!  d;*.D '#D !DNDL+/D '#D !DNDLs BB0ch||_ t||jd|d|_S#d|_wxYw)z Unjelly an sexp according to the local security rules for this broker. @param sexp: The object to unjelly. @param perspective: The perspective. N)rr.r)rErrYs r8rlzBroker.unserializes4)4% 14d;,0D )DD )s( 1cB|jdz|_|jS)z3 @return: A newly generated LUID. r)rrSs r8r9zBroker.newLocalIDs# #11A5"""r7cB|jdz|_|jS)z9 @return: A newly generated request ID. r)rrSs r8 newRequestIDzBroker.newRequestIDs# !% 5 5 9$$$r7c Vd}d}d} d|vr|d}|d=d|vr|d}|d=d|vr|s|rJd|d} |d=|jr td |j|||} |j|||} |j} | rOt j} | |j| <|s|r*tjd| j||nd} |j|d z| ||| | | | S#t$r*t j t jcYSwxYw) Nr pbcallback pberrbackpbanswerz*You can't specify a no-answer requirement.zCalling Stale Broker)rYrqz&warning! using deprecated "pbcallback"smessage)rr:rprr rrrr\rTrrrorUr)rEprefixrYobjectIDrdr\r]pbcpbeanswerRequirednetArgsnetKw requestIDrvals r8rXzBroker._sendMessagesX 2 \"C< " [/C;  c X,X X* ^N:   $%;< < 1nnT{7nSGNN2;wNOE%%' >>#D04D " "9 -c@A!!#s+D Z         ) 1::goo/0 0 1s(C550D('D(c F|j|j||||||yr@) _recvMessager2rErhrbrdrerfrgs r8 proto_messagezBroker.proto_messages-   ! !       r7c F|j|j||||||yr@)rkrNrls r8proto_cachemessagezBroker.proto_cachemessages-         r7ct|ts|jd} ||}| td|j ||||} |rZt| t j r-|f} | j|j|j| | y|j| |yy#t$ry} |rmt| ts%|jj| jr|j| |n |jt| |Yd} ~ yYd} ~ yYd} ~ yd} ~ wt $rL|r3t#j$ddt} |j| |t#j&YywxYw)a Received a message-send. Look up message based on object, unserialize the arguments, and invoke it with args, and send an 'answer' or 'error' response. @param findObjMethod: A callable which takes C{objectID} as argument. @param requestID: The requiest ID. @param objectID: The object ID. @param message: The message. @param answerRequired: @param netArgs: Arguments. @param netKw: Keyword arguments. rNzInvalid Object ID) callbackArgs errbackArgs)Peer will receive following PB traceback:T)isError)rrrr<rwr rTrU _sendAnswer_sendFailureOrErrorrrisClassAllowed __class__ _sendErrorrrrror+) rE findObjMethodrhrbrdrerfrgrx netResultr\ers r8rkzBroker._recvMessagesS0'3'nnV,G% ;"8,F~/0044T7GUSI,i8%2A%D&&AE>=E>c*|jd||y)z (internal) Send an answer to a previously sent message. @param netResult: The answer. @param requestID: The request ID. sanswerNr)rEr{rhs r8ruzBroker._sendAnswer@s iI6r7c||j|}|j|=|j|j|y)z (internal) Got an answer to a previously sent message. Look up the appropriate callback and call it. @param requestID: The request ID. @param netResult: The answer. N)rrrl)rErhr{r#s r8 proto_answerzBroker.proto_answerIs9  " "9 -  " "9 - 4##I./r7cx|jt|j||y|j||y)z Call L{_sendError} or L{_sendFailure}, depending on whether C{fail} represents an L{Error} subclass or not. @param fail: The failure. @param requestID: The request ID. N)checkr< _sendFailureryrErrhs r8rvzBroker._sendFailureOrErrorVs1 ::e  $   dI . OOD) ,r7c|tjdtj||j||y)zz Log error and then send it. @param fail: The failure. @param requestID: The request ID. rsN)rror+ryrs r8rzBroker._sendFailurecs* ;<   i(r7ct|tjrt|jts/|j j |jjr |j}n0t|ts t||jj}t|tr|jj|_ |jd||j|y)z (internal) Send an error for a previously sent message. @param fail: The failure. @param requestID: The request ID. serrorN)rrrrFrrrwrxrrrrrrprs r8ryzBroker._sendErrorns dGOO ,$**i0DMM4P4P $$5zzo6'dll.K.KL dO ,$(LL$A$AD ! h 4>>$+?@r7c||j|}|j|=|j|j|y)z} (internal) Deal with an error. @param requestID: The request ID. @param fail: The failure. N)rrrl)rErhrr#s r8 proto_errorzBroker.proto_errors9  " "9 -  " "9 - $""4()r7c(|jd|y)z^ (internal) Send a DECREF directive. @param objectID: The object ID. sdecrefNr~rErbs r8rzBroker.sendDecRefs i*r7cRt|tr|jd}|j|j }|dk(rd|j|j j }|j|=|j|=|jj|dyy)z (internal) Decrement the reference count of an object. If the reference count is zero, it will free the reference to this object. @param objectID: The object ID. rrcyr@r6r6r7r8rRz%Broker.proto_decref..rgr7N) rrr[rrrxr5rrpop)rErbrefsr:s r8 proto_decrefzBroker.proto_decrefs h $v.H  *113 19$$X.55EEGD 4 !!(+ 6D   " "4 6 8 r7c(|jd|y)z_ (internal) Send a DECACHE directive. @param objectID: The object ID. sdecacheNr~rs r8 decCacheRefzBroker.decCacheRefs j(+r7c|j|j}|dk(r|j|}|j}|j} |j |t ||||j}|j|=|j|=|jd|yy#t $rtjY]wxYw)z (internal) Decrement the reference count of a cached object. If the reference count is zero, free the reference, then send an 'uncached' directive. @param objectID: The object ID. rsuncacheN) rrrxrYrrrrrr5rr)rErbrr$r%rYr:s r8 proto_decachezBroker.proto_decaches))(3::< 19--h7D I**K **!4T9k!R ,,.D((.**84 MM*h / !   s B&&CCcJ|j|}d|_|j|=y)zx (internal) Tell the client it is now OK to uncache an object. @param objectID: The object ID. N)rrW)rErbrKs r8 proto_uncachezBroker.proto_uncaches+''1   % %h /r7r)NNNNr@)6r2r3r4r5r usernamerr,rBrrrrrr rrrrrr&rr)r,rr2r7r;r=r?rBrDrGrLrNrprlr9r\rXrmrorkrurrvrryrrrrrrr6r7r8rrsGHG !N$ L 0  5 A( S ; 0'!R*' +  60 4 7*2( T 1#%'R    @;D7 0 - )A( *+9$,08 0r7rct}|j||j}t}|j||j||j}|S)z Respond to a challenge. This is useful for challenge/response authentication. @param challenge: A challenge. @param password: A password. @return: The password hashed twice. )rupdatedigest) challengepasswordmhashedPassworddoubleHashedPasswords r8respondrsS AHHXXXZN AHH^HHY88: r7c tdttjddD}t |j }|S)z% @return: Some random data. c3HK|]}tjddyw)AZN)randomrandint).0rQs r8 zchallenge..sQAB'Qs ")rrr randrangerr)craps r8rrs= Qv7G7GB7O1PQ QD t9   D Kr7cpeZdZdZeZdZdefdZdZ dZ dZ dZ ddZ d Zd Zd Zd Zd ZdZddZy)PBClientFactoryz Client factory for PB brokers. As with all client factories, use with reactor.connectTCP/SSL/etc.. getPerspective and getRootObject can be called either before or after the connect. Fc@||_||_|jy)aE @param unsafeTracebacks: if set, tracebacks for exceptions will be sent over the wire. @type unsafeTracebacks: C{bool} @param security: security options used by the broker, default to C{globalSecurity}. @type security: L{twisted.spread.jelly.SecurityOptions} N)rr_reset)rErrs r8rBzPBClientFactory.__init__s!1   r7cN|jd|j}||_|S)zP Build the broker instance, passing the security options to it. Trr)r rr)rEaddrps r8 buildProtocolzPBClientFactory.buildProtocols& MM4$--M @ r7c.g|_d|_d|_yr@)rootObjectRequests_broker_rootrSs r8rzPBClientFactory._resets"$  r7cl|j}|j|D]}|j|yr@)rrr)rEr" deferredsr#s r8_failAllzPBClientFactory._failAlls1++   A IIf  r7c&|j|yr@)r)rE connectorr"s r8clientConnectionFailedz&PBClientFactory.clientConnectionFailed%s fr7cH|rd|_d|_y|j|y)zJ Reconnecting subclasses should call with reconnecting=1. N)rrr)rErr" reconnectings r8clientConnectionLostz$PBClientFactory.clientConnectionLost(s#  DLDJ MM& !r7c||_|jd|_|j}g|_|D]}|j |jy)Nroot)rr?rrr)rErWdsr#s r8rz$PBClientFactory.clientConnectionMade4sM ))&1  $ $"$ #A JJtzz " #r7c|jr5|jjstj|jStj }|j j||S)ze Get root object of remote PB server. @return: Deferred of the root object. )rrr succeedrrTrr)rEr#s r8 getRootObjectzPBClientFactory.getRootObject<sO << 9 9==, , NN  &&q)r7cf|jr%|jjjyy)z If the factory is connected, close the connection. Note that if you set up the factory to reconnect, you will need to implement extra logic to prevent automatic reconnection after this is called. N)rrr8rSs r8 disconnectzPBClientFactory.disconnectHs& << LL " " 1 1 3 r7c\|jd|j|j||S)Nlogin)r addCallback _cbResponse)rErrrclients r8_cbSendUsernamezPBClientFactory._cbSendUsernameSs-w1==   h  r7cF|\}}|jdt|||S)Nr)rr)rE challengesrrr challengers r8rzPBClientFactory._cbResponseXs( * :$$Y 80LfUUr7c&|jd|S)ab Attempt an anonymous login on the given remote root object. @type root: L{RemoteReference} @param root: The object on which to attempt the login, most likely returned by a call to L{PBClientFactory.getRootObject}. @param client: A jellyable object which will be used as the I{mind} parameter for the login attempt. @rtype: L{Deferred} @return: A L{Deferred} which will be called back with a L{RemoteReference} to an avatar when anonymous login succeeds, or which will errback if anonymous login fails. loginAnonymous)r)rErrs r8_cbLoginAnonymousz!PBClientFactory._cbLoginAnonymous\s /88r7Nc|j}tj|r|j|j||S|j|j |j |j||S)a Login and get perspective from remote PB server. Currently the following credentials are supported:: L{twisted.cred.credentials.IUsernamePassword} L{twisted.cred.credentials.IAnonymous} @rtype: L{Deferred} @return: A L{Deferred} which will be called back with a L{RemoteReference} for the avatar logged in to, or which will errback if login fails. )rr providedByrrrrr)rE credentialsrr#s r8rzPBClientFactory.loginnsl       - MM$00& 9  MM$$k&:&:K.maybeLogoutsBq Dr7)r)rrtr5rWrr)rEresult interfaceavatarr:rrs @r8_cbLoginz_JellyableAvatarMixin._cbLoginst '-#FF$$V,$V];F%%'  +6 !!$' &&{3 r7N)r2r3r4r5rr6r7r8rrs  r7rc"eZdZdZdZdZdZy)rz= Root Referenceable object, used to login to portal. c ||_||_yr@)rrW)rErrWs r8rBz_PortalWrapper.__init__s  r7c^t}|t|j|j||fS)z[ Start of username/password login. @param username: The username. )r_PortalAuthChallengerrrW)rErcs r8 remote_loginz_PortalWrapper.remote_logins* K' T[[(ANNNr7c|jjt|t}|j |j |S)aU Attempt an anonymous login. @param mind: An object to use as the mind parameter to the portal login call (possibly None). @rtype: L{Deferred} @return: A Deferred which will be called back with an avatar when login succeeds or which will be errbacked if login fails somehow. )rrrrbrr)rEmindr#s r8remote_loginAnonymousz$_PortalWrapper.remote_loginAnonymous&s3 KK  ik4 > dmm$r7N)r2r3r4r5rBrrr6r7r8rrsO r7rc(eZdZdZdZdZdZdZy)rz5 Called with response to password challenge. c<||_||_||_||_yr@)rrWrr)rErrWrrs r8rBz_PortalAuthChallenger.__init__<s    "r7c||_|jj||t}|j |j |Sr@)responserrrbrr)rErrr#s r8remote_respondz$_PortalAuthChallenger.remote_respondBs6  KK  dD, 7 dmm$r7cR|jt|jS)z L{IUsernameHashedPassword} @param password: The password. @return: L{_PortalAuthChallenger.checkMD5Password} )rrr)rErs r8rz#_PortalAuthChallenger.checkPasswordHs"$$S]%9%9%;<rIr`rbrjrt Ephemeralr|rrrrrrrrr ClientFactoryr ServerFactoryrrrrrr__all__r6r7r8rsG 41 ',$1015!,?MM I I/)/4     @ y & 9& R \%?%?%?PVmV \ E.lF$4$4E. E.Px1  Hgoox:(,J(,V 6 O 0V]]O 0d (Lh,,L^- h,,- `' <' T W 3 3 3 VW-  F]$9D $&:;&(M+@&(<&(R* r7