Esempio n. 1
0
        private TransactionNode ExtractHttpData(PacketStream stream, HTTPTransactionType type, string nodeName)
        {
            if (nodeName == null)
            {
                nodeName = (type == HTTPTransactionType.REQUEST) ? "Request" : "Response";
            }

            TransactionNode node = new TransactionNode(nodeName);
            List<PacketSlice> slices = new List<PacketSlice>();

            string line = stream.PeekLineUTF8();

            int fieldCount = (type == HTTPTransactionType.REQUEST) ? 3 : 2;

            string[] tokens = line.Split(new char[] { ' ' }, fieldCount);
            if (tokens.Length < fieldCount)
                throw new ProtocolError();

            if (type == HTTPTransactionType.REQUEST)
            {
                stream.ReadBytes(StaticUtils.GetUTF8ByteCount(tokens[0]), slices);
                node.AddField("Verb", tokens[0], "Request verb.", slices);

                stream.ReadByte();

                stream.ReadBytes(StaticUtils.GetUTF8ByteCount(tokens[1]), slices);
                node.AddField("Argument", tokens[1], "Request argument.", slices);

                stream.ReadByte();

                stream.ReadBytes(StaticUtils.GetUTF8ByteCount(tokens[2]), slices);
                node.AddField("Protocol", tokens[2], "Protocol identifier.", slices);

                // Set a description
                node.Description = String.Format("{0} {1}", tokens[0], tokens[1]);
                if (node.Description.Length > MAX_DESCRIPTION_LENGTH)
                {
                    node.Description = node.Description.Substring(0, MAX_DESCRIPTION_LENGTH - ellipsis.Length);
                    node.Description += ellipsis;
                }
            }
            else
            {
                stream.ReadBytes(StaticUtils.GetUTF8ByteCount(tokens[0]), slices);
                node.AddField("Protocol", tokens[0], "Protocol identifier.", slices);

                if (tokens.Length > 1)
                {
                    stream.ReadByte();

                    stream.ReadBytes(StaticUtils.GetUTF8ByteCount(tokens[1]), slices);
                    node.AddField("Result", tokens[1], "Result.", slices);
                }

                // Set a description
                string result = tokens[1];
                if (result.Length > MAX_DESCRIPTION_LENGTH)
                {
                    result = result.Substring(0, MAX_DESCRIPTION_LENGTH - ellipsis.Length) + ellipsis;
                }

                node.Description = result;
            }

            stream.ReadBytes(2);

            TransactionNode headersNode = new TransactionNode("Headers");
            Dictionary<string, string> headerFields = new Dictionary<string, string>();

            do
            {
                line = stream.PeekLineUTF8();
                if (line.Length > 0)
                {
                    tokens = line.Split(new char[] { ':' }, 2);
                    if (tokens.Length < 2)
                        throw new ProtocolError();

                    string key = tokens[0];
                    string value = tokens[1].TrimStart();

                    stream.ReadBytes(StaticUtils.GetUTF8ByteCount(line), slices);
                    headersNode.AddField(key, value, "Header field.", slices);

                    headerFields[key.ToLower()] = value;
                }

                stream.ReadBytes(2);
            } while (line != "");

            if (headersNode.Fields.Count > 0)
            {
                node.AddChild(headersNode);
            }

            int contentLen = -1;

            if (headerFields.ContainsKey("content-length"))
                contentLen = Convert.ToInt32(headerFields["content-length"]);
            else if (headerFields.ContainsKey("contentlength"))
                contentLen = Convert.ToInt32(headerFields["contentlength"]);

            if (contentLen != -1)
            {
                string contentType = null, contentEncoding = null;

                if (headerFields.ContainsKey("content-type"))
                    contentType = headerFields["content-type"];
                else if (headerFields.ContainsKey("contenttype"))
                    contentType = headerFields["contenttype"];

                if (contentType != null)
                {
                    contentType = contentType.ToLower();

                    tokens = contentType.Split(new char[] { ';' });
                    contentType = tokens[0].Trim();
                    if (tokens.Length > 1)
                    {
                        string[] encTokens = tokens[1].Split(new char[] { '=' }, 2);
                        if (encTokens[0].Trim() == "charset" && encTokens.Length > 1)
                        {
                            contentEncoding = encTokens[1];
                        }
                    }
                }

                string str = stream.PeekStringASCII(5);
                if (str == "<?xml")
                {
                    contentType = "text/xml";
                    contentEncoding = "utf-8"; // FIXME
                }

                if (contentLen > 0)
                {
                    AddBodyNode(stream, node, contentType, contentEncoding, contentLen);
                }
            }

            return node;
        }