BonCodeAJP13.BonCodeAJP13ServerConnection.AnalyzePackage C# (CSharp) Method

AnalyzePackage() private method

Primary Signature for Analyzing Package. Review received bytes and put them into the package container. Added delayWriteIndicator in case write occured in this context we want to delay writing for POST.
private AnalyzePackage ( bool &delayWriteIndicator, byte receiveBuffer, bool skipFlush = false, int iOffset ) : byte[]
delayWriteIndicator bool
receiveBuffer byte
skipFlush bool
iOffset int
return byte[]
        private byte[] AnalyzePackage(ref bool delayWriteIndicator, byte[] receiveBuffer, bool skipFlush = false, int iOffset = 0)
        {
            //the packages received by tomcat have to start with the correct package signature start bytes (41 42 or AB)
            int iStart = 0 + iOffset; //offset determines where we start in this package
            byte[] searchFor = new byte[2] { 0x41, 0x42 };
            int packetLength = 0;
            byte[] unalyzedBytes = null;
            int iSafety = 0; //safety check for exit condition (with standard packets and a min packet size of 4 bytes 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 if this is negative we need continue scanning
                    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];
                        string adobePath = "";
                        string requestPath = "";

                        //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:
                                //only add user data if there is something so we don't create null packets (this condition may not occur)
                                if (userData.Length > 0)
                                {
                                    p_PacketsReceived.Add(new TomcatSendBodyChunk(userData));
                                    //check whether we have an AJP flush and whether we will accept it. In that case we have only four bytes in the packet. No user payload.
                                    if (userData.Length == 4 && (BonCodeAJP13Settings.BONCODEAJP13_AUTOFLUSHDETECTION_TICKS > 0 || BonCodeAJP13Settings.BONCODEAJP13_AUTOFLUSHDETECTION_BYTES > 0))
                                    {
                                        p_IsFlush = true;
                                    }

                                }
                                else
                                {
                                    //warning
                                    if (p_Logger != null) p_Logger.LogMessage("Received empty user packet in TOMCAT_SENDBODYCHUNK, skipping.", BonCodeAJP13LogLevels.BONCODEAJP13_LOG_DEBUG);
                                }
                                break;

                            case BonCodeAJP13TomcatPacketType.TOMCAT_CFPATHREQUEST:
                                //this is Adobe specific we will need to send back a header
                                p_PacketsReceived.Add(new TomcatPhysicalPathRequest(userData));

                                requestPath = ((TomcatPhysicalPathRequest)p_PacketsReceived[p_PacketsReceived.Count - 1]).GetFilePath();
                                adobePath = ""; //this will contain the resolved absolute path
                                //TODO: move the following into a response queue
                                //prep response and return now CF will ask for two paths one for index.htm one for the actual URI
                                //The user did not ask for index.htm it is how CF marks docroot vs final path
                                if (requestPath == "/index.htm")
                                {
                                    adobePath = BonCodeAJP13Settings.BonCodeAjp13_DocRoot + "index.htm";
                                }
                                else
                                {
                                    //if we get bogus requests to paths that don't exist or have fake data this will error. Adobe CF just appends the request to doc root when error. We will do the same.
                                    try
                                    {
                                        adobePath = ServerPath(requestPath); //System.Web.HttpContext.Current.Server.MapPath("/yeah") ;//BonCodeAJP13Settings.BonCodeAjp13_PhysicalFilePath;
                                    }
                                    catch (Exception e)
                                    {
                                        //if (p_Logger != null) p_Logger.LogException(e, "Problem determining absolute path [" + adobePath + "] for provided relative path: [" + requestPath + "]. Please ensure that provided path is a relative path and there is a virtual mapping and you have spelled correctly.");
                                        if (p_Logger != null) p_Logger.LogMessageAndType("Problem determining absolute path [" + adobePath + "] for provided relative path: [" + requestPath + "]. Please ensure that provided path is a relative path and there is a virtual mapping and you have spelled correctly.", "warning", BonCodeAJP13LogLevels.BONCODEAJP13_LOG_BASIC);
                                        adobePath = BonCodeAJP13Settings.BonCodeAjp13_DocRoot + requestPath;
                                    }
                                };

                                //build a response package
                                BonCodeFilePathPacket pathResponse = null;
                                pathResponse = new BonCodeFilePathPacket(adobePath);

                                p_NetworkStream.Write(pathResponse.GetDataBytes(), 0, pathResponse.PacketLength);
                                if (p_Logger != null) p_Logger.LogPacket(pathResponse);
                                delayWriteIndicator = true; //prevent main process from writing to network stream

                                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:", BonCodeAJP13LogLevels.BONCODEAJP13_LOG_ERRORS);
                                    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 + 4 + packetLength - 1;

                        //detect end package
                        if (packetType == BonCodeAJP13TomcatPacketType.TOMCAT_ENDRESPONSE)
                        {
                            p_IsLastPacket = true;
                            p_IsFlush = false;
                        }
                        else
                        {
                            //old flush check position
                            /*
                            //check whether we need monitor for tomcat flush signs
                            if (BonCodeAJP13Settings.BONCODEAJP13_AUTOFLUSHDETECTION_TICKS > 0)
                            {
                                long elapsedTicks = p_StopWatch.ElapsedTicks;
                                p_TickDelta = elapsedTicks - p_LastTick;
                                p_LastTick = elapsedTicks;
                                if (p_TickDelta > BonCodeAJP13Settings.BONCODEAJP13_AUTOFLUSHDETECTION_TICKS)
                                {
                                    //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;
        }

Same methods

BonCodeAJP13ServerConnection::AnalyzePackage ( byte receiveBuffer, bool skipFlush = false, int iOffset ) : byte[]