Esempio n. 1
0
    def checkBadMessage2(self):
        # just like a real message, but with an unpicklable argument
        global Hack
        class Hack:
            pass

        msg = Marshaller().encode(1, 0, "foo", (Hack(),))
        self._bad_message(msg)
        del Hack
Esempio n. 2
0
    def __init__(self, sock, addr, obj, tag, map=None):
        self.obj = None
        self.marshal = Marshaller()
        self.closed = False
        self.peer_protocol_version = None  # set in recv_handshake()

        assert tag in "CS"
        self.tag = tag
        self.logger = logging.getLogger('ZEO.zrpc.Connection(%c)' % tag)
        if isinstance(addr, tuple):
            self.log_label = "(%s:%d) " % addr
        else:
            self.log_label = "(%s) " % addr

        # Supply our own socket map, so that we don't get registered with
        # the asyncore socket map just yet.  The initial protocol messages
        # are treated very specially, and we dare not get invoked by asyncore
        # before that special-case setup is complete.  Some of that setup
        # occurs near the end of this constructor, and the rest is done by
        # a concrete subclass's handshake() method.  Unfortunately, because
        # we ultimately derive from asyncore.dispatcher, it's not possible
        # to invoke the superclass constructor without asyncore stuffing
        # us into _some_ socket map.
        ourmap = {}
        self.__super_init(sock, addr, map=ourmap)

        # A Connection either uses asyncore directly or relies on an
        # asyncore mainloop running in a separate thread.  If
        # thr_async is true, then the mainloop is running in a
        # separate thread.  If thr_async is true, then the asyncore
        # trigger (self.trigger) is used to notify that thread of
        # activity on the current thread.
        self.thr_async = False
        self.trigger = None
        self._prepare_async()

        # The singleton dict is used in synchronous mode when a method
        # needs to call into asyncore to try to force some I/O to occur.
        # The singleton dict is a socket map containing only this object.
        self._singleton = {self._fileno: self}

        # msgid_lock guards access to msgid
        self.msgid = 0
        self.msgid_lock = threading.Lock()

        # replies_cond is used to block when a synchronous call is
        # waiting for a response
        self.replies_cond = threading.Condition()
        self.replies = {}

        # waiting_for_reply is used internally to indicate whether
        # a call is in progress.  setting a session key is deferred
        # until after the call returns.
        self.waiting_for_reply = False
        self.delay_sesskey = None
        self.register_object(obj)

        # The first message we see is a protocol handshake.  message_input()
        # is temporarily replaced by recv_handshake() to treat that message
        # specially.  revc_handshake() does "del self.message_input", which
        # uncovers the normal message_input() method thereafter.
        self.message_input = self.recv_handshake

        # Server and client need to do different things for protocol
        # negotiation, and handshake() is implemented differently in each.
        self.handshake()

        # Now it's safe to register with asyncore's socket map; it was not
        # safe before message_input was replaced, or before handshake() was
        # invoked.
        # Obscure:  in Python 2.4, the base asyncore.dispatcher class grew
        # a ._map attribute, which is used instead of asyncore's global
        # socket map when ._map isn't None.  Because we passed `ourmap` to
        # the base class constructor above, in 2.4 asyncore believes we want
        # to use `ourmap` instead of the global socket map -- but we don't.
        # So we have to replace our ._map with the global socket map, and
        # update the global socket map with `ourmap`.  Replacing our ._map
        # isn't necessary before Python 2.4, but doesn't hurt then (it just
        # gives us an unused attribute in 2.3); updating the global socket
        # map is necessary regardless of Python version.
        if map is None:
            map = asyncore.socket_map
        self._map = map
        map.update(ourmap)