Пример #1
0
 /// <summary>
 /// Creates a new instance of this class
 /// </summary>
 protected HTTPMessage()
 {
     httpHeaders = new HTTPHeaderCollection();
     bPayload    = new byte[0];
 }
Пример #2
0
        /// <summary>
        /// Creates a new instance of this class by reading from the given stream.
        /// </summary>
        /// <param name="sStream">The stream to read from</param>
        /// <param name="iLength">An integer which is set to the length of this HTTP message in bytes</param>
        protected HTTPMessage(System.IO.Stream sStream, out int iLength)
        {
            MemoryStream msHeader = new MemoryStream();

            byte[] bMessage = null;
            HTTPHeaderCollection htHeaders = new HTTPHeaderCollection();

            int iContentLength = 0;
            int iHeaderLength  = 0;

            // Get the header
            if (!CompressionHelper.CopyUntilFound(sStream, msHeader, new byte[] { (byte)'\r', (byte)'\n', (byte)'\r', (byte)'\n' }))
            {
                throw new HTTPParserStreamEndedException("The end of the stream was reached while trying to parse the message.");
            }

            iHeaderLength = (int)msHeader.Length;

            //Parse the header and get the content length

            byte[] bHeader    = msHeader.ToArray();
            bool   bIsChunked = false;

            string strHeaderFields = Encoding.ASCII.GetString(bHeader);

            string[] arstrHeaders = strHeaderFields.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);

            for (int iC1 = 1; iC1 < arstrHeaders.Length; iC1++)
            {
                string[] arstrHeader = arstrHeaders[iC1].Split(new string[] { ": " }, StringSplitOptions.RemoveEmptyEntries);

                if (arstrHeader.Length == 0)
                {
                    throw new HTTPParserException("Invalid HTTP header supplied: " + arstrHeaders[iC1]);
                }
                if (arstrHeader[0] == "Content-Length" && arstrHeader.Length >= 2)
                {
                    iContentLength = Int32.Parse(arstrHeader[1]);
                }
                if (arstrHeader[0] == "Transfer-Encoding" && arstrHeader.Length >= 2)
                {
                    bIsChunked = arstrHeader[1].ToLower() == "chunked";
                }
            }

            if (bIsChunked)
            {
                //We have chunked content encoding (We have to wait)
                if (iContentLength != 0)
                {
                    throw new HTTPParserException("The Transfer-Encoding is set to chunked, but " +
                                                  "also the Content-Length header is set to " + iContentLength + ". This should not happen.");
                }

                MemoryStream msChunkedContent = new MemoryStream();

                if (!CompressionHelper.CopyUntilFound(sStream, msChunkedContent, new byte[] { (byte)'\r', (byte)'\n', (byte)'0', (byte)'\r', (byte)'\n', (byte)'\r', (byte)'\n' }))
                {
                    throw new HTTPParserStreamEndedException("The end of the stream was reached while trying to parse the message.");
                }

                iContentLength = (int)msChunkedContent.Length;

                bMessage          = new byte[iHeaderLength + iContentLength];
                msHeader.Position = 0;
                msHeader.Read(bMessage, 0, iHeaderLength);
                msChunkedContent.Position = 0;
                msChunkedContent.Read(bMessage, iHeaderLength, iContentLength);
            }
            else
            {
                //We have normal content encoding
                //Copy all data into an array
                bMessage          = new byte[iHeaderLength + iContentLength];
                msHeader.Position = 0;
                msHeader.Read(bMessage, 0, iHeaderLength);
                if (sStream.Read(bMessage, iHeaderLength, iContentLength) != iContentLength)
                {
                    throw new HTTPParserStreamEndedException("The end of the stream was reached while trying to parse the message.");
                }
            }

            //Initialize

            iLength = Initialize(bMessage);

            //Cleanup

            msHeader.Dispose();
        }
Пример #3
0
        /// <summary>
        /// Initializes this instance with the given data.
        /// </summary>
        /// <param name="bData">The data to create this HTTP message from</param>
        /// <returns>The length of the data which belongs to this HTTP message</returns>
        private int Initialize(byte[] bData)
        {
            int iLength;

            byte[] bHeader  = null;
            byte[] bContent = null;
            httpHeaders = new HTTPHeaderCollection();
            bPayload    = new byte[0];

            for (int iC1 = 0; iC1 < bData.Length - 3; iC1++)
            {
                if (bData[iC1] == '\r' && bData[iC1 + 1] == '\n' && bData[iC1 + 2] == '\r' && bData[iC1 + 3] == '\n')
                {
                    bHeader = new byte[iC1 + 4];
                    for (int iC2 = 0; iC2 <= iC1 + 3; iC2++)
                    {
                        bHeader[iC2] = bData[iC2];
                    }
                    break;

                    //bContent = new byte[bData.Length - iC1 - 4];
                    //for (int iC2 = 0; iC2 < bData.Length - iC1 - 4; iC2++)
                    //{
                    //    bHeader[iC2] = bData[iC2 + iC1 + 4];
                    //}
                }
            }

            if (bHeader == null)
            {
                bHeader = bData;
            }

            string strHeaderFields = Encoding.ASCII.GetString(bHeader);

            string[] arstrHeaders = strHeaderFields.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);

            ParseStatusLine(arstrHeaders[0]);

            for (int iC1 = 1; iC1 < arstrHeaders.Length; iC1++)
            {
                int iFirstIndexOf = arstrHeaders[iC1].IndexOf(": ");

                if (iFirstIndexOf == -1)
                {
                    throw new HTTPParserException("Invalid HTTP header supplied: " + arstrHeaders[iC1]);
                }

                string strHeader = arstrHeaders[iC1].Substring(0, iFirstIndexOf);
                string strValue  = arstrHeaders[iC1].Substring(iFirstIndexOf + 2);

                httpHeaders.Add(new HTTPHeader(strHeader, strValue));
            }

            if (httpHeaders.Contains("Content-Length"))
            {
                int iContentLength = Int32.Parse(httpHeaders["Content-Length"][0].Value);

                if (iContentLength > bData.Length - bHeader.Length)
                {
                    throw new HTTPParserException("Payload length given in HTTP-header is longer then length of HTTP-conversation.");
                }

                bContent = new byte[iContentLength];

                for (int iC1 = 0; iC1 < iContentLength; iC1++)
                {
                    bContent[iC1] = bData[iC1 + bHeader.Length];
                }
            }
            else
            {
                if (httpHeaders.Contains("Transfer-Encoding") && httpHeaders["Transfer-Encoding"][0].Value.ToLower() == "chunked")
                {
                    //We've got chunked encoding
                    for (int iC1 = bHeader.Length; iC1 < bData.Length - 4; iC1++)
                    {
                        if (bData[iC1] == '\r' && bData[iC1 + 1] == '\n' && bData[iC1 + 2] == '0' && bData[iC1 + 3] == '\r' && bData[iC1 + 4] == '\n')
                        {
                            bContent = new byte[iC1 + 5 - bHeader.Length];
                            for (int iC2 = bHeader.Length; iC2 <= iC1 + 4; iC2++)
                            {
                                bContent[iC2 - bHeader.Length] = bData[iC2];
                            }
                            break;
                        }
                    }
                }
                else
                {
                    bContent = new byte[0];
                }
            }

            this.bPayload = bContent;

            iLength = bHeader.Length + bContent.Length;
            return(iLength);
        }