Example #1
0
        /**
         * Internal call method to actually perform the Pyro method call and process the result.
         */
        private object call(string method, ushort flags, params object[] parameters)
        {
            lock (this) {
                connect();
                unchecked {
                    sequenceNr++;                // unchecked so this ushort wraps around 0-65535 instead of raising an OverflowException
                }
            }
            if (parameters == null)
            {
                parameters = new object[] {}
            }
            ;
            PyroSerializer ser = PyroSerializer.GetFor(Config.SERIALIZER);

            byte[]  pickle = ser.serializeCall(objectid, method, parameters, new Dictionary <string, object>(0));
            var     msg    = new Message(Message.MSG_INVOKE, pickle, ser.serializer_id, flags, sequenceNr, null);
            Message resultmsg;

            lock (this.sock) {
                IOUtil.send(sock_stream, msg.to_bytes());
                if (Config.MSG_TRACE_DIR != null)
                {
                    Message.TraceMessageSend(sequenceNr, msg.get_header_bytes(), msg.get_annotations_bytes(), msg.data);
                }
                pickle = null;

                if ((flags & Message.FLAGS_ONEWAY) != 0)
                {
                    return(null);
                }

                resultmsg = Message.recv(sock_stream, new ushort[] { Message.MSG_RESULT });
            }
            if (resultmsg.seq != sequenceNr)
            {
                throw new PyroException("result msg out of sync");
            }
            if ((resultmsg.flags & Message.FLAGS_COMPRESSED) != 0)
            {
                // we need to skip the first 2 bytes in the buffer due to a tiny mismatch between zlib-written
                // data and the deflate data bytes that .net expects.
                // See http://www.chiramattel.com/george/blog/2007/09/09/deflatestream-block-length-does-not-match.html
                using (MemoryStream compressed = new MemoryStream(resultmsg.data, 2, resultmsg.data.Length - 2, false)) {
                    using (DeflateStream decompresser = new DeflateStream(compressed, CompressionMode.Decompress)) {
                        MemoryStream bos    = new MemoryStream(resultmsg.data.Length);
                        byte[]       buffer = new byte[4096];
                        int          numRead;
                        while ((numRead = decompresser.Read(buffer, 0, buffer.Length)) != 0)
                        {
                            bos.Write(buffer, 0, numRead);
                        }
                        resultmsg.data = bos.ToArray();
                    }
                }
            }

            if ((resultmsg.flags & Message.FLAGS_EXCEPTION) != 0)
            {
                Exception rx = (Exception)ser.deserializeData(resultmsg.data);
                if (rx is PyroException)
                {
                    throw (PyroException)rx;
                }
                else
                {
                    PyroException px = new PyroException("remote exception occurred", rx);
                    PropertyInfo  remotetbProperty = rx.GetType().GetProperty("_pyroTraceback");
                    if (remotetbProperty != null)
                    {
                        string remotetb = (string)remotetbProperty.GetValue(rx, null);
                        px._pyroTraceback = remotetb;
                    }
                    throw px;
                }
            }

            return(ser.deserializeData(resultmsg.data));
        }
Example #2
0
        /// <summary>
        /// Internal call method to actually perform the Pyro method call and process the result.
        /// </summary>
        private object internal_call(string method, string actual_objectId, ushort flags, bool checkMethodName, params object[] parameters)
        {
            actual_objectId = actual_objectId ?? this.objectid;
            lock (this) {
                connect();
                unchecked {
                    sequenceNr++;                // unchecked so this ushort wraps around 0-65535 instead of raising an OverflowException
                }
            }
            if (pyroAttrs.Contains(method))
            {
                throw new PyroException("cannot call an attribute");
            }
            if (pyroOneway.Contains(method))
            {
                flags |= Message.FLAGS_ONEWAY;
            }
            if (checkMethodName && Config.METADATA && !pyroMethods.Contains(method))
            {
                throw new PyroException(string.Format("remote object '{0}' has no exposed attribute or method '{1}'", actual_objectId, method));
            }

            if (parameters == null)
            {
                parameters = new object[] {}
            }
            ;

            PyroSerializer ser = PyroSerializer.GetFor(Config.SERIALIZER);

            byte[]  pickle = ser.serializeCall(actual_objectId, method, parameters, new Dictionary <string, object>(0));
            var     msg    = new Message(Message.MSG_INVOKE, pickle, ser.serializer_id, flags, sequenceNr, this.annotations(), pyroHmacKey);
            Message resultmsg;

            lock (this.sock) {
                IOUtil.send(sock_stream, msg.to_bytes());
                if (Config.MSG_TRACE_DIR != null)
                {
                    Message.TraceMessageSend(sequenceNr, msg.get_header_bytes(), msg.get_annotations_bytes(), msg.data);
                }
                // ReSharper disable once RedundantAssignment
                pickle = null;

                if ((flags & Message.FLAGS_ONEWAY) != 0)
                {
                    return(null);
                }

                resultmsg = Message.recv(sock_stream, new [] { Message.MSG_RESULT }, pyroHmacKey);
            }
            if (resultmsg.seq != sequenceNr)
            {
                throw new PyroException("result msg out of sync");
            }
            responseAnnotations(resultmsg.annotations, resultmsg.type);
            if ((resultmsg.flags & Message.FLAGS_COMPRESSED) != 0)
            {
                _decompressMessageData(resultmsg);
            }

            if ((resultmsg.flags & Message.FLAGS_ITEMSTREAMRESULT) != 0)
            {
                byte[] streamId;
                if (!resultmsg.annotations.TryGetValue("STRM", out streamId))
                {
                    throw new PyroException("result of call is an iterator, but the server is not configured to allow streaming");
                }
                return(new StreamResultIterator(Encoding.UTF8.GetString(streamId), this));
            }

            if ((resultmsg.flags & Message.FLAGS_EXCEPTION) != 0)
            {
                Exception rx = (Exception)ser.deserializeData(resultmsg.data);
                if (rx is PyroException)
                {
                    throw (PyroException)rx;
                }
                else
                {
                    PyroException px;

                    // if the source was a PythonException, copy its message and python exception type
                    PythonException pyx = rx as PythonException;
                    if (pyx == null)
                    {
                        px = new PyroException(null, rx);
                    }
                    else
                    {
                        px = new PyroException(rx.Message, rx);
                        px.PythonExceptionType = pyx.PythonExceptionType;
                    }

                    PropertyInfo remotetbProperty = rx.GetType().GetProperty("_pyroTraceback");
                    if (remotetbProperty != null)
                    {
                        string remotetb = (string)remotetbProperty.GetValue(rx, null);
                        px._pyroTraceback = remotetb;
                    }
                    throw px;
                }
            }

            return(ser.deserializeData(resultmsg.data));
        }
Example #3
0
        /// <summary>
        /// Perform the Pyro protocol connection handshake with the Pyro daemon.
        /// </summary>
        protected void _handshake()
        {
            var ser           = PyroSerializer.GetFor(Config.SERIALIZER);
            var handshakedata = new Dictionary <string, Object>();

            handshakedata["handshake"] = pyroHandshake;
            if (Config.METADATA)
            {
                handshakedata["object"] = objectid;
            }
            byte[] data  = ser.serializeData(handshakedata);
            ushort flags = Config.METADATA? Message.FLAGS_META_ON_CONNECT : (ushort)0;
            var    msg   = new Message(Message.MSG_CONNECT, data, ser.serializer_id, flags, sequenceNr, annotations(), pyroHmacKey);

            IOUtil.send(sock_stream, msg.to_bytes());
            if (Config.MSG_TRACE_DIR != null)
            {
                Message.TraceMessageSend(sequenceNr, msg.get_header_bytes(), msg.get_annotations_bytes(), msg.data);
            }

            // process handshake response
            msg = Message.recv(sock_stream, new [] { Message.MSG_CONNECTOK, Message.MSG_CONNECTFAIL }, pyroHmacKey);
            responseAnnotations(msg.annotations, msg.type);
            object handshake_response = "?";

            if (msg.data != null)
            {
                if ((msg.flags & Message.FLAGS_COMPRESSED) != 0)
                {
                    _decompressMessageData(msg);
                }
                try {
                    ser = PyroSerializer.GetFor(msg.serializer_id);
                    handshake_response = ser.deserializeData(msg.data);
                } catch (Exception) {
                    msg.type           = Message.MSG_CONNECTFAIL;
                    handshake_response = "<not available because unsupported serialization format>";
                }
            }
            if (msg.type == Message.MSG_CONNECTOK)
            {
                if ((msg.flags & Message.FLAGS_META_ON_CONNECT) != 0)
                {
                    var response_dict = (IDictionary <object, object>)handshake_response;
                    _processMetadata((IDictionary <object, object>)response_dict["meta"]);
                    handshake_response = response_dict["handshake"];
                    try {
                        validateHandshake(handshake_response);
                    } catch (Exception) {
                        close();
                        throw;
                    }
                }
            }
            else if (msg.type == Message.MSG_CONNECTFAIL)
            {
                close();
                throw new PyroException("connection rejected, reason: " + handshake_response);
            }
            else
            {
                close();
                throw new PyroException(string.Format("connect: invalid msg type {0} received", msg.type));
            }
        }
Example #4
0
        /// <summary>
        /// Perform the Pyro protocol connection handshake with the Pyro daemon.
        /// </summary>
        protected void _handshake()
        {
            var ser           = PyroSerializer.GetSerpentSerializer();
            var handshakedata = new Dictionary <string, object> {
                ["handshake"] = pyroHandshake
            };

            handshakedata["object"] = objectid;
            var    data  = ser.serializeData(handshakedata);
            ushort flags = 0;

            if (correlation_id != null)
            {
                flags |= Message.FLAGS_CORR_ID;
            }
            var msg = new Message(Message.MSG_CONNECT, data, ser.serializer_id, flags, sequenceNr, annotations(), correlation_id);

            IOUtil.send(sock_stream, msg.to_bytes());
            if (Config.MSG_TRACE_DIR != null)
            {
                Message.TraceMessageSend(sequenceNr, msg.get_header_bytes(), msg.get_annotations_bytes(), msg.data);
            }

            // process handshake response
            msg = Message.recv(sock_stream, new [] { Message.MSG_CONNECTOK, Message.MSG_CONNECTFAIL });
            responseAnnotations(msg.annotations, msg.type);
            object handshake_response = "?";

            if (msg.data != null)
            {
                if ((msg.flags & Message.FLAGS_COMPRESSED) != 0)
                {
                    _decompressMessageData(msg);
                }
                try {
                    ser = PyroSerializer.GetFor(msg.serializer_id);
                    handshake_response = ser.deserializeData(msg.data);
                } catch (Exception) {
                    msg.type           = Message.MSG_CONNECTFAIL;
                    handshake_response = "<not available because unsupported serialization format>";
                }
            }
            switch (msg.type)
            {
            case Message.MSG_CONNECTOK:
                var response_dict = (IDictionary)handshake_response;

                _processMetadata((IDictionary)response_dict["meta"]);
                handshake_response = response_dict["handshake"];
                try {
                    validateHandshake(handshake_response);
                } catch (Exception) {
                    close();
                    throw;
                }

                break;

            case Message.MSG_CONNECTFAIL:
                close();
                throw new PyroException("connection rejected, reason: " + handshake_response);

            default:
                close();
                throw new PyroException($"connect: invalid msg type {msg.type} received");
            }
        }