in Source/RulesEngine/ServiceCallItem.cs [306:469]
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")
{
System.Diagnostics.Debug.WriteLine("CONNECT Frames should not be in the analysis.");
return null;
}
// Fiddler Test Frames can cause LTA to break. This filters out those fames.
if (firstLineSplit[1].StartsWith("http:///", true, null))
{
System.Diagnostics.Debug.WriteLine("Fiddler Test Frames should not be in the analysis.");
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)
{
try
{
reqHeaders.Add(fileLine);
}
catch (Exception)
{
// This will throw if a header value contains invalid characters
// Ignore and continue
}
fileLine = cFile.ReadLine();
}
System.Diagnostics.Debug.WriteLine("Analyzing " + frame.m_uri);
// 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;
}