public void DeserializeCSV(String input) { StreamReader data = new StreamReader(input); String version = data.ReadLine(); if (version == Constants.Version1509 || version == Constants.Version1510) { // Skip over the headers data.ReadLine(); var consoleData = new PerConsoleData(); m_perConsoleData.Add("Console", consoleData); while (!data.EndOfStream) { String row = data.ReadLine(); ServiceCallItem item = ServiceCallItem.FromCSV1509(row); item.m_logVersion = version; if (item != null) { if (!consoleData.m_servicesHistory.ContainsKey(item.m_host)) { consoleData.m_servicesHistory.Add(item.m_host, new LinkedList <ServiceCallItem>()); } consoleData.m_servicesHistory[item.m_host].AddLast(item); } } foreach (var endpoint in consoleData.m_servicesHistory) { consoleData.m_servicesStats.Add(endpoint.Key, new ServiceCallStats(endpoint.Value)); } } }
public void DeserializeJson(String input) { String data = File.ReadAllText(input); data = "{\"Data\":" + data + "}"; XmlDocument doc = JsonConvert.DeserializeXmlNode(data, "Root"); var consoleData = new PerConsoleData(); m_perConsoleData.Add("Console", consoleData); //gather data from every endpoint foreach (XmlNode endpointNode in doc.FirstChild.ChildNodes) { String endpointName = endpointNode.FirstChild.InnerText; for (int j = 1; j < endpointNode.ChildNodes.Count; ++j) { XmlNode itemNode = endpointNode.ChildNodes[j]; ServiceCallItem item = ServiceCallItem.FromJson(itemNode); item.m_host = endpointName; if (!consoleData.m_servicesHistory.ContainsKey(item.m_host)) { consoleData.m_servicesHistory.Add(item.m_host, new LinkedList <ServiceCallItem>()); } consoleData.m_servicesHistory[item.m_host].AddLast(item); } } foreach (var endpoint in consoleData.m_servicesHistory) { consoleData.m_servicesStats.Add(endpoint.Key, new ServiceCallStats(endpoint.Value)); } }
public static bool IsAnalyzedService(ServiceCallItem frame, String customUserAgent) { return((frame.m_reqHeader.Contains("x-xbl-api-build-version:") && !frame.m_reqHeader.Contains("x-xbl-api-build-version: adk")) || (frame.m_reqHeader.Contains("User-Agent: XboxServicesAPI") && !frame.m_reqHeader.Contains("x-xbl-client-name")) || frame.m_reqHeader.Contains("X-XBL-Build-Version") || // XCE CS1.0 event frame.m_reqHeader.Contains("X-AuthXToken") || // UTC upload CS2.1 events (!String.IsNullOrEmpty(customUserAgent) && frame.m_reqHeader.Contains($"User-Agent: {customUserAgent}"))); }
// Helper method to add a violation with a single call public void AddViolation(ViolationLevel level, String description, ServiceCallItem call) { Violation v = new Violation(); v.m_level = level; v.m_endpoint = Endpoint; v.m_summary = description; v.m_violatingCalls.Add(call); Violations.Add(v); }
private void GatherFirstOrderStats(ServiceCallItem item) { // Ignore shoulder taps if (item.m_isShoulderTap) { return; } UInt64 n = m_numCalls; UInt64 avg = m_avgElapsedCallTimeMs; avg = n * avg + item.m_elapsedCallTimeMs; avg /= (n + 1); //update values m_avgElapsedCallTimeMs = avg; //track skipped calls if (item.m_reqTimeUTC < m_lastReqTimeUTC) { ++m_numSkippedCalls; } //m_avgTimeBetweenReqsMs if (m_lastReqTimeUTC != 0 && item.m_reqTimeUTC >= m_lastReqTimeUTC) { UInt64 avgTime = m_avgTimeBetweenReqsMs; avgTime = n * avgTime + (item.m_reqTimeUTC - m_lastReqTimeUTC) / TimeSpan.TicksPerMillisecond; avgTime /= (n + 1); m_avgTimeBetweenReqsMs = avgTime; } //update last call time m_lastReqTimeUTC = item.m_reqTimeUTC; //increment num calls for next time ++m_numCalls; // Update m_maxElapsedCallTimeMs if applicable if (item.m_elapsedCallTimeMs > m_maxElapsedCallTimeMs) { m_maxElapsedCallTimeMs = item.m_elapsedCallTimeMs; } // m_reqBodyHashCountMap if (!m_reqBodyHashCountMap.ContainsKey(item.m_reqBodyHash)) { m_reqBodyHashCountMap.Add(item.m_reqBodyHash, 1); } else { ++m_reqBodyHashCountMap[item.m_reqBodyHash]; } }
public static ServiceCallItem FromCSV1509(String row) { ServiceCallItem item = new ServiceCallItem(); String[] values = Utils.GetCSVValues(row); try { item.m_host = values[(UInt32)CSVValueIndex.Host]; item.m_uri = values[(UInt32)CSVValueIndex.Uri]; item.m_xboxUserId = values[(UInt32)CSVValueIndex.XboxUserId]; item.m_multiplayerCorrelationId = values[(UInt32)CSVValueIndex.MultiplayerCorrelationId]; item.m_reqHeader = values[(UInt32)CSVValueIndex.RequestHeader]; item.m_reqBody = values[(UInt32)CSVValueIndex.RequestBody]; item.m_reqBodyHash = (ulong)item.m_reqBody.GetHashCode(); item.m_rspHeader = values[(UInt32)CSVValueIndex.ResponseHeader]; item.m_rspBody = values[(UInt32)CSVValueIndex.ResponseBody]; UInt32.TryParse(values[(UInt32)CSVValueIndex.HttpStatusCode], out item.m_httpStatusCode); UInt64.TryParse(values[(UInt32)CSVValueIndex.ElapsedCallTime], out item.m_elapsedCallTimeMs); DateTime reqTime; bool valid = DateTime.TryParse(values[(UInt32)CSVValueIndex.RequestTime], null, System.Globalization.DateTimeStyles.RoundtripKind, out reqTime); if (valid) { item.m_reqTimeUTC = (UInt64)reqTime.ToFileTimeUtc(); } bool.TryParse(values[(UInt32)CSVValueIndex.IsGet], out item.m_isGet); UInt32.TryParse(values[(UInt32)CSVValueIndex.Id], out item.m_id); bool.TryParse(values[(UInt32)CSVValueIndex.IsShoulderTap], out item.m_isShoulderTap); UInt64.TryParse(values[(UInt32)CSVValueIndex.ChangeNumber], out item.m_changeNumber); item.m_sessionReferenceUriPath = values[(UInt32)CSVValueIndex.SessionReferenceUriPath]; bool.TryParse(values[(UInt32)CSVValueIndex.IsInGameEvent], out item.m_isInGameEvent); item.m_eventName = values[(UInt32)CSVValueIndex.EventName]; item.m_playerSessionId = values[(UInt32)CSVValueIndex.PlayerSessionId]; UInt16.TryParse(values[(UInt32)CSVValueIndex.EventVersion], out item.m_version); item.m_dimensions = values[(UInt32)CSVValueIndex.Dimensions]; item.m_measurements = values[(UInt32)CSVValueIndex.Measurements]; item.m_breadCrumb = values[(UInt32)CSVValueIndex.BreadCrumb]; } catch (Exception) { Console.WriteLine("Error Parsing a CSV Item."); return(null); } return(item); }
private void GatherSecondOrderStats(ServiceCallItem item) { // Ignore shoulder taps if (item.m_isShoulderTap) { return; } // // Calculate variance // // Var[n+1] = ( n * Var[n] + ( x[n+1] - Avg ) ^ 2 ) / ( n + 1) // UInt64 avg = m_avgElapsedCallTimeMs; UInt64 n = m_numCalls; // m_varElapsedCallTimeMs UInt64 var = m_varElapsedCallTimeMs; UInt64 dev = item.m_elapsedCallTimeMs - avg; var = n * var + dev * dev; var /= (n + 1); //m_varTimeBetweenReqsMs if (m_lastReqTimeUTC != 0 && item.m_reqTimeUTC >= m_lastReqTimeUTC) { UInt64 localVar = m_varTimeBetweenReqsMs; UInt64 localDev = (item.m_reqTimeUTC - m_lastReqTimeUTC) / TimeSpan.TicksPerMillisecond - avg; localVar = n * localVar + localDev * localDev; localVar /= (n + 1); //update values m_varTimeBetweenReqsMs = localVar; } m_lastReqTimeUTC = item.m_reqTimeUTC; // increment m_numCalls for next time ++n; //update values m_numCalls = n; m_varElapsedCallTimeMs = var; }
public ServiceCallItem Copy() { var copy = new ServiceCallItem(); copy.m_logVersion = m_logVersion; copy.m_host = m_host; copy.m_uri = m_uri; copy.m_xboxUserId = m_xboxUserId; copy.m_multiplayerCorrelationId = m_multiplayerCorrelationId; copy.m_reqHeader = m_reqHeader; copy.m_reqBody = m_reqBody; copy.m_rspHeader = m_rspHeader; copy.m_rspBody = m_rspBody; copy.m_rspFullString = m_rspFullString; copy.m_branch = m_branch; copy.m_sessionReferenceUriPath = m_sessionReferenceUriPath; copy.m_eventName = m_eventName; copy.m_playerSessionId = m_playerSessionId; copy.m_dimensions = m_dimensions; copy.m_measurements = m_measurements; copy.m_breadCrumb = m_breadCrumb; copy.m_xsapiMethods = m_xsapiMethods; copy.m_callDataFromJSON = m_callDataFromJSON; copy.m_consoleIP = m_consoleIP; copy.m_version = m_version; copy.m_httpStatusCode = m_httpStatusCode; copy.m_reqBodyHash = m_reqBodyHash; copy.m_elapsedCallTimeMs = m_elapsedCallTimeMs; copy.m_reqTimeUTC = m_reqTimeUTC; copy.m_startTimeUTC = m_startTimeUTC; copy.m_changeNumber = m_changeNumber; copy.m_isGet = m_isGet; copy.m_method = m_method; copy.m_isShoulderTap = m_isShoulderTap; copy.m_isInGameEvent = m_isInGameEvent; return(copy); }
public static ServiceCallItem FromFiddlerFrame(UInt32 frameId, ZipArchiveEntry cFileStream, ZipArchiveEntry mFileStream, ZipArchiveEntry sFileStream, Func <WebHeaderCollection, bool> filterCallback) { ServiceCallItem frame = new ServiceCallItem(); frame.m_id = frameId; // Read the client part of the frame (###_c.txt) using (var cFileMemory = Utils.DecompressToMemory(cFileStream)) { using (var cFile = new BinaryReader(cFileMemory)) { var fileLine = cFile.ReadLine(); var firstLineSplit = fileLine.Split(' '); // CONNECT Frames should not be in the analysis. if (firstLineSplit[0] == "CONNECT") { return(null); } // Fiddler Test Frames can cause LTA to break. This filters out those fames. if (firstLineSplit[1].StartsWith("http:///", true, null)) { return(null); } frame.m_isGet = firstLineSplit[0].Equals("GET"); frame.m_method = firstLineSplit[0]; // Extract the XUID (if any) from the first line of the client side of the frame // POST https://userpresence.xboxlive.com/users/xuid(2669321029139235)/devices/current HTTP/1.1 frame.m_xboxUserId = Utils.GetXboxUserID(firstLineSplit[1]); // Grab just the url from the line frame.m_uri = firstLineSplit[1]; // Read the Request Headers fileLine = cFile.ReadLine(); var reqHeaders = new WebHeaderCollection(); while (String.IsNullOrWhiteSpace(fileLine) == false) { reqHeaders.Add(fileLine); fileLine = cFile.ReadLine(); } // Filter calls with headers if (filterCallback != null && !filterCallback(reqHeaders)) { return(null); } frame.m_host = reqHeaders["Host"]; // Read the Request Body string contentEncoding = reqHeaders["Content-Encoding"]; if (!string.IsNullOrWhiteSpace(contentEncoding) && contentEncoding.Equals("deflate", StringComparison.OrdinalIgnoreCase)) { using (var memory = Utils.InflateData(cFile.ReadToEnd())) { using (var data = new BinaryReader(memory)) { fileLine = Encoding.ASCII.GetString(data.ReadToEnd()); } } } else { fileLine = Encoding.ASCII.GetString(cFile.ReadToEnd()); } frame.m_reqHeader = reqHeaders.ToString(); frame.m_reqBody = fileLine; frame.m_reqBodyHash = (UInt64)frame.m_reqBody.GetHashCode(); } } // Read the frame metadata (###_m.xml) using (var mFile = new StreamReader(mFileStream.Open())) { String rawData = mFile.ReadToEnd(); var xmldata = System.Xml.Linq.XDocument.Parse(rawData); var sessionTimers = xmldata.Element("Session").Element("SessionTimers"); var reqTime = DateTime.Parse((String)sessionTimers.Attribute("ClientBeginRequest")).ToUniversalTime(); frame.m_reqTimeUTC = (UInt64)reqTime.ToFileTimeUtc(); var endTime = DateTime.Parse((String)sessionTimers.Attribute("ClientDoneResponse")).ToUniversalTime(); frame.m_elapsedCallTimeMs = (UInt64)(endTime - reqTime).TotalMilliseconds; var sessionFlags = xmldata.Element("Session").Element("SessionFlags"); foreach (var flag in sessionFlags.Descendants()) { if ((String)flag.Attribute("N") == "x-clientip") { frame.m_consoleIP = (String)flag.Attribute("V"); frame.m_consoleIP = frame.m_consoleIP.Substring(frame.m_consoleIP.LastIndexOf(':') + 1); break; } } } //Read the server part of the frame(###_s.txt) using (var sFileMemory = Utils.DecompressToMemory(sFileStream)) { using (var sFile = new BinaryReader(sFileMemory)) { var fileLine = sFile.ReadLine(); if (String.IsNullOrEmpty(fileLine) == false) { var statusCodeLine = fileLine.Split(' '); frame.m_httpStatusCode = UInt32.Parse(statusCodeLine[1]); } // Read the Response Headers var headers = new WebHeaderCollection(); fileLine = sFile.ReadLine(); while (!String.IsNullOrWhiteSpace(fileLine)) { headers.Add(fileLine); fileLine = sFile.ReadLine(); } // Read the Response Body string contentEncoding = headers["Content-Encoding"]; if (!string.IsNullOrWhiteSpace(contentEncoding) && contentEncoding.Equals("deflate", StringComparison.OrdinalIgnoreCase)) { using (var memory = Utils.InflateData(sFile.ReadToEnd())) { using (var data = new BinaryReader(memory)) { fileLine = Encoding.ASCII.GetString(data.ReadToEnd()); } } } else { fileLine = Encoding.ASCII.GetString(sFile.ReadToEnd()); } frame.m_rspHeader = headers.ToString(); // Read the Response Body frame.m_rspBody = fileLine; } } return(frame); }
public static ServiceCallItem FromJson(XmlNode serviceCallNode) { ServiceCallItem item = new ServiceCallItem(); foreach (XmlNode propertyNode in serviceCallNode.ChildNodes) { try { //check for each service call property if (propertyNode.Name == "Uri") { item.m_uri = propertyNode.InnerText; } else if (propertyNode.Name == "Host") { item.m_host = propertyNode.InnerText; } else if (propertyNode.Name == "XboxUserId") { item.m_xboxUserId = propertyNode.InnerText; } else if (propertyNode.Name == "MultiplayerCorrelationId") { item.m_multiplayerCorrelationId = propertyNode.InnerText; } else if (propertyNode.Name == "RequestHeaders") { item.m_reqHeader = propertyNode.InnerText; } else if (propertyNode.Name == "RequestBody") { item.m_reqBody = propertyNode.InnerText; item.m_reqBodyHash = (ulong)item.m_reqBody.GetHashCode(); } else if (propertyNode.Name == "ResponseHeaders") { item.m_rspHeader = propertyNode.InnerText; } else if (propertyNode.Name == "ResponseBody") { item.m_rspBody = propertyNode.InnerText; } else if (propertyNode.Name == "FullResponse") { item.m_rspFullString = propertyNode.InnerText; } else if (propertyNode.Name == "HttpStatusCode") { UInt32.TryParse(propertyNode.InnerText, out item.m_httpStatusCode); } else if (propertyNode.Name == "RequestBodyHashCode") { UInt64.TryParse(propertyNode.InnerText, out item.m_reqBodyHash); } else if (propertyNode.Name == "ElapsedCallTimeMs") { UInt64.TryParse(propertyNode.InnerText, out item.m_elapsedCallTimeMs); } else if (propertyNode.Name == "ReqTimeUTC") { double reqTimeUTC; bool valid = double.TryParse(propertyNode.InnerText, out reqTimeUTC); if (valid) { item.m_reqTimeUTC = (UInt64)BitConverter.DoubleToInt64Bits(reqTimeUTC); } } else if (propertyNode.Name == "StartTimeUTC") { double startTimeUTC; bool valid = double.TryParse(propertyNode.InnerText, out startTimeUTC); if (valid) { item.m_startTimeUTC = (UInt64)BitConverter.DoubleToInt64Bits(startTimeUTC); } } else if (propertyNode.Name == "IsGet") { bool.TryParse(propertyNode.InnerText, out item.m_isGet); } else if (propertyNode.Name == "Id") { UInt32.TryParse(propertyNode.InnerText, out item.m_id); } else if (propertyNode.Name == "IsShoulderTap") { bool.TryParse(propertyNode.InnerText, out item.m_isShoulderTap); } else if (propertyNode.Name == "ChangeNumber") { UInt64.TryParse(propertyNode.InnerText, out item.m_changeNumber); } else if (propertyNode.Name == "Branch") { item.m_branch = propertyNode.InnerText; } else if (propertyNode.Name == "SessionReferenceUriPath") { item.m_sessionReferenceUriPath = propertyNode.InnerText; } else if (propertyNode.Name == "IsInGameEvent") { bool.TryParse(propertyNode.InnerText, out item.m_isInGameEvent); } else if (propertyNode.Name == "EventName") { item.m_eventName = propertyNode.InnerText; } else if (propertyNode.Name == "EventPlayerSessionId") { item.m_playerSessionId = propertyNode.InnerText; } else if (propertyNode.Name == "EventVersion") { UInt16.TryParse(propertyNode.InnerText, out item.m_version); } else if (propertyNode.Name == "EventDimensionsData") { item.m_dimensions = propertyNode.InnerText; } else if (propertyNode.Name == "EventMeasurementsData") { item.m_measurements = propertyNode.InnerText; } else if (propertyNode.Name == "BreadCrumb") { item.m_breadCrumb = propertyNode.InnerText; } } catch (ArgumentException) { } } return(item); }
private void ConvertCS1ToEvent(Dictionary <string, LinkedList <ServiceCallItem> > servicesHistory) { var events = servicesHistory["data-vef.xboxlive.com"]; servicesHistory.Remove("data-vef.xboxlive.com"); LinkedList <ServiceCallItem> inGameEvents = null; if (servicesHistory.ContainsKey("inGameEvents")) { inGameEvents = servicesHistory["inGameEvents"]; } else { inGameEvents = new LinkedList <ServiceCallItem>(); servicesHistory.Add("inGameEvents", inGameEvents); } // Event Name starts with a string in the form of {Publisher}_{TitleId} Regex eventNameMatch = new Regex("[a-zA-z]{4}_[a-zA-Z0-9]{8}"); foreach (var eventCall in events) { var requestBody = eventCall.m_reqBody; var eventArray = requestBody.Split(Environment.NewLine.ToCharArray()); foreach (var eventLine in eventArray) { var fields = eventLine.Split('|'); if (fields.Length < 12) { // This event is not valid as it is missing fields continue; } // The name field is in the form of {Publisher}_{TitleId}.{EventName} var eventNameParts = fields[1].Split('.'); if (eventNameParts.Length > 1 && eventNameMatch.IsMatch(eventNameParts[0])) { ServiceCallItem splitEvent = eventCall.Copy(); splitEvent.m_host = "inGameEvents"; splitEvent.m_eventName = eventNameParts[1]; splitEvent.m_reqTimeUTC = (UInt64)DateTime.Parse(fields[2]).ToFileTimeUtc(); splitEvent.m_reqBody = String.Empty; splitEvent.m_dimensions = CS1PartBC(fields); splitEvent.m_isInGameEvent = true; if (splitEvent.m_eventName.Contains("MultiplayerRoundStart") || splitEvent.m_eventName.Contains("MultiplayerRoundEnd")) { splitEvent.m_playerSessionId = fields[15]; splitEvent.m_multiplayerCorrelationId = fields[16]; } inGameEvents.AddLast(splitEvent); } } } }
public void DeserializeFiddlerTrace(String filePath, String customAgent) { // Open the SAZ var archive = System.IO.Compression.ZipFile.Open(filePath, ZipArchiveMode.Read); // Group the archive entries by frame number var result = from e in archive.Entries where e.Name.Contains("_c.txt") || e.Name.Contains("_s.txt") || e.Name.Contains("_m.xml") group e by Utils.GetFrameNumber(e.Name) into g select new { Frame = g.Key, Data = g }; m_dataTelemetry.m_totalCalls = result.Count(); List <ServiceCallItem> frameData = new List <ServiceCallItem>(); int frameNumber = 1; // Process data per frame foreach (var group in result) { // Grab the individual files ZipArchiveEntry cFileArchive = group.Data.ElementAt(0); ZipArchiveEntry mFileArchive = group.Data.ElementAt(1); ZipArchiveEntry sFileArchive = group.Data.ElementAt(2); ServiceCallItem frame = null; System.Diagnostics.Debug.WriteLine("Analyzing Frame# " + frameNumber); frameNumber++; frame = ServiceCallItem.FromFiddlerFrame((UInt32)group.Frame, cFileArchive, mFileArchive, sFileArchive, o => m_allEndpoints || Utils.IsAnalyzedService(o, customAgent)); // If this is not an Xbox Service Endpoint that we are checking, then move along. if (frame == null) { System.Diagnostics.Debug.WriteLine("Skipping\r\n"); continue; } else { System.Diagnostics.Debug.WriteLine("Processing Call\r\n"); } frameData.Add(frame); m_dataTelemetry.m_callsProcessed++; } var consoleGroups = from f in frameData group f by f.m_consoleIP; foreach (var consoleFrames in consoleGroups.Where(g => g.Key != String.Empty)) { var consoleData = new PerConsoleData(); var xboxServiceFrames = consoleFrames.GroupBy(f => f.m_host) .Select(group => new { Host = group.Key, History = group.AsEnumerable() }); consoleData.m_servicesHistory = xboxServiceFrames.ToDictionary(g => g.Host, g => new LinkedList <ServiceCallItem>(g.History.OrderBy(call => call.m_reqTimeUTC))); // Xbox telemetry endpoint if (consoleData.m_servicesHistory.ContainsKey("data-vef.xboxlive.com")) { ConvertCS1ToEvent(consoleData.m_servicesHistory); } // Windows Telemetry endpoint if (consoleData.m_servicesHistory.Any(k => k.Key.Contains(".data.microsoft.com"))) { ConvertCS2ToEvent(consoleData.m_servicesHistory); } // clear empty items consoleData.m_servicesHistory = consoleData.m_servicesHistory.Where(o => o.Value.Count > 0).ToDictionary(x => x.Key, x => x.Value); foreach (var endpoint in consoleData.m_servicesHistory) { consoleData.m_servicesStats.Add(endpoint.Key, new ServiceCallStats(endpoint.Value)); } m_perConsoleData.Add(consoleFrames.Key, consoleData); } }
public static ServiceCallItem FromFiddlerFrame(UInt32 frameId, ZipArchiveEntry cFileStream, ZipArchiveEntry mFileStream, ZipArchiveEntry sFileStream) { ServiceCallItem frame = new ServiceCallItem(); frame.m_id = frameId; // Read the client part of the frame (###_c.txt) using (var cFileMemory = Utils.DecompressToMemory(cFileStream)) { using (var cFile = new BinaryReader(cFileMemory)) { var fileLine = cFile.ReadLine(); var firstLineSplit = fileLine.Split(' '); // CONNECT Frames should not be in the analysis. if (firstLineSplit[0] == "CONNECT") { return(null); } frame.m_isGet = firstLineSplit[0].Equals("GET"); // Extract the XUID (if any) from the first line of the client side of the frame // POST https://userpresence.xboxlive.com/users/xuid(2669321029139235)/devices/current HTTP/1.1 frame.m_xboxUserId = Utils.GetXboxUserID(firstLineSplit[1]); // Grab just the url from the line frame.m_uri = firstLineSplit[1]; // Read the Request Headers fileLine = cFile.ReadLine(); frame.m_reqHeader = String.Empty; while (String.IsNullOrEmpty(fileLine) == false) { frame.m_reqHeader += (fileLine + "\r\n"); fileLine = cFile.ReadLine(); } var index = frame.m_reqHeader.IndexOf("Host:"); index += 6; var endIndex = frame.m_reqHeader.IndexOf("\r\n", index); frame.m_host = frame.m_reqHeader.Substring(index, endIndex - index); // Read the Request Body if (frame.m_reqHeader.Contains("Content-Encoding: deflate")) { using (var memory = Utils.InflateData(cFile.ReadToEnd())) { using (var data = new BinaryReader(memory)) { fileLine = Encoding.ASCII.GetString(data.ReadToEnd()); } } } else { fileLine = Encoding.ASCII.GetString(cFile.ReadToEnd()); } frame.m_reqBody = fileLine; frame.m_reqBodyHash = (UInt64)frame.m_reqBody.GetHashCode(); } } // Read the frame metadata (###_m.xml) using (var mFile = new StreamReader(mFileStream.Open())) { String rawData = mFile.ReadToEnd(); var xmldata = System.Xml.Linq.XDocument.Parse(rawData); var sessionTimers = xmldata.Element("Session").Element("SessionTimers"); var reqTime = DateTime.Parse((String)sessionTimers.Attribute("ClientBeginRequest")).ToUniversalTime(); frame.m_reqTimeUTC = (UInt64)reqTime.ToFileTimeUtc(); var endTime = DateTime.Parse((String)sessionTimers.Attribute("ClientDoneResponse")).ToUniversalTime(); frame.m_elapsedCallTimeMs = (UInt64)(endTime - reqTime).TotalMilliseconds; var sessionFlags = xmldata.Element("Session").Element("SessionFlags"); foreach (var flag in sessionFlags.Descendants()) { if ((String)flag.Attribute("N") == "x-clientip") { frame.m_consoleIP = (String)flag.Attribute("V"); frame.m_consoleIP = frame.m_consoleIP.Substring(frame.m_consoleIP.LastIndexOf(':') + 1); break; } } } //Read the server part of the frame(###_s.txt) using (var sFileMemory = Utils.DecompressToMemory(sFileStream)) { using (var sFile = new BinaryReader(sFileMemory)) { var fileLine = sFile.ReadLine(); if (String.IsNullOrEmpty(fileLine) == false) { var statusCodeLine = fileLine.Split(' '); frame.m_httpStatusCode = UInt32.Parse(statusCodeLine[1]); } // Read the Response Headers fileLine = sFile.ReadLine(); frame.m_rspHeader = String.Empty; while (String.IsNullOrEmpty(fileLine) == false) { frame.m_rspHeader += (fileLine + "\r\n"); fileLine = sFile.ReadLine(); } // Read the Response Body if (frame.m_rspHeader.Contains("Content-Encoding: deflate")) { using (var memory = Utils.InflateData(sFile.ReadToEnd())) { using (var data = new BinaryReader(memory)) { fileLine = Encoding.ASCII.GetString(data.ReadToEnd()); } } } else { fileLine = Encoding.ASCII.GetString(sFile.ReadToEnd()); } // Read the Response Body frame.m_rspBody = fileLine; } } return(frame); }