/** * 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)); }
/// <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)); } }
/// <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)); }
/// <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"); } }
public void Setup() { Config.SERPENT_INDENT=true; Config.SERPENT_SET_LITERALS=true; ser = new SerpentSerializer(); }
public void Setup() { ser = new PickleSerializer(); }