public void TestLocateReplySerialisation() { uint requestId = 5; byte[] objectKey = new byte[] { 116, 101, 115, 116, 111, 98, 106, 101, 99, 116 }; // testobject string targetUri = "testobject"; GiopVersion version = new GiopVersion(1, 2); LocateRequestMessage locReq = new LocateRequestMessage(requestId, objectKey, targetUri); // create a connection context GiopConnectionDesc conDesc = new GiopConnectionDesc(null, null); // create the reply LocateStatus replyStatus = LocateStatus.OBJECT_HERE; LocateReplyMessage locReply = new LocateReplyMessage(replyStatus); MemoryStream targetStream = new MemoryStream(); m_handler.SerialiseOutgoingLocateReplyMessage(locReply, locReq, version, targetStream, conDesc); // check to serialised stream targetStream.Seek(0, SeekOrigin.Begin); CdrInputStreamImpl cdrIn = new CdrInputStreamImpl(targetStream); cdrIn.ConfigStream(0, version); // first is Giop-magic byte data; AssertBytesFollowing(m_giopMagic, cdrIn); // Giop version data = (byte)cdrIn.ReadOctet(); Assert.AreEqual(1, data); data = (byte)cdrIn.ReadOctet(); Assert.AreEqual(2, data); // flags: big-endian, no fragements data = (byte)cdrIn.ReadOctet(); Assert.AreEqual(0, data); // Giop Msg type: locate reply data = (byte)cdrIn.ReadOctet(); Assert.AreEqual((byte)GiopMsgTypes.LocateReply, data); // Giop Msg length uint msgLength = cdrIn.ReadULong(); cdrIn.SetMaxLength(msgLength); // req-id Assert.AreEqual(requestId, cdrIn.ReadULong()); // the location status Assert.AreEqual((uint)replyStatus, cdrIn.ReadULong()); }
/// <summary> /// adds a fragment to the combined message. /// </summary> /// <returns>the fragment description for the message</returns> private FragmentedMsgDesc AddFragmentInternal(Stream fragment, bool isLastFragment) { CdrInputStreamImpl cdrInput = new CdrInputStreamImpl(fragment); GiopHeader header = new GiopHeader(cdrInput); CheckGiop1_2OrLater(header); // GIOP 1.2 or newer: read request id from fragment msg header uint reqId = cdrInput.ReadULong(); int payLoadLength = (int)(header.ContentMsgLength - 4); lock (m_fragmentedMsgs.SyncRoot) { FragmentedMsgDesc fragmentDesc = (FragmentedMsgDesc)m_fragmentedMsgs[reqId]; if (fragmentDesc == null) { throw new IOException("illegal fragment; not found previous fragment for request-id: " + reqId); } if (!isLastFragment) { fragmentDesc.AddFragment(cdrInput, payLoadLength); } else { fragmentDesc.AddLastFragment(cdrInput, payLoadLength); // remove the desc for unfinished msg from table m_fragmentedMsgs.Remove(reqId); } return(fragmentDesc); } }
/// <summary> /// extracts the request id from a non-fragmented reply message /// </summary> /// <param name="replyMessage"></param> private uint ExtractRequestIdFromReplyMessage(Stream replyMessage) { replyMessage.Seek(0, SeekOrigin.Begin); CdrInputStreamImpl reader = new CdrInputStreamImpl(replyMessage); GiopHeader msgHeader = new GiopHeader(reader); if (msgHeader.Version.IsBeforeGiop1_2()) { // GIOP 1.0 / 1.1, the service context collection preceeds the id SkipServiceContexts(reader); } return(reader.ReadULong()); }
/// <param name="expectedContentLength">length in bytes after the request-id</param> private void CheckAssembledMessage(Stream msgStream, GiopVersion version, byte endianFlags, uint reqId, uint expectedContentLength) { CdrInputStreamImpl inStream = new CdrInputStreamImpl(msgStream); GiopHeader header = new GiopHeader(inStream); Assert.AreEqual(GiopMsgTypes.Request, header.GiopType); Assert.AreEqual(version, header.Version); uint contentLength = 0; uint msgReqId = 0; if (!((version.Major == 1) && (version.Minor <= 1))) { // GIOP 1.2 // req-id contentLength = (uint)(4 + expectedContentLength); msgReqId = inStream.ReadULong(); } else { // svc-cntx + req-id contentLength = (uint)(8 + expectedContentLength); inStream.ReadULong(); // svc-cnxt msgReqId = inStream.ReadULong(); } Assert.AreEqual(contentLength, header.ContentMsgLength); Assert.AreEqual(endianFlags, header.GiopFlags); for (int i = 0; i < expectedContentLength; i++) { Assert.AreEqual(i % 255, inStream.ReadOctet()); } }
/// <summary>Start a new fragmented msg</summary> internal void StartFragment(Stream fragment) { CdrInputStreamImpl cdrInput = new CdrInputStreamImpl(fragment); GiopHeader header = new GiopHeader(cdrInput); CheckGiop1_2OrLater(header); // GIOP 1.2 or newer: read request id from msg; for giop 1.2, the requestId follows just // after the header for request, reply, locateRequest and locateReply; only those messages // can be fragmented uint reqId = cdrInput.ReadULong(); int payLoadLength = (int)(header.ContentMsgLength - 4); lock (m_fragmentedMsgs.SyncRoot) { FragmentedMsgDesc fragmentDesc = new FragmentedMsgDesc(cdrInput, payLoadLength, header, reqId); m_fragmentedMsgs[reqId] = fragmentDesc; } }
public void TestLocateReplySerialisation() { uint requestId = 5; byte[] objectKey = new byte[] { 116, 101, 115, 116, 111, 98, 106, 101, 99, 116 }; // testobject string targetUri = "testobject"; GiopVersion version = new GiopVersion(1, 2); LocateRequestMessage locReq = new LocateRequestMessage(requestId, objectKey, targetUri); // create a connection context GiopConnectionDesc conDesc = new GiopConnectionDesc(null, null); // create the reply LocateStatus replyStatus = LocateStatus.OBJECT_HERE; LocateReplyMessage locReply = new LocateReplyMessage(replyStatus); MemoryStream targetStream = new MemoryStream(); m_handler.SerialiseOutgoingLocateReplyMessage(locReply, locReq, version, targetStream, conDesc); // check to serialised stream targetStream.Seek(0, SeekOrigin.Begin); CdrInputStreamImpl cdrIn = new CdrInputStreamImpl(targetStream); cdrIn.ConfigStream(0, version); // first is Giop-magic byte data; AssertBytesFollowing(m_giopMagic, cdrIn); // Giop version data = (byte) cdrIn.ReadOctet(); Assert.AreEqual(1, data); data = (byte) cdrIn.ReadOctet(); Assert.AreEqual(2, data); // flags: big-endian, no fragements data = (byte) cdrIn.ReadOctet(); Assert.AreEqual(0, data); // Giop Msg type: locate reply data = (byte) cdrIn.ReadOctet(); Assert.AreEqual((byte)GiopMsgTypes.LocateReply, data); // Giop Msg length uint msgLength = cdrIn.ReadULong(); cdrIn.SetMaxLength(msgLength); // req-id Assert.AreEqual(requestId, cdrIn.ReadULong()); // the location status Assert.AreEqual((uint)replyStatus, cdrIn.ReadULong()); }
public void TestReplySerialisation() { // request msg the reply is for MethodInfo methodToCall = typeof(TestService).GetMethod("Add"); object[] args = new object[] { ((Int32) 1), ((Int32) 2) }; string uri = "iiop://localhost:8087/testuri"; // Giop 1.2 will be used because no version spec in uri GiopVersion version = new GiopVersion(1, 2); TestMessage msg = new TestMessage(methodToCall, args, uri); msg.Properties[SimpleGiopMsg.REQUEST_ID_KEY] = (uint)5; msg.Properties[SimpleGiopMsg.GIOP_VERSION_KEY] = version; msg.Properties[SimpleGiopMsg.CALLED_METHOD_KEY] = methodToCall; msg.Properties[SimpleGiopMsg.IDL_METHOD_NAME_KEY] = methodToCall.Name; // done by serialization normally // create a connection context GiopConnectionDesc conDesc = new GiopConnectionDesc(null, null); // create the reply ReturnMessage retMsg = new ReturnMessage((Int32) 3, new object[0], 0, null, msg); MemoryStream targetStream = new MemoryStream(); m_handler.SerialiseOutgoingReplyMessage(retMsg, msg, version, targetStream, conDesc); // check to serialised stream targetStream.Seek(0, SeekOrigin.Begin); CdrInputStreamImpl cdrIn = new CdrInputStreamImpl(targetStream); cdrIn.ConfigStream(0, new GiopVersion(1, 2)); // first is Giop-magic byte data; AssertBytesFollowing(m_giopMagic, cdrIn); // Giop version data = (byte) cdrIn.ReadOctet(); Assert.AreEqual(1, data); data = (byte) cdrIn.ReadOctet(); Assert.AreEqual(2, data); // flags: big-endian, no fragements data = (byte) cdrIn.ReadOctet(); Assert.AreEqual(0, data); // Giop Msg type: reply data = (byte) cdrIn.ReadOctet(); Assert.AreEqual(1, data); // Giop Msg length uint msgLength = cdrIn.ReadULong(); cdrIn.SetMaxLength(msgLength); // req-id Assert.AreEqual(5, cdrIn.ReadULong()); // response status: NO_EXCEPTION Assert.AreEqual(0, cdrIn.ReadULong()); // ignore service contexts SkipServiceContexts(cdrIn); // Giop 1.2, must be aligned on 8 cdrIn.ForceReadAlign(Aligns.Align8); // now return value is following Assert.AreEqual(3, cdrIn.ReadLong()); }
public void TestRequestSerialisation() { // prepare message MethodInfo methodToCall = typeof(TestService).GetMethod("Add"); object[] args = new object[] { ((Int32) 1), ((Int32) 2) }; string uri = "iiop://localhost:8087/testuri"; // Giop 1.2 will be used because no version spec in uri Ior target = m_iiopUrlUtil.CreateIorForUrl(uri, ""); TestMessage msg = new TestMessage(methodToCall, args, uri); // prepare connection context GiopClientConnectionDesc conDesc = new GiopClientConnectionDesc(null, null, new GiopRequestNumberGenerator(), null); // serialise MemoryStream targetStream = new MemoryStream(); uint reqId = 5; m_handler.SerialiseOutgoingRequestMessage(msg, target.Profiles[0], conDesc, targetStream, reqId); // check to serialised stream targetStream.Seek(0, SeekOrigin.Begin); CdrInputStreamImpl cdrIn = new CdrInputStreamImpl(targetStream); cdrIn.ConfigStream(0, new GiopVersion(1, 2)); // first is Giop-magic byte data; AssertBytesFollowing(m_giopMagic, cdrIn); // Giop version data = (byte) cdrIn.ReadOctet(); Assert.AreEqual(1, data); data = (byte) cdrIn.ReadOctet(); Assert.AreEqual(2, data); // flags: big-endian, no fragements data = (byte) cdrIn.ReadOctet(); Assert.AreEqual(0, data); // Giop Msg type: request data = (byte) cdrIn.ReadOctet(); Assert.AreEqual(0, data); // Giop Msg length uint msgLength = cdrIn.ReadULong(); cdrIn.SetMaxLength(msgLength); // req-id Assert.AreEqual(reqId, cdrIn.ReadULong()); // response flags data = (byte) cdrIn.ReadOctet(); Assert.AreEqual(3, data); cdrIn.ReadPadding(3); // reserved // target Assert.AreEqual(0, cdrIn.ReadUShort()); // target must be testuri encoded as ascii-characters Assert.AreEqual(7 , cdrIn.ReadULong()); AssertBytesFollowing( new byte[] { 116, 101, 115, 116, 117, 114, 105 }, cdrIn); // now the target method follows: Add (string is terminated by a zero) Assert.AreEqual(4, cdrIn.ReadULong()); AssertBytesFollowing(new byte[] { 65, 100, 100, 0}, cdrIn); // now service contexts are following SkipServiceContexts(cdrIn); // Giop 1.2, must be aligned on 8 cdrIn.ForceReadAlign(Aligns.Align8); // now params are following Assert.AreEqual(1, cdrIn.ReadLong()); Assert.AreEqual(2, cdrIn.ReadLong()); }
internal void MsgReceivedCallback(MessageReceiveTask messageReceived) { Stream messageStream = messageReceived.MessageStream; GiopHeader header = messageReceived.Header; if (FragmentedMessageAssembler.IsFragmentedMessage(header)) { // defragment if (FragmentedMessageAssembler.IsStartFragment(header)) { m_fragmentAssembler.StartFragment(messageStream); messageReceived.StartReceiveMessage(); // receive next message return; // wait for next callback } else if (!FragmentedMessageAssembler.IsLastFragment(header)) { m_fragmentAssembler.AddFragment(messageStream); messageReceived.StartReceiveMessage(); // receive next message return; // wait for next callback } else { messageStream = m_fragmentAssembler.FinishFragmentedMsg(messageStream, out header); } } // here, the message is no longer fragmented, don't check for fragment here switch (header.GiopType) { case GiopMsgTypes.Request: ProcessRequestMessage(messageStream, messageReceived); // process this message // don't receive next message here, new message reception is started by dispatcher at appropriate time break; case GiopMsgTypes.LocateRequest: ProcessLocateRequestMessage(messageStream, messageReceived); // process this message // don't receive next message here, new message reception is started by dispatcher at appropriate time break; case GiopMsgTypes.Reply: // see, if somebody is interested in the response lock (m_waitingForResponse.SyncRoot) { uint replyForRequestId = ExtractRequestIdFromReplyMessage(messageStream); IResponseWaiter waiter = (IResponseWaiter)m_waitingForResponse[replyForRequestId]; if (waiter != null) { m_waitingForResponse.Remove(replyForRequestId); waiter.Response = messageStream; waiter.Notify(); } else { Debug.WriteLine("received not expected reply for request with id " + replyForRequestId); } } messageReceived.StartReceiveMessage(); // receive next message break; case GiopMsgTypes.LocateReply: // ignore, not interesting messageReceived.StartReceiveMessage(); // receive next message break; case GiopMsgTypes.CloseConnection: CloseConnection(); AbortAllPendingRequestsWaiting(); // if requests are waiting for a reply, abort them RaiseConnectionClosedEvent(); // inform about connection closure break; case GiopMsgTypes.CancelRequest: CdrInputStreamImpl input = new CdrInputStreamImpl(messageStream); GiopHeader cancelHeader = new GiopHeader(input); uint requestIdToCancel = input.ReadULong(); m_fragmentAssembler.CancelFragmentsIfInProgress(requestIdToCancel); messageReceived.StartReceiveMessage(); // receive next message break; case GiopMsgTypes.MessageError: CloseConnectionAfterUnexpectedException(new MARSHAL(16, CompletionStatus.Completed_MayBe)); AbortAllPendingRequestsWaiting(); // if requests are waiting for a reply, abort them RaiseConnectionClosedEvent(); // inform about connection closure break; default: // should not occur; // hint: fragment is also considered as error here, // because fragment should be handled before this loop // send message error SendErrorResponseMessage(); messageReceived.StartReceiveMessage(); // receive next message break; } }
/// <summary> /// extracts the request id from a non-fragmented reply message /// </summary> /// <param name="replyMessage"></param> private uint ExtractRequestIdFromReplyMessage(Stream replyMessage) { replyMessage.Seek(0, SeekOrigin.Begin); CdrInputStreamImpl reader = new CdrInputStreamImpl(replyMessage); GiopHeader msgHeader = new GiopHeader(reader); if (msgHeader.Version.IsBeforeGiop1_2()) { // GIOP 1.0 / 1.1, the service context collection preceeds the id SkipServiceContexts(reader); } return reader.ReadULong(); }
/// <summary> /// adds a fragment to the combined message. /// </summary> /// <returns>the fragment description for the message</returns> private FragmentedMsgDesc AddFragmentInternal(Stream fragment, bool isLastFragment) { CdrInputStreamImpl cdrInput = new CdrInputStreamImpl(fragment); GiopHeader header = new GiopHeader(cdrInput); CheckGiop1_2OrLater(header); // GIOP 1.2 or newer: read request id from fragment msg header uint reqId = cdrInput.ReadULong(); int payLoadLength = (int)(header.ContentMsgLength - 4); lock(m_fragmentedMsgs.SyncRoot) { FragmentedMsgDesc fragmentDesc = (FragmentedMsgDesc) m_fragmentedMsgs[reqId]; if (fragmentDesc == null) { throw new IOException("illegal fragment; not found previous fragment for request-id: " + reqId); } if (!isLastFragment) { fragmentDesc.AddFragment(cdrInput, payLoadLength); } else { fragmentDesc.AddLastFragment(cdrInput, payLoadLength); // remove the desc for unfinished msg from table m_fragmentedMsgs.Remove(reqId); } return fragmentDesc; } }
/// <summary>Start a new fragmented msg</summary> internal void StartFragment(Stream fragment) { CdrInputStreamImpl cdrInput = new CdrInputStreamImpl(fragment); GiopHeader header = new GiopHeader(cdrInput); CheckGiop1_2OrLater(header); // GIOP 1.2 or newer: read request id from msg; for giop 1.2, the requestId follows just // after the header for request, reply, locateRequest and locateReply; only those messages // can be fragmented uint reqId = cdrInput.ReadULong(); int payLoadLength = (int)(header.ContentMsgLength - 4); lock(m_fragmentedMsgs.SyncRoot) { FragmentedMsgDesc fragmentDesc = new FragmentedMsgDesc(cdrInput, payLoadLength, header, reqId); m_fragmentedMsgs[reqId] = fragmentDesc; } }
public void TestReplySerialisation() { // request msg the reply is for MethodInfo methodToCall = typeof(TestService).GetMethod("Add"); object[] args = new object[] { ((Int32)1), ((Int32)2) }; string uri = "iiop://localhost:8087/testuri"; // Giop 1.2 will be used because no version spec in uri GiopVersion version = new GiopVersion(1, 2); TestMessage msg = new TestMessage(methodToCall, args, uri); msg.Properties[SimpleGiopMsg.REQUEST_ID_KEY] = (uint)5; msg.Properties[SimpleGiopMsg.GIOP_VERSION_KEY] = version; msg.Properties[SimpleGiopMsg.CALLED_METHOD_KEY] = methodToCall; msg.Properties[SimpleGiopMsg.IDL_METHOD_NAME_KEY] = methodToCall.Name; // done by serialization normally // create a connection context GiopConnectionDesc conDesc = new GiopConnectionDesc(null, null); // create the reply ReturnMessage retMsg = new ReturnMessage((Int32)3, new object[0], 0, null, msg); MemoryStream targetStream = new MemoryStream(); m_handler.SerialiseOutgoingReplyMessage(retMsg, msg, version, targetStream, conDesc); // check to serialised stream targetStream.Seek(0, SeekOrigin.Begin); CdrInputStreamImpl cdrIn = new CdrInputStreamImpl(targetStream); cdrIn.ConfigStream(0, new GiopVersion(1, 2)); // first is Giop-magic byte data; AssertBytesFollowing(m_giopMagic, cdrIn); // Giop version data = (byte)cdrIn.ReadOctet(); Assert.AreEqual(1, data); data = (byte)cdrIn.ReadOctet(); Assert.AreEqual(2, data); // flags: big-endian, no fragements data = (byte)cdrIn.ReadOctet(); Assert.AreEqual(0, data); // Giop Msg type: reply data = (byte)cdrIn.ReadOctet(); Assert.AreEqual(1, data); // Giop Msg length uint msgLength = cdrIn.ReadULong(); cdrIn.SetMaxLength(msgLength); // req-id Assert.AreEqual(5, cdrIn.ReadULong()); // response status: NO_EXCEPTION Assert.AreEqual(0, cdrIn.ReadULong()); // ignore service contexts SkipServiceContexts(cdrIn); // Giop 1.2, must be aligned on 8 cdrIn.ForceReadAlign(Aligns.Align8); // now return value is following Assert.AreEqual(3, cdrIn.ReadLong()); }
public void TestRequestSerialisation() { // prepare message MethodInfo methodToCall = typeof(TestService).GetMethod("Add"); object[] args = new object[] { ((Int32)1), ((Int32)2) }; string uri = "iiop://localhost:8087/testuri"; // Giop 1.2 will be used because no version spec in uri Ior target = m_iiopUrlUtil.CreateIorForUrl(uri, ""); TestMessage msg = new TestMessage(methodToCall, args, uri); // prepare connection context GiopClientConnectionDesc conDesc = new GiopClientConnectionDesc(null, null, new GiopRequestNumberGenerator(), null); // serialise MemoryStream targetStream = new MemoryStream(); uint reqId = 5; m_handler.SerialiseOutgoingRequestMessage(msg, target.Profiles[0], conDesc, targetStream, reqId); // check to serialised stream targetStream.Seek(0, SeekOrigin.Begin); CdrInputStreamImpl cdrIn = new CdrInputStreamImpl(targetStream); cdrIn.ConfigStream(0, new GiopVersion(1, 2)); // first is Giop-magic byte data; AssertBytesFollowing(m_giopMagic, cdrIn); // Giop version data = (byte)cdrIn.ReadOctet(); Assert.AreEqual(1, data); data = (byte)cdrIn.ReadOctet(); Assert.AreEqual(2, data); // flags: big-endian, no fragements data = (byte)cdrIn.ReadOctet(); Assert.AreEqual(0, data); // Giop Msg type: request data = (byte)cdrIn.ReadOctet(); Assert.AreEqual(0, data); // Giop Msg length uint msgLength = cdrIn.ReadULong(); cdrIn.SetMaxLength(msgLength); // req-id Assert.AreEqual(reqId, cdrIn.ReadULong()); // response flags data = (byte)cdrIn.ReadOctet(); Assert.AreEqual(3, data); cdrIn.ReadPadding(3); // reserved // target Assert.AreEqual(0, cdrIn.ReadUShort()); // target must be testuri encoded as ascii-characters Assert.AreEqual(7, cdrIn.ReadULong()); AssertBytesFollowing( new byte[] { 116, 101, 115, 116, 117, 114, 105 }, cdrIn); // now the target method follows: Add (string is terminated by a zero) Assert.AreEqual(4, cdrIn.ReadULong()); AssertBytesFollowing(new byte[] { 65, 100, 100, 0 }, cdrIn); // now service contexts are following SkipServiceContexts(cdrIn); // Giop 1.2, must be aligned on 8 cdrIn.ForceReadAlign(Aligns.Align8); // now params are following Assert.AreEqual(1, cdrIn.ReadLong()); Assert.AreEqual(2, cdrIn.ReadLong()); }