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; }