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; } }
public void TestCantAddFragmentIfNotStarted() { Stream msgStream = new MemoryStream(); byte endianFlags = 0; uint reqId = 15; uint lastFragmentContentLength = 13; uint currentOffsetInMsg = 0; // the content offset for the next message GiopVersion version = new GiopVersion(1,2); CdrOutputStreamImpl cdrOut = new CdrOutputStreamImpl(msgStream, endianFlags, version); AddFinishFragment(cdrOut, version, endianFlags, reqId, lastFragmentContentLength, currentOffsetInMsg); msgStream.Seek(0, SeekOrigin.Begin); try { FragmentedMessageAssembler assembler = new FragmentedMessageAssembler(); // finish fragment GiopHeader combinedHeader; assembler.FinishFragmentedMsg(msgStream, out combinedHeader); Assert.Fail("accepted finish fragment, although no start fragment seen"); } catch (IOException) { // ok, no start fragment found } }
public void TestCantAddFragmentAfterMessageFinished() { Stream msgStream = new MemoryStream(); byte endianFlags = 0; uint reqId = 16; uint startMsgContentBlocks = 2; // make sure, that start fragment length is a multiple of 8; giop 1.2 uint lastFragmentContentLength = 13; uint currentOffsetInMsg = 0; // the content offset for the next message GiopVersion version = new GiopVersion(1,2); CdrOutputStreamImpl cdrOut = AddStartMsg(msgStream, version, endianFlags, reqId, startMsgContentBlocks, out currentOffsetInMsg); uint endOffset = AddFinishFragment(cdrOut, version, endianFlags, reqId, lastFragmentContentLength, currentOffsetInMsg); msgStream.Seek(0, SeekOrigin.Begin); // start fragment FragmentedMessageAssembler assembler = new FragmentedMessageAssembler(); assembler.StartFragment(msgStream); // finish fragment GiopHeader combinedHeader; assembler.FinishFragmentedMsg(msgStream, out combinedHeader); // now check, that no additional finish fragment is supported msgStream = new MemoryStream(); currentOffsetInMsg = 0; // the content offset for the next message cdrOut = new CdrOutputStreamImpl(msgStream, endianFlags, version); AddFinishFragment(cdrOut, version, endianFlags, reqId, lastFragmentContentLength, currentOffsetInMsg); msgStream.Seek(0, SeekOrigin.Begin); try { // finish fragment assembler.FinishFragmentedMsg(msgStream, out combinedHeader); Assert.Fail("accepted finish fragment, although no start fragment seen"); } catch (IOException) { // ok, no start fragment found } }
private void InternalTestThreeFramgents(GiopVersion version) { Stream msgStream = new MemoryStream(); byte endianFlags = 0; uint reqId = 11; uint startMsgContentBlocks = 2; // make sure, that start fragment length is a multiple of 8; giop 1.2 uint middleMsgContentBlocks = 4; // make sure, that middle fragment length is a multiple of 8; giop 1.2 uint lastFragmentContentLength = 13; uint currentOffsetInMsg = 0; // the content offset for the next message CdrOutputStreamImpl cdrOut = AddStartMsg(msgStream, version, endianFlags, reqId, startMsgContentBlocks, out currentOffsetInMsg); currentOffsetInMsg = AddFragmentInTheMiddle(cdrOut, version, endianFlags, reqId, middleMsgContentBlocks, currentOffsetInMsg); uint endOffset = AddFinishFragment(cdrOut, version, endianFlags, reqId, lastFragmentContentLength, currentOffsetInMsg); msgStream.Seek(0, SeekOrigin.Begin); // start fragment FragmentedMessageAssembler assembler = new FragmentedMessageAssembler(); assembler.StartFragment(msgStream); // middle fragment assembler.AddFragment(msgStream); // finish fragment GiopHeader combinedHeader; Stream resultStream = assembler.FinishFragmentedMsg(msgStream, out combinedHeader); CheckAssembledMessage(resultStream, version, endianFlags, reqId, endOffset); }