/// <summary>
        /// Initialize new connection from server to tomcat in new thread.
        /// this connection will run in new thread spawned from the listener thread.
        /// </summary>
        public BonCodeAJP13ServerConnection(BonCodeAJP13Packet singlePacket)
        {
            CheckMutex();
            //package single package into packets to Send
            BonCodeAJP13PacketCollection packetsToSend = new BonCodeAJP13PacketCollection();

            packetsToSend.Add(singlePacket);
            //call connection creation
            p_CreateConnection(packetsToSend);
        }
 public void AddTest()
 {
     BonCodeAJP13PacketCollection target = new BonCodeAJP13PacketCollection(); // TODO: Initialize to an appropriate value
     BonCodeAJP13Packet value = null; // TODO: Initialize to an appropriate value
     int expected = 0; // TODO: Initialize to an appropriate value
     int actual;
     actual = target.Add(value);
     Assert.AreEqual(expected, actual);
     Assert.Inconclusive("Verify the correctness of this test method.");
 }
        /// <summary>
        /// Initialize new connection to tomcat using server and port input
        /// </summary>
        public BonCodeAJP13ServerConnection(string server, int port, BonCodeAJP13Packet singlePacket)
        {
            CheckMutex();
            this.Port   = port;
            this.Server = server;
            //create collection and add packet passed
            BonCodeAJP13PacketCollection packetsToSend = new BonCodeAJP13PacketCollection();

            packetsToSend.Add(singlePacket);
            //call connection creation
            p_CreateConnection(packetsToSend);
        }
        /// <summary>
        /// Initialize new connection from server to tomcat in new thread.
        /// Delayed connection init. Will wait until connection is initialized
        /// </summary>
        public BonCodeAJP13ServerConnection(BonCodeAJP13Packet singlePacket, bool delayConnection = true)
        {
            CheckMutex();
            //package single package into packets to Send
            BonCodeAJP13PacketCollection packetsToSend = new BonCodeAJP13PacketCollection();

            packetsToSend.Add(singlePacket);
            p_PacketsToSend = packetsToSend; //assign to instance store
            //call connection creation if desired
            if (!delayConnection)
            {
                p_CreateConnection(packetsToSend);
            }
        }
 /// <summary>
 /// Initialize new connection to tomcat using server and port input
 /// DEPRECATED DO NOT USE
 /// </summary>
 public BonCodeAJP13ServerConnection(string server, int port, BonCodeAJP13Packet singlePacket)
 {
     CheckMutex();
     this.Port = port;
     this.Server = server;
     //create collection and add packet passed
     BonCodeAJP13PacketCollection packetsToSend = new BonCodeAJP13PacketCollection();
     packetsToSend.Add(singlePacket);
     //call connection creation
     p_CreateConnection(packetsToSend);
 }
 /// <summary>
 /// Initialize new connection from server to tomcat in new thread.
 /// this connection will run in new thread spawned from the listener thread.
 /// DEPRECATED DO NOT USE
 /// </summary>
 public BonCodeAJP13ServerConnection(BonCodeAJP13Packet singlePacket)
 {
     CheckMutex();
     //package single package into packets to Send
     BonCodeAJP13PacketCollection packetsToSend = new BonCodeAJP13PacketCollection();
     packetsToSend.Add(singlePacket);
     //call connection creation
     p_CreateConnection(packetsToSend);
 }
 /// <summary>
 /// Initialize new connection from server to tomcat in new thread.
 /// Delayed connection init. Will wait until connection is initialized
 /// DEPRECATED DO NOT USE
 /// </summary>
 public BonCodeAJP13ServerConnection(BonCodeAJP13Packet singlePacket, bool delayConnection = true)
 {
     CheckMutex();
     //package single package into packets to Send
     BonCodeAJP13PacketCollection packetsToSend = new BonCodeAJP13PacketCollection();
     packetsToSend.Add(singlePacket);
     p_PacketsToSend = packetsToSend; //assign to instance store
     //call connection creation if desired
     if (!delayConnection)
     {
         p_CreateConnection(packetsToSend);
     }
 }
        /// <summary>
        /// Analyze the provided buffer and returns a collection of packets represented by the buffer
        /// </summary>
        public static BonCodeAJP13PacketCollection GetPackets(byte[] Buffer)
        {
            BonCodeAJP13PacketCollection AnalyzedResponses = new BonCodeAJP13PacketCollection();

            if (Buffer != null)
            {
                int start = 0;
                for (int i = 0; i < Buffer.Length; i++)
                {
                    if (Buffer[start] == BonCodeAJP13PacketFormat.BONCODEAJP13_PACKET_START)
                    {
                        UInt16 UserDataLength = 0;
                        GetUInt16(Buffer, ref UserDataLength, start + USERDATALENGTH_POS);
                        i = start + UserDataLength + 8;

                        // here we need to truncate the buffer and analyze the packet.
                        if (Buffer[i] == BonCodeAJP13PacketFormat.BONCODEAJP13_PACKET_END)
                        {

                            byte[] NewPacket = new byte[i + 1 - start];
                            Array.Copy(Buffer, start, NewPacket, 0, i + 1 - start);

                            BonCodeAJP13Packet packet = BonCodeAJP13Packet.GetPacket(NewPacket);
                            if (packet != null)
                            {
                                AnalyzedResponses.Add(packet);
                            }
                            else
                            {
                                return null;
                            }

                            start = i + 1;
                        }
                        else
                        {
                            return null;
                        }
                    }
                    else
                    {
                        return null;
                    }
                }
                return AnalyzedResponses;
            }
            else
            {
                return null;
            }
        }
        /// <summary>
        /// Review received bytes and put them into the package container
        /// </summary>
        private byte[] AnalyzePackage(byte[] receiveBuffer, bool skipFlush = false)
        {
            //the packages received by tomcat have to start with the correct package signature start bytes (41 42 or AB)
            int iStart = 0;

            byte[] searchFor = new byte[2] {
                0x41, 0x42
            };
            int packetLength = 0;

            byte[] unalyzedBytes = null;
            int    iSafety       = 0; //safety check for exit condition (max theoretical packets to be analyze is 8196/4)

            while (iStart >= 0 && iStart <= receiveBuffer.Length - 1 && iSafety <= 2050)
            {
                iSafety++;

                //find packet start bytes (41 42 or AB)
                iStart = ByteSearch(receiveBuffer, searchFor, iStart);
                if (iStart >= 0)
                {
                    //determine end of packet
                    try
                    {
                        packetLength = GetInt16B(receiveBuffer, iStart + 2);
                    }
                    catch (Exception e)
                    {
                        //log exception
                        if (p_Logger != null)
                        {
                            p_Logger.LogException(e, "packet length determination problem", 1);
                        }
                    }
                    //check whether we have sufficient data in receive buffer to analyze package
                    if (packetLength + iStart + 4 <= receiveBuffer.Length)
                    {
                        //TODO: check whether packet length is beyond maximum and throw error
                        int    packetType = (int)receiveBuffer[iStart + 4];
                        byte[] userData   = new byte[packetLength];
                        //we skip 4-bytes:magic (AB) and packet length markers when determining user data
                        Array.Copy(receiveBuffer, iStart + 4, userData, 0, packetLength);


                        //Detect Correct packet Type and create instance of store
                        switch (packetType)
                        {
                        case BonCodeAJP13TomcatPacketType.TOMCAT_GETBODYCHUNK:
                            p_PacketsReceived.Add(new TomcatGetBodyChunk(userData));
                            //if this command is encountered when only one GET package was previously send (no multi-packets) we need to send a terminator body package
                            if (p_PacketsToSend.Count == 1)
                            {
                                p_SendTermPacket = true;
                            }

                            //p_NetworkStream.Write(sendPacket.GetDataBytes(), 0, sendPacket.PacketLength);
                            break;

                        case BonCodeAJP13TomcatPacketType.TOMCAT_ENDRESPONSE:
                            p_PacketsReceived.Add(new TomcatEndResponse(userData));
                            //this is the termination indicator we need to stop processing from here on. This can happen
                            //when we post data as well. Tomcat can indicate a connection stop and we need to stop processing as well.

                            break;

                        case BonCodeAJP13TomcatPacketType.TOMCAT_SENDHEADERS:
                            p_PacketsReceived.Add(new TomcatSendHeaders(userData));
                            break;

                        case BonCodeAJP13TomcatPacketType.TOMCAT_CPONGREPLY:
                            p_PacketsReceived.Add(new TomcatCPongReply(userData));
                            break;

                        case BonCodeAJP13TomcatPacketType.TOMCAT_SENDBODYCHUNK:
                            p_PacketsReceived.Add(new TomcatSendBodyChunk(userData));
                            break;

                        default:
                            //we don't know this type of package; add to collection anyway and log it, we will not raise error but continue processing
                            p_PacketsReceived.Add(new TomcatReturn(userData));
                            if (p_Logger != null)
                            {
                                p_Logger.LogMessage("Unknown Packet Type Received, see next log entry:", 1);
                                p_Logger.LogPacket(p_PacketsReceived[p_PacketsReceived.Count - 1], true);
                            }
                            ;

                            break;
                        }


                        //Log packets Received. Whether the packet will actually be logged depends on log level chosen.
                        if (p_Logger != null)
                        {
                            p_Logger.LogPacket(p_PacketsReceived[p_PacketsReceived.Count - 1]);
                        }

                        //reset new iStart
                        iStart = iStart + packetLength - 1;

                        //detect end package
                        if (packetType == BonCodeAJP13TomcatPacketType.TOMCAT_ENDRESPONSE)
                        {
                            p_IsLastPacket = true;
                            p_IsFlush      = false;
                        }
                        else
                        {
                            //check whether we need monitor for tomcat flush signs
                            if (BonCodeAJP13Settings.BONCODEAJP13_AUTOFLUSHDETECTION_THRESHOLD > 0)
                            {
                                long elapsedTicks = p_StopWatch.ElapsedTicks;
                                p_TickDelta = elapsedTicks - p_LastTick;
                                p_LastTick  = elapsedTicks;
                                if (p_TickDelta > BonCodeAJP13Settings.BONCODEAJP13_AUTOFLUSHDETECTION_THRESHOLD)
                                {
                                    //flush has been detected set the flag. We should flush after this receiveBuffer has been processed.
                                    //no flush is needed if we see end marker during receiveBuffer processing

                                    p_IsFlush = true;
                                }
                            }
                        }
                    }
                    else
                    {
                        //we need to read more data before we can process. For now mark these bytes as unanalyzed and return to stream reader
                        unalyzedBytes = new byte[receiveBuffer.Length - iStart];
                        Array.Copy(receiveBuffer, iStart, unalyzedBytes, 0, receiveBuffer.Length - iStart);
                        //set breakout conditions
                        iStart = iStart + packetLength - 1;
                        break;
                    }
                }
            }

            //flush skip check
            if (skipFlush)
            {
                p_IsFlush = false;
            }


            //flush processing
            if (p_IsFlush)
            {
                //do what is needed to flush data so far
                ProcessFlush();

                //reset flush marker
                p_IsFlush = false;
            }

            return(unalyzedBytes);
        }
 /// <summary>
 /// add a package to the collection of packets to be send to tomcat
 /// </summary>
 public void AddPacketToSendQueue(BonCodeAJP13Packet singlePacket)
 {
     p_PacketsToSend.Add(singlePacket);
 }