public static ServiceCallItem FromFiddlerFrame()

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