Exemplo n.º 1
0
 def register(self, obj, objectId=None):
     """
     Register a Pyro object under the given id. Note that this object is now only
     known inside this daemon, it is not automatically available in a name server.
     This method returns a URI for the registered object.
     """
     if objectId:
         if not isinstance(objectId, basestring):
             raise TypeError("objectId must be a string or None")
     else:
         objectId = "obj_" + uuid.uuid4().hex  # generate a new objectId
     if hasattr(
             obj, "_pyroId"
     ) and obj._pyroId != "":  # check for empty string is needed for Cython
         raise errors.DaemonError("object already has a Pyro id")
     if objectId in self.objectsById:
         raise errors.DaemonError("object already registered with that id")
     # set some pyro attributes
     obj._pyroId = objectId
     obj._pyroDaemon = self
     if Pyro4.config.AUTOPROXY:
         # register a custom serializer for the type to automatically return proxies
         # we need to do this for all known serializers
         for ser in util._serializers.values():
             ser.register_type_replacement(type(obj), pyroObjectToAutoProxy)
     # register the object in the mapping
     self.objectsById[obj._pyroId] = obj
     return self.uriFor(objectId)
Exemplo n.º 2
0
 def register(self, obj, objectId=None):
     """
     Register a Pyro object under the given id. Note that this object is now only
     known inside this daemon, it is not automatically available in a name server.
     This method returns a URI for the registered object.
     """
     if objectId:
         if not isinstance(objectId, basestring):
             raise TypeError("objectId must be a string or None")
     else:
         objectId="obj_"+uuid.uuid4().hex   # generate a new objectId
     if hasattr(obj, "_pyroId") and obj._pyroId != "":     # check for empty string is needed for Cython
         raise errors.DaemonError("object already has a Pyro id")
     if objectId in self.objectsById:
         raise errors.DaemonError("object already registered with that id")
     # set some pyro attributes
     obj._pyroId=objectId
     obj._pyroDaemon=self
     if Pyro4.config.AUTOPROXY:
         # register a custom serializer for the type to automatically return proxies
         try:
             if isinstance(obj, tuple(self.serializers)):
                 # Find the most fitting serializer by picking the highest in the mro
                 for t in type(obj).__mro__:
                     if t in self.serializers:
                         copyreg.pickle(type(obj), self.serializers[t])
                         break
             else:
                 copyreg.pickle(type(obj),pyroObjectSerializer)
         except TypeError:
             pass
     # register the object in the mapping
     self.objectsById[obj._pyroId]=obj
     return self.uriFor(objectId)
Exemplo n.º 3
0
 def get_metadata(objectId):
     obj = self.objectsById.get(objectId)
     if obj is not None:
         if hasattr(obj, 'QSUB_metadata'):
             return getattr(obj, 'QSUB_metadata')
         return pyro_util.get_exposed_members(obj, only_exposed=Pyro4.config.REQUIRE_EXPOSE)
     else:
         Pyro4.core.log.debug("unknown object requested: %s", objectId)
         raise pyro_errors.DaemonError("unknown object")
Exemplo n.º 4
0
 def uriFor(self, objectOrId=None, nat=True):
     """
     Get a URI for the given object (or object id) from this daemon.
     Only a daemon can hand out proper uris because the access location is
     contained in them.
     Note that unregistered objects cannot be given an uri, but unregistered
     object names can (it's just a string we're creating in that case).
     If nat is set to False, the configured NAT address (if any) is ignored and it will
     return an URI for the internal address.
     """
     if not isinstance(objectOrId, basestring):
         objectOrId = getattr(objectOrId, "_pyroId", None)
         if objectOrId is None:
             raise errors.DaemonError("object isn't registered")
     if nat:
         loc = self.natLocationStr or self.locationStr
     else:
         loc = self.locationStr
     return URI("PYRO:%s@%s" % (objectOrId, loc))
Exemplo n.º 5
0
 def unregister(self, objectOrId):
     """
     Remove an object from the known objects inside this daemon.
     You can unregister an object directly or with its id.
     """
     if objectOrId is None:
         raise ValueError("object or objectid argument expected")
     if not isinstance(objectOrId, basestring):
         objectId = getattr(objectOrId, "_pyroId", None)
         if objectId is None:
             raise errors.DaemonError("object isn't registered")
     else:
         objectId = objectOrId
         objectOrId = None
     if objectId == constants.DAEMON_NAME:
         return
     if objectId in self.objectsById:
         del self.objectsById[objectId]
         if objectOrId is not None:
             del objectOrId._pyroId
             del objectOrId._pyroDaemon
Exemplo n.º 6
0
 def handleRequest(self, conn):
     """
     Handle incoming Pyro request. Catches any exception that may occur and
     wraps it in a reply to the calling side, as to not make this server side loop
     terminate due to exceptions caused by remote invocations.
     """
     request_flags = 0
     request_seq = 0
     request_serializer_id = util.MarshalSerializer.serializer_id
     wasBatched = False
     isCallback = False
     try:
         msg = Message.recv(
             conn, [Pyro4.message.MSG_INVOKE, Pyro4.message.MSG_PING])
         request_flags = msg.flags
         request_seq = msg.seq
         request_serializer_id = msg.serializer_id
         if Pyro4.config.LOGWIRE:
             log.debug(
                 "daemon wiredata received: msgtype=%d flags=0x%x ser=%d seq=%d data=%r"
                 % (msg.type, msg.flags, msg.serializer_id, msg.seq,
                    msg.data))
         if msg.type == Pyro4.message.MSG_PING:
             # return same seq, but ignore any data (it's a ping, not an echo). Nothing is deserialized.
             msg = Message(Pyro4.message.MSG_PING, b"pong",
                           msg.serializer_id, 0, msg.seq)
             if Pyro4.config.LOGWIRE:
                 log.debug(
                     "daemon wiredata sending: msgtype=%d flags=0x%x ser=%d seq=%d data=%r"
                     % (msg.type, msg.flags, msg.serializer_id, msg.seq,
                        msg.data))
             conn.send(msg.to_bytes())
             return
         if msg.serializer_id not in self.__serializer_ids:
             raise errors.ProtocolError(
                 "message used serializer that is not accepted: %d" %
                 msg.serializer_id)
         serializer = util.get_serializer_by_id(msg.serializer_id)
         objId, method, vargs, kwargs = serializer.deserializeCall(
             msg.data,
             compressed=msg.flags & Pyro4.message.FLAGS_COMPRESSED)
         del msg  # invite GC to collect the object, don't wait for out-of-scope
         obj = self.objectsById.get(objId)
         if obj is not None:
             if kwargs and sys.version_info < (2, 6,
                                               5) and os.name != "java":
                 # Python before 2.6.5 doesn't accept unicode keyword arguments
                 kwargs = dict((str(k), kwargs[k]) for k in kwargs)
             if request_flags & Pyro4.message.FLAGS_BATCH:
                 # batched method calls, loop over them all and collect all results
                 data = []
                 for method, vargs, kwargs in vargs:
                     method = util.resolveDottedAttribute(
                         obj, method, Pyro4.config.DOTTEDNAMES)
                     try:
                         result = method(
                             *vargs, **kwargs
                         )  # this is the actual method call to the Pyro object
                     except Exception:
                         xt, xv = sys.exc_info()[0:2]
                         log.debug(
                             "Exception occurred while handling batched request: %s",
                             xv)
                         xv._pyroTraceback = util.formatTraceback(
                             detailed=Pyro4.config.DETAILED_TRACEBACK)
                         if sys.platform == "cli":
                             util.fixIronPythonExceptionForPickle(
                                 xv, True)  # piggyback attributes
                         data.append(futures._ExceptionWrapper(xv))
                         break  # stop processing the rest of the batch
                     else:
                         data.append(result)
                 wasBatched = True
             else:
                 # normal single method call
                 method = util.resolveDottedAttribute(
                     obj, method, Pyro4.config.DOTTEDNAMES)
                 if request_flags & Pyro4.message.FLAGS_ONEWAY and Pyro4.config.ONEWAY_THREADED:
                     # oneway call to be run inside its own thread
                     thread = threadutil.Thread(target=method,
                                                args=vargs,
                                                kwargs=kwargs)
                     thread.setDaemon(True)
                     thread.start()
                 else:
                     isCallback = getattr(method, "_pyroCallback", False)
                     data = method(
                         *vargs, **kwargs
                     )  # this is the actual method call to the Pyro object
         else:
             log.debug("unknown object requested: %s", objId)
             raise errors.DaemonError("unknown object")
         if request_flags & Pyro4.message.FLAGS_ONEWAY:
             return  # oneway call, don't send a response
         else:
             data, compressed = serializer.serializeData(
                 data, compress=Pyro4.config.COMPRESSION)
             response_flags = 0
             if compressed:
                 response_flags |= Pyro4.message.FLAGS_COMPRESSED
             if wasBatched:
                 response_flags |= Pyro4.message.FLAGS_BATCH
             if Pyro4.config.LOGWIRE:
                 log.debug(
                     "daemon wiredata sending: msgtype=%d flags=0x%x ser=%d seq=%d data=%r"
                     % (Pyro4.message.MSG_RESULT, response_flags,
                        serializer.serializer_id, request_seq, data))
             msg = Message(Pyro4.message.MSG_RESULT, data,
                           serializer.serializer_id, response_flags,
                           request_seq)
             conn.send(msg.to_bytes())
     except Exception:
         xt, xv = sys.exc_info()[0:2]
         if xt is not errors.ConnectionClosedError:
             log.debug("Exception occurred while handling request: %r", xv)
             if not request_flags & Pyro4.message.FLAGS_ONEWAY:
                 # only return the error to the client if it wasn't a oneway call
                 tblines = util.formatTraceback(
                     detailed=Pyro4.config.DETAILED_TRACEBACK)
                 self._sendExceptionResponse(conn, request_seq,
                                             request_serializer_id, xv,
                                             tblines)
         if isCallback or isinstance(
                 xv, (errors.CommunicationError, errors.SecurityError)):
             raise  # re-raise if flagged as callback, communication or security error.
Exemplo n.º 7
0
 def handleRequest(self, conn):
     """
     Handle incoming Pyro request. Catches any exception that may occur and
     wraps it in a reply to the calling side, as to not make this server side loop
     terminate due to exceptions caused by remote invocations.
     """
     flags=0
     seq=0
     wasBatched=False
     isCallback=False
     client_future = None
     try:
         msgType, flags, seq, data = MessageFactory.getMessage(conn, MessageFactory.MSG_INVOKE)
         objId, method, vargs, kwargs=self.serializer.deserialize(
                                        data, compressed=flags & MessageFactory.FLAGS_COMPRESSED)
         del data  # invite GC to collect the object, don't wait for out-of-scope
         obj=self.objectsById.get(objId)
         
         if flags & MessageFactory.FLAGS_ASYNC:
             client_future = vargs[0]
             client_future._pyroOneway.update(["set_cancelled", "set_result", "set_exception", "set_progress"])
             vargs = vargs[1:]
         elif flags & MessageFactory.FLAGS_ASYNC_CANCEL:
             client_future_uri = vargs[0]
         
         if obj is not None:
             if kwargs and sys.version_info<(2, 6, 5) and os.name!="java":
                 # Python before 2.6.5 doesn't accept unicode keyword arguments
                 kwargs = dict((str(k), kwargs[k]) for k in kwargs)
             if flags & MessageFactory.FLAGS_BATCH:
                 # batched method calls, loop over them all and collect all results
                 data=[]
                 for method,vargs,kwargs in vargs:
                     method=util.resolveDottedAttribute(obj, method, Pyro4.config.DOTTEDNAMES)
                     try:
                         result=method(*vargs, **kwargs)   # this is the actual method call to the Pyro object
                     except Exception:
                         xt,xv=sys.exc_info()[0:2]
                         log.debug("Exception occurred while handling batched request: %s", xv)
                         xv._pyroTraceback=util.formatTraceback(detailed=Pyro4.config.DETAILED_TRACEBACK)
                         if sys.platform=="cli":
                             util.fixIronPythonExceptionForPickle(xv, True)  # piggyback attributes
                         data.append(futures._ExceptionWrapper(xv))
                         break   # stop processing the rest of the batch
                     else:
                         data.append(result)
                 wasBatched=True
             elif flags & MessageFactory.FLAGS_ASYNC_CANCEL:
                 data=self._cancelFuture(client_future_uri)
             else:
                 # normal single method call
                 method=util.resolveDottedAttribute(obj, method, Pyro4.config.DOTTEDNAMES)
                 if flags & MessageFactory.FLAGS_ONEWAY and Pyro4.config.ONEWAY_THREADED:
                     # oneway call to be run inside its own thread
                     thread=threadutil.Thread(target=method, args=vargs, kwargs=kwargs)
                     thread.setDaemon(True)
                     thread.start()
                 elif flags & MessageFactory.FLAGS_ASYNC:
                     future=method(*vargs, **kwargs)
                     self._followFuture(future, client_future)
                 else:
                     isCallback=getattr(method, "_pyroCallback", False)
                     data=method(*vargs, **kwargs)   # this is the actual method call to the Pyro object
         else:
             log.debug("unknown object requested: %s", objId)
             raise errors.DaemonError("unknown object")
         if flags & MessageFactory.FLAGS_ONEWAY:
             return   # oneway call, don't send a response
         elif flags & MessageFactory.FLAGS_ASYNC:
             return  # async call, don't send a response yet
         else:
             data, compressed=self.serializer.serialize(data, compress=Pyro4.config.COMPRESSION)
             flags=0
             if compressed:
                 flags |= MessageFactory.FLAGS_COMPRESSED
             if wasBatched:
                 flags |= MessageFactory.FLAGS_BATCH
             msg=MessageFactory.createMessage(MessageFactory.MSG_RESULT, data, flags, seq)
             del data
             conn.send(msg)
     except Exception as ex:
         xt,xv=sys.exc_info()[0:2]
         if xt is not errors.ConnectionClosedError:
             log.debug("Exception occurred while handling request: %r", xv)
             if client_future is not None:
                 # send exception to the client future
                 client_future.set_exception(ex)
             elif not flags & MessageFactory.FLAGS_ONEWAY:
                 # only return the error to the client if it wasn't a oneway call
                 tblines=util.formatTraceback(detailed=Pyro4.config.DETAILED_TRACEBACK)
                 self._sendExceptionResponse(conn, seq, xv, tblines)
         if isCallback or isinstance(xv, (errors.CommunicationError, errors.SecurityError)):
             raise       # re-raise if flagged as callback, communication or security error.