BonCodeAJP13.ServerPackets.BonCodeAJP13ForwardRequest.WritePacket C# (CSharp) Метод

WritePacket() приватный Метод

Creates actual forward request package and stores in p_ByteStore of the instance
private WritePacket ( byte method, string protocol, string req_uri, string remote_addr, string remote_host, string server_name, ushort server_port, bool is_ssl, int num_headers, NameValueCollection httpHeaders, String realPathInfo = "", int sourcePort, String vDirs = "" ) : void
method byte
protocol string
req_uri string
remote_addr string
remote_host string
server_name string
server_port ushort
is_ssl bool
num_headers int
httpHeaders System.Collections.Specialized.NameValueCollection
realPathInfo String
sourcePort int
vDirs String
Результат void
        private void WritePacket(byte method,
                            string protocol,
                            string req_uri,
                            string remote_addr,
                            string remote_host,
                            string server_name,
                            ushort server_port,
                            bool is_ssl,
                            int num_headers,
                            NameValueCollection httpHeaders,
                            String realPathInfo ="",
                            int sourcePort=0,
                            String vDirs="")
        {
            //locals
            int pos = 0;
            byte attributeByte = 0x00;
            byte[] aUserData = new byte[BonCodeAJP13Settings.MAX_BONCODEAJP13_PACKET_LENGTH]; //allocate full number of bytes for processing
            int packetFillBytes = 14; //bytes used to complete package
            int expectedPacketSize = 0;
            string keyName = "";
            string keyValue = "";

            NameValueCollection goodHeaders = CheckHeaders(httpHeaders); //determine headers to be transferred
            num_headers = goodHeaders.AllKeys.Length;
            PopulateRawHeaders(httpHeaders["ALL_RAW"]); //we use this to do retranslate the spelling (case) of header names

            //populate log values
            if (BonCodeAJP13Settings.BONCODEAJP13_LOG_LEVEL >= BonCodeAJP13LogLevels.BONCODEAJP13_LOG_HEADERS)
            {
                p_Method = BonCodeAJP13PacketHeaders.GetMethodString(method);   //not using: GetKeyValue(httpHeaders, "REQUEST_METHOD");
                p_Url = req_uri;
                p_HttpHeaders = goodHeaders;
            }

            //add optional headers and reset count
            NameValueCollection addlHeaders = new NameValueCollection();

            if (BonCodeAJP13Settings.BONCODEAJP13_HEADER_SUPPORT)    // "X-Tomcat-DocRoot";
            {
                addlHeaders.Add("x-tomcat-docroot", BonCodeAJP13Settings.BonCodeAjp13_DocRoot);   // System.Web.HttpContext.Current.Server.MapPath("~"); alternatly we could use "appl-physical-path" http var
                if (vDirs.Length > 3)
                {
                    addlHeaders.Add("x-vdirs", vDirs);
                }
                //instance id
                addlHeaders.Add("x-webserver-context", "W3SVC" + httpHeaders["INSTANCE_ID"]);
                //if we have a shared key send it
                if (BonCodeAJP13Settings.BONCODE_MODCFML_SECRET.Length > 0) {
                    addlHeaders.Add("X-ModCFML-SharedKey", BonCodeAJP13Settings.BONCODE_MODCFML_SECRET);
                }
            }

            //path info alternate header determination
            if (BonCodeAJP13Settings.BONCODEAJP13_PATHINFO_HEADER != "")    // "xajp-path-info";
            {
                addlHeaders.Add(BonCodeAJP13Settings.BONCODEAJP13_PATHINFO_HEADER, realPathInfo);   // httpHeaders["PATH_INFO"]
            }

            //determine client fingerprint based on HTTP information
            if (BonCodeAJP13Settings.BONCODEAJP13_ENABLE_CLIENTFINGERPRINT)
            {
                addlHeaders.Add("xajp-clientfingerprint", GetFingerprint(httpHeaders));
            }

            //during debug logging also add thread id to headers
            if (BonCodeAJP13Settings.BONCODEAJP13_LOG_LEVEL == BonCodeAJP13LogLevels.BONCODEAJP13_LOG_DEBUG)   // debug test threadid
            {
                addlHeaders.Add("xajp-managedthreadid", "" + System.Threading.Thread.CurrentThread.ManagedThreadId);
            }

            //reset count of headers
            num_headers += addlHeaders.Count;

            //add a mapping prefix if one is provided unless the same prefix is already on the start of Uri (case sensitive comparison)
            if (BonCodeAJP13Settings.BONCODEAJP13_PATH_PREFIX.Length > 2
                && !BonCodeAJP13Settings.BONCODEAJP13_PATH_PREFIX.Equals(req_uri.Substring(0, BonCodeAJP13Settings.BONCODEAJP13_PATH_PREFIX.Length - 1), StringComparison.Ordinal))
            {
                req_uri = BonCodeAJP13Settings.BONCODEAJP13_PATH_PREFIX + req_uri;
            }

            //write start of a packet
            // ============================================================
            pos = SetByte(aUserData, BonCodeAJP13ServerPacketType.SERVER_FORWARD_REQUEST, pos); // all have to start with this
            pos = SetByte(aUserData, method, pos);  //method: e.g. we have clicked on URL
            pos = SetString(aUserData, protocol, pos); //protocol
            pos = SetString(aUserData, req_uri, pos); //uri any call to SetString will UTF8 encode by default
            pos = SetString(aUserData, remote_addr, pos); //remote addr
            pos = SetString(aUserData, remote_host, pos); //remote host
            pos = SetString(aUserData, server_name, pos); //server name
            pos = SetInt16(aUserData, server_port, pos); //port
            pos = SetByte(aUserData, Convert.ToByte(is_ssl), pos); //is ssl
            pos = SetInt16(aUserData, System.Convert.ToUInt16(num_headers), pos); //number of headers
            //pos = SetInt16(aUserData, System.Convert.ToUInt16(goodHeaders.AllKeys.Length), pos); //number of headers
            //iterate through headers and add to packet

            //first write all additional headers
            foreach (String key in addlHeaders)
            {
                pos = SetString(aUserData, key.ToLower(), pos);
                pos = SetString(aUserData, addlHeaders[key], pos);
            }

            //TODO Remove this
            /*
            keyName = "xajp-setting-drive";
            keyValue = BonCodeAJP13Logger.GetAssemblyDirectory();
            pos = SetString(aUserData, keyName.ToLower(), pos);
            pos = SetString(aUserData, keyValue, pos);

            keyName = "xajp-setting-file";
            keyValue = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
            pos = SetString(aUserData, keyName.ToLower(), pos);
            pos = SetString(aUserData, keyValue, pos);
             */
            //END REMOVE THIS

            //all other headers
            for (int i = 0; i < goodHeaders.AllKeys.Length; i++)
            {
                keyName = goodHeaders.AllKeys[i];
                keyValue = goodHeaders[keyName];
                expectedPacketSize = keyName.Length + keyValue.Length + pos + packetFillBytes;

                if (expectedPacketSize < BonCodeAJP13Settings.MAX_BONCODEAJP13_PACKET_LENGTH)
                {
                    //add byte or string header name
                    if (BonCodeAJP13PacketHeaders.GetHeaderBytes(keyName) != null)
                    {
                        //byte header
                        pos = SetSimpleByteArray(aUserData, BonCodeAJP13PacketHeaders.GetHeaderBytes(keyName), pos);
                    }
                    else
                    {
                        //string header (remove HTTP prefix this is added by IIS) and change underscore
                        pos = SetString(aUserData, GetCorrectHeaderName(keyName), pos);
                    }
                    //add value if keyName is not empty string
                    pos = SetString(aUserData, keyValue, pos);
                }
                else
                {
                    //raise error:
                    throw new Exception("Invalid content length. Last header processed [" + keyName + "]. Please reconfigure BonCode Connector and Apache Tomcat to allow larger transfer packets. Your max allowed content length is " + BonCodeAJP13Settings.MAX_BONCODEAJP13_USERDATA_LENGTH + " bytes. Provided content length would be at least " + expectedPacketSize + " bytes. Clearing cookies may allow you proceed.");
                }

            }

            //add SSL-Cert information to AJP ATTRIBUTES as well since this is how the servlet container accepts them
            if (clientCert != null)
            {

                //This is the only SSL attribute exchanged as byte type all others are explicitly named
                //pos = SetByte(aUserData, BonCodeAJP13HTTPAttributes.BONCODEAJP13_SSL_CERT, pos); //attribute marker
                //pos = SetString(aUserData, CertExportToPEM(clientCert), pos); //attribute value

                //set named AJP Attributes
                NameValueCollection addlAtts = new NameValueCollection();
                addlAtts.Add("SSL_CLIENTCERT", CertExportToPEM(clientCert));
                addlAtts.Add("CERT_ISSUER", clientCert.Issuer);
                addlAtts.Add("CERT_SUBJECT", clientCert.Subject);
                addlAtts.Add("CERT_COOKIE", httpHeaders["CERT_COOKIE"]);
                addlAtts.Add("HTTPS_SERVER_SUBJECT", httpHeaders["CERT_SERVER_SUBJECT"]);
                addlAtts.Add("CERT_FLAGS", httpHeaders["CERT_FLAGS"]);
                //addlAtts.Add("HTTPS_SECRETKEYSIZE", httpHeaders["CERT_SECRETKEYSIZE"]);  // this is done later and extracted from http headers
                addlAtts.Add("CERT_SERIALNUMBER", clientCert.GetSerialNumberString());
                addlAtts.Add("HTTPS_SERVER_ISSUER", httpHeaders["CERT_SERVER_ISSUER"]);
                addlAtts.Add("HTTPS_KEYSIZE", httpHeaders["CERT_KEYSIZE"]);

                //now write named attributes
                for (int i = 0; i < addlAtts.AllKeys.Length; i++)
                {
                    keyName = addlAtts.AllKeys[i];
                    keyValue = addlAtts[keyName];
                    expectedPacketSize = keyName.Length + keyValue.Length + pos + packetFillBytes;
                    attributeByte = BonCodeAJP13PacketHeaders.GetAttributeByte(keyName);
                    //check whether this is byte attribute if so wee need to add the header as attribute to packet
                    if (keyValue != "")
                    {
                        if (expectedPacketSize < BonCodeAJP13Settings.MAX_BONCODEAJP13_PACKET_LENGTH)
                        {
                            //set either name or byte attribute name
                            if (attributeByte == 0x00)
                            {
                                //set attribute name as string
                                pos = SetByte(aUserData, BonCodeAJP13HTTPAttributes.BONCODEAJP13_REQ_ATTRIBUTE, pos); //attribute marker
                                pos = SetString(aUserData, keyName, pos); //attribute name
                            }
                            else
                            {
                                //set as byte-type
                                pos = SetByte(aUserData, attributeByte, pos); //attribute marker
                            }

                            //set value of attribute
                            pos = SetString(aUserData, keyValue, pos); //attribute value as string

                        }
                        else
                        {
                            throw new Exception("Invalid content length. Last attribute processed [" + keyName + "]. Please reconfigure BonCode Connector and Apache Tomcat to allow larger transfer packets. Your max allowed content length is " + BonCodeAJP13Settings.MAX_BONCODEAJP13_USERDATA_LENGTH + " bytes. Provided content length would be at least " + expectedPacketSize + " bytes.");
                        }
                    }
                }

            }

            //EXTRACT AND WRITE BYTE TYPE ATTRIBUTES FOLLOW:
            //Second iteration through headers Some header values have to be passed as attributes REMOTE_USER, AUTH_TYPE, QUERY_STRING
            for (int i = 0; i < httpHeaders.AllKeys.Length; i++)
            {
                keyName = httpHeaders.AllKeys[i];
                keyValue = httpHeaders[keyName];
                expectedPacketSize = keyName.Length + keyValue.Length + pos + packetFillBytes;
                attributeByte = BonCodeAJP13PacketHeaders.GetAttributeByte(keyName);
                //check whether this is byte attribute if so wee need to add the header as attribute to packet
                if (attributeByte != 0x00 && keyValue != "")
                {
                    if (expectedPacketSize < BonCodeAJP13Settings.MAX_BONCODEAJP13_PACKET_LENGTH)
                    {
                        pos = SetByte(aUserData, attributeByte, pos); //attribute marker

                        if (attributeByte == 0x0B)  //the SSL Key Size attribute is the only one currently that needs to be sent as Uint
                        {
                            pos = SetUInt16(aUserData, System.Convert.ToUInt16(keyValue), pos); //attribute value as int (high/low)
                        }
                        else
                        {
                            pos = SetString(aUserData, keyValue, pos); //attribute value as string
                        }

                    }
                    else
                    {
                        throw new Exception("Invalid content length. Last header processed [" + keyName + "]. Please reconfigure BonCode Connector and Apache Tomcat to allow larger transfer packets. Your max allowed content length is " + BonCodeAJP13Settings.MAX_BONCODEAJP13_USERDATA_LENGTH + " bytes. Provided content length would be at least " + expectedPacketSize + " bytes.");
                    }
                }
            }

            //WRITE NAMED ATTRIBUTES

            //add secure session attribute
            if (BonCodeAJP13Settings.BONCODEAJP13_FORCE_SECURE_SESSION)
            {
                pos = SetByte(aUserData, BonCodeAJP13HTTPAttributes.BONCODEAJP13_SSL_SESSION, pos); //attribute marker
                pos = SetString(aUserData, "on", pos); //attribute value
            }

            //add request shared secret key
            if (BonCodeAJP13Settings.BONCODEAJP13_REQUEST_SECRET.Length > 0)
            {
                pos = SetByte(aUserData, BonCodeAJP13HTTPAttributes.BONCODEAJP13_SECRET, pos); //attribute marker
                pos = SetString(aUserData, BonCodeAJP13Settings.BONCODEAJP13_REQUEST_SECRET, pos); //attribute value
            }

            //add constant attribute for AJP13 JVM Route
            /*
            pos = SetByte(aUserData, BonCodeAJP13HTTPAttributes.BONCODEAJP13_JVM_ROUTE, pos); //attribute marker
            pos = SetString(aUserData, BonCodeAJP13Markers.BONCODEAJP13_PROTOCOL_MARKER, pos); //attribute value
            */

            //add pathinfo attempt to bypass tomcat bug
            /*
            pos = SetByte(aUserData, BonCodeAJP13HTTPAttributes.BONCODEAJP13_REQ_ATTRIBUTE, pos); //attribute marker
            pos = SetString(aUserData, "path_info", pos); //attribute name
            pos = SetString(aUserData, httpHeaders["PATH_INFO"], pos); //attribute value
             */

            //START ADOBE MODIFICATIONS

            //add Adobe ColdFusion 10 specific attributes, this is backwards since this data is already available, adobe chose to
            //transfer again in attributes because of problems with ISAPI constructed connector

            //SERVER_SOFTWARE VIA ATTRIBUTES
            //pos = SetByte(aUserData, 0x0E, pos); //attribute marker for web server
            //pos = SetString(aUserData, httpHeaders["SERVER_SOFTWARE"], pos); //attribute value

            //END OF ADOBE MODIFICATIONS

            //Remote port marker seems to be a common element transferred in attributes
            if (sourcePort > 0)
            {
                pos = SetByte(aUserData, BonCodeAJP13HTTPAttributes.BONCODEAJP13_REQ_ATTRIBUTE, pos); //attribute marker
                pos = SetString(aUserData, "AJP_REMOTE_PORT", pos); //attribute name
                pos = SetString(aUserData, sourcePort.ToString(), pos); //attribute value
            }

            //add packet terminator
            pos = SetByte(aUserData, 0xFF, pos); //marks the end of user packet

            //assess length of package and type
            int pLength = pos; // true length of user data
            p_UserDataLength = Convert.ToUInt16(pLength);

            //assemble full package now in the final array container of the object
            p_ByteStore = new byte[pos + 4]; // this is the true length as we add magic and length bytes
            int pos2 = 0;
            pos2 = SetByte(p_ByteStore, BonCodeAJP13Markers.BONCODEAJP13_PACKET_START, pos2);
            pos2 = SetByte(p_ByteStore, BonCodeAJP13Markers.BONCODEAJP13_PACKET_START2, pos2);
            pos2 = SetUInt16(p_ByteStore, p_UserDataLength, pos2);
            Array.Copy(aUserData, 0, p_ByteStore, 4, pos); //only copy relevant data values from temporary store
            //determine overall packet length
            p_PacketLength = p_ByteStore.Length;
        }

Same methods

BonCodeAJP13ForwardRequest::WritePacket ( NameValueCollection httpHeaders, String pathInfo, int sourcePort, String vDirs = "" ) : void
BonCodeAJP13ForwardRequest::WritePacket ( byte transferContent ) : void