Proxy 当插入脚本时,Fiddler(FiddlerCore)响应工作缓慢

Proxy 当插入脚本时,Fiddler(FiddlerCore)响应工作缓慢,proxy,html-agility-pack,fiddler,fiddlercore,Proxy,Html Agility Pack,Fiddler,Fiddlercore,我尝试用fiddlercore创建代理服务器,当我使用event Before时,响应代码工作得非常慢。我试图做的是在当前浏览页面的顶部插入脚本 为什么下面的代码这么慢?它需要插入某种过滤器还是什么 Fiddler.FiddlerApplication.BeforeResponse += delegate(Fiddler.Session oS) { Console.WriteLine("{0}:HTTP {1} for {2}", oS.id, oS.re

我尝试用fiddlercore创建代理服务器,当我使用event Before时,响应代码工作得非常慢。我试图做的是在当前浏览页面的顶部插入脚本

为什么下面的代码这么慢?它需要插入某种过滤器还是什么

Fiddler.FiddlerApplication.BeforeResponse += delegate(Fiddler.Session oS)
        {
            Console.WriteLine("{0}:HTTP {1} for {2}", oS.id, oS.responseCode, oS.fullUrl);

            oS.utilDecodeResponse(); 
            string HTML = oS.GetResponseBodyAsString();

            HtmlDocument htmlDoc = new HtmlDocument();
            try
            {
                htmlDoc.LoadHtml(HTML);
                HtmlNode node = htmlDoc.CreateElement("script");
                node.SetAttributeValue("src", "https://somesite.com");
                HtmlNode Head = htmlDoc.DocumentNode.SelectSingleNode("//Head");

                if (Head != null)
                {
                    Head.AppendChild(node);
                    oS.utilSetResponseBody(htmlDoc.DocumentNode.OuterHtml);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message.ToString());
            }

            Console.WriteLine("URL: {0}", oS.url);
        };
以下是完整代码:

    /*
    * This demo program shows how to use the FiddlerCore library.
    *
    * Before compiling, ensure that the project's REFERENCES list points to the 
    * copy of FiddlerCore.dll included in this package.
    *
    * By default, the project is compiled without support for the SAZ File format.
    * If you want to add SAZ support, define the token SAZ_SUPPORT in the list of
    * Conditional Compilation symbols on the project's BUILD tab. You will also
    * need to add Ionic.Zip.Reduced.dll to your project's references.
    */

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Reflection;
    using System.Threading;
    using Fiddler;
    using System.Diagnostics;
    using HtmlAgilityPack;
    using System.Security.Cryptography.X509Certificates;
    using System.Text.RegularExpressions;

    namespace Demo
    {
        class Program
        {
            static Proxy oSecureEndpoint;
            static string sSecureEndpointHostname = "localhost";
            static int iSecureEndpointPort = 7777;

            public static void WriteCommandResponse(string s)
            {
                ConsoleColor oldColor = Console.ForegroundColor;
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine(s);
                Console.ForegroundColor = oldColor;
            }

            public static void DoQuit()
            {
                WriteCommandResponse("Shutting down...");
                //  UninstallCertificate();
                //  Console.Write("\ncert: {0}", CertMaker.rootCertExists()); Console.ReadLine();
                //  if (null != oSecureEndpoint) oSecureEndpoint.Dispose();
                Fiddler.FiddlerApplication.Shutdown();

                Thread.Sleep(500);
            }
            private static string Ellipsize(string s, int iLen)
            {
                if (s.Length <= iLen) return s;
                return s.Substring(0, iLen - 3) + "...";
            }

    #if SAZ_SUPPORT
            private static void ReadSessions(List<Fiddler.Session> oAllSessions)
            {
                Session[] oLoaded = Utilities.ReadSessionArchive(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) 
                                                               + Path.DirectorySeparatorChar + "ToLoad.saz", false);

                if ((oLoaded != null) && (oLoaded.Length > 0))
                {
                    oAllSessions.AddRange(oLoaded);
                    WriteCommandResponse("Loaded: " + oLoaded.Length + " sessions.");
                }
            }

            private static void SaveSessionsToDesktop(List<Fiddler.Session> oAllSessions)
            {
                bool bSuccess = false;
                string sFilename = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)
                                 + Path.DirectorySeparatorChar + DateTime.Now.ToString("hh-mm-ss") + ".saz";
                try
                {
                    try
                    {
                        Monitor.Enter(oAllSessions);

                        string sPassword = null;
                        Console.WriteLine("Password Protect this Archive (Y/N)?");
                        ConsoleKeyInfo oCKI = Console.ReadKey();
                        if ((oCKI.KeyChar == 'y') || (oCKI.KeyChar == 'Y'))
                        {
                            Console.WriteLine("\nEnter the password:");
                            sPassword = Console.ReadLine();
                            Console.WriteLine(String.Format("\nEncrypting with Password: '{0}'", sPassword));
                        }
                        Console.WriteLine();

                        bSuccess = Utilities.WriteSessionArchive(sFilename, oAllSessions.ToArray(), sPassword, false);
                    }
                    finally
                    {
                        Monitor.Exit(oAllSessions);
                    }

                    WriteCommandResponse( bSuccess ? ("Wrote: " + sFilename) : ("Failed to save: " + sFilename) );
                }
                catch (Exception eX)
                {
                    Console.WriteLine("Save failed: " + eX.Message);
                }
            }
    #endif
            public static bool InstallCertificate()
            {
                if (!CertMaker.rootCertExists())
                {
                    if (!CertMaker.createRootCert())
                        return false;

                    if (!CertMaker.trustRootCert())
                        return false;
                }

                return true;
            }

            public static bool UninstallCertificate()
            {
                if (CertMaker.rootCertExists())
                {
                    if (!CertMaker.removeFiddlerGeneratedCerts(true))
                        return false;
                }
                return true;
            }

            private static void WriteSessionList(List<Fiddler.Session> oAllSessions)
            {
                ConsoleColor oldColor = Console.ForegroundColor;
                Console.ForegroundColor = ConsoleColor.White;
                Console.WriteLine("Session list contains...");
                try
                {
                    Monitor.Enter(oAllSessions);
                    foreach (Session oS in oAllSessions)
                    {
                        Console.Write(String.Format("{0} {1} {2}\n{3} {4}\n\n", oS.id, oS.oRequest.headers.HTTPMethod, Ellipsize(oS.fullUrl, 60), oS.responseCode, oS.oResponse.MIMEType));
                    }
                }
                finally
                {
                    Monitor.Exit(oAllSessions);
                }
                Console.WriteLine();
                Console.ForegroundColor = oldColor;
            }

            private static bool setMachineTrust(X509Certificate2 oRootCert)
            {
                try
                {
                    // X509Certificate2 cert = X509Certificate2("C:\Path\my.pfx", "password");

                    X509Store certStore = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
                    certStore.Open(OpenFlags.ReadWrite);

                    try
                    {
                        certStore.Add(oRootCert);
                    }
                    finally
                    {
                        certStore.Close();
                    }
                    return true;
                }
                catch (Exception eX)
                {
                    return false;
                }
            }

            static void Main(string[] args)
            {
                List<Fiddler.Session> oAllSessions = new List<Fiddler.Session>();

                // <-- Personalize for your Application, 64 chars or fewer
                Fiddler.FiddlerApplication.SetAppDisplayName("FiddlerCoreDemoApp");
                #region AttachEventListeners

                // Simply echo notifications to the console.  Because Fiddler.CONFIG.QuietMode=true 
                // by default, we must handle notifying the user ourselves.
                Fiddler.FiddlerApplication.OnNotification += delegate(object sender, NotificationEventArgs oNEA) { Console.WriteLine("** NotifyUser: " + oNEA.NotifyString); };
                Fiddler.FiddlerApplication.Log.OnLogString += delegate(object sender, LogEventArgs oLEA) { Console.WriteLine("** LogString: " + oLEA.LogString); };

                Fiddler.FiddlerApplication.BeforeRequest += delegate(Fiddler.Session oS)
                {
                    oS.bBufferResponse = true;

                    //Monitor.Enter(oAllSessions);
                    //oAllSessions.Add(oS);
                    //Monitor.Exit(oAllSessions);
                    //oS["X-AutoAuth"] = "(default)";

                    //if ((oS.oRequest.pipeClient.LocalPort == iSecureEndpointPort) && (oS.hostname == sSecureEndpointHostname))
                    {
                        // oSession.oRequest["NewHeaderName"] = "New header value";
                        // oS.oResponse.headers.Add("headerName", "\nThis is new header!!!\n").ToString()

                        //oS.utilCreateResponseAndBypassServer();
                        //oS.oResponse.headers.Add("headerName", "This is new header!!!\n");

                        //oS.oResponse.headers.SetStatus(200, "Ok");
                        //oS.oResponse["Content-Type"] = "text/html; charset=UTF-8";
                        //oS.oResponse["Cache-Control"] = "private, max-age=0";

                        // oS.utilSetResponseBody("fazlija ");

                        //oS.utilSetResponseBody("<html><body>Response for https://" + sSecureEndpointHostname + ":" + iSecureEndpointPort.ToString() + " received. Your response was:<br /><plaintext>" + oS.oRequest.headers.ToString());
                        // oS.oResponse["NewHeaderName"] = "\nNew header value";
                        // oSession.oResponse.headers.Remove("Set-Cookie");
                    //}
                };

                // Fiddler.FiddlerApplication.OnReadResponseBuffer += new EventHandler<RawReadEventArgs>(FiddlerApplication_OnReadResponseBuffer);
                Fiddler.FiddlerApplication.BeforeResponse += delegate(Fiddler.Session oS)
                {
                    Console.WriteLine("{0}:HTTP {1} for {2}", oS.id, oS.responseCode, oS.fullUrl);
                     oS.utilDecodeResponse(); oS.utilReplaceInResponse("Amazon", "Something");
                };

                Fiddler.FiddlerApplication.AfterSessionComplete += delegate(Fiddler.Session oS)
                {
                    //Console.WriteLine("Finished session:\t" + oS.fullUrl); 
                    Console.Title = ("Session list contains: " + oAllSessions.Count.ToString() + " sessions");
                };

                Console.CancelKeyPress += new ConsoleCancelEventHandler(Console_CancelKeyPress);
                #endregion AttachEventListeners

                string sSAZInfo = "NoSAZ";

                Console.WriteLine(String.Format("Starting {0} ({1})...", Fiddler.FiddlerApplication.GetVersionString(), sSAZInfo));

                Fiddler.CONFIG.IgnoreServerCertErrors = false;

                FiddlerApplication.Prefs.SetBoolPref("fiddler.network.streaming.abortifclientaborts", true);

                // For forward-compatibility with updated FiddlerCore libraries, it is strongly recommended that you 
                // start with the DEFAULT options and manually disable specific unwanted options.
                FiddlerCoreStartupFlags oFCSF = FiddlerCoreStartupFlags.Default;

                // NOTE: In the next line, you can pass 0 for the port (instead of 8877) to have FiddlerCore auto-select an available port
                int iPort = 8879;
                Fiddler.FiddlerApplication.Startup(iPort, oFCSF);

                FiddlerApplication.Log.LogFormat("Created endpoint listening on port {0}", iPort);

                FiddlerApplication.Log.LogFormat("Starting with settings: [{0}]", oFCSF);
                FiddlerApplication.Log.LogFormat("Gateway: {0}", CONFIG.UpstreamGateway.ToString());

                Console.WriteLine("Hit CTRL+C to end session.");

                // We'll also create a HTTPS listener, useful for when FiddlerCore is masquerading as a HTTPS server
                // instead of acting as a normal CERN-style proxy server.
                oSecureEndpoint = FiddlerApplication.CreateProxyEndpoint(iSecureEndpointPort, true, sSecureEndpointHostname);
                if (null != oSecureEndpoint)
                {
                    FiddlerApplication.Log.LogFormat("Created secure endpoint listening on port {0}, using a HTTPS certificate for '{1}'", iSecureEndpointPort, sSecureEndpointHostname);
                }

                bool bDone = false;
                do
                {

                } while (!bDone);
            }


            /// <summary>
            /// This callback allows your code to evaluate the certificate for a site and optionally override default validation behavior for that certificate.
            /// You should not implement this method unless you understand why it is a security risk.
            /// </summary>
            static void CheckCert(object sender, ValidateServerCertificateEventArgs e)
            {
                if (null != e.ServerCertificate)
                {
                    Console.WriteLine("Certificate for " + e.ExpectedCN + " was for site " + e.ServerCertificate.Subject + " and errors were " + e.CertificatePolicyErrors.ToString());

                    if (e.ServerCertificate.Subject.Contains("fiddler2.com"))
                    {
                        Console.WriteLine("Got a certificate for fiddler2.com. We'll say this is also good for any other site, like https://fiddlertool.com.");
                        e.ValidityState = CertificateValidity.ForceValid;
                    }
                }
            }


            /*
            // This event handler is called on every socket read for the HTTP Response. You almost certainly don't want
            // to add a handler for this event, but the code below shows how you can use it to mess up your HTTP traffic.
            static void FiddlerApplication_OnReadResponseBuffer(object sender, RawReadEventArgs e)
            {
                // NOTE: arrDataBuffer is a fixed-size array. Only bytes 0 to iCountOfBytes should be read/manipulated.
                //
                // Just for kicks, lowercase every byte. Note that this will obviously break any binary content.
                for (int i = 0; i < e.iCountOfBytes; i++)
                {
                    if ((e.arrDataBuffer[i] > 0x40) && (e.arrDataBuffer[i] < 0x5b))
                    {
                        e.arrDataBuffer[i] = (byte)(e.arrDataBuffer[i] + (byte)0x20);
                    }
                }
                Console.WriteLine(String.Format("Read {0} response bytes for session {1}", e.iCountOfBytes, e.sessionOwner.id));
            }
            */

            /// <summary>
            /// When the user hits CTRL+C, this event fires.  We use this to shut down and unregister our FiddlerCore.
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
            {
                DoQuit();
            }

            /*
            public static bool InstallCertificate()
            {
                if (!CertMaker.rootCertExists())
                {
                    if (!CertMaker.createRootCert())
                        return false;

                    if (!CertMaker.trustRootCert())
                        return false;



                    App.Configuration.UrlCapture.Cert =
                        FiddlerApplication.Prefs.GetStringPref("fiddler.certmaker.bc.cert", null);
                    App.Configuration.UrlCapture.Key =
                        FiddlerApplication.Prefs.GetStringPref("fiddler.certmaker.bc.key", null);
                }

                return true;
            }
            public static bool UninstallCertificate()
            {
                if (CertMaker.rootCertExists())
                {
                    if (!CertMaker.removeFiddlerGeneratedCerts(true))
                        return false;
                }
                App.Configuration.UrlCapture.Cert = null;
                App.Configuration.UrlCapture.Key = null;
                return true;
            }

             */
        }
    }
/*
*此演示程序演示如何使用FiddlerCore库。
*
*在编译之前,请确保项目的引用列表指向
*此包中包含的FiddlerCore.dll的副本。
*
*默认情况下,编译项目时不支持SAZ文件格式。
*如果要添加SAZ支持,请在标记列表中定义标记SAZ_支持
*项目的“生成”选项卡上的条件编译符号。你也会
*需要将Ionic.Zip.Reduced.dll添加到项目的引用中。
*/
使用制度;
使用System.Collections.Generic;
使用System.IO;
运用系统反思;
使用系统线程;
使用小提琴;
使用系统诊断;
使用HtmlAgilityPack;
使用System.Security.Cryptography.X509证书;
使用System.Text.RegularExpressions;
名称空间演示
{
班级计划
{
静态代理端点;
静态字符串sSecureEndpointHostname=“localhost”;
静态int iSecureEndpointPort=7777;
公共静态void writeCommand响应(字符串s)
{
ConsoleColor oldColor=Console.ForegroundColor;
Console.ForegroundColor=ConsoleColor.Yellow;
控制台。写入线(s);
Console.ForegroundColor=oldColor;
}
公共静态void DoQuit()
{
书面命令响应(“关闭…”);
//卸载证书();
//Write(“\ncert:{0}”,CertMaker.rootCertExists());Console.ReadLine();
//如果(null!=oSecureEndpoint)oSecureEndpoint.Dispose();
Fiddler.FiddlerApplication.Shutdown();
睡眠(500);
}
私有静态字符串省略(字符串s,int-iLen)
{
如果(标准长度0))
{
oAllSessions.AddRange(oLoaded);
WriteCommandResponse(“加载:+oLoaded.Length+”会话”);
}
}
私有静态void SaveSessionsToDesktop(列出所有会话)
{
bool bsucces=假;
字符串sFilename=Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)
+Path.directoryseportorchar+DateTime.Now.ToString(“hh-mm-ss”)+“.saz”;
尝试
{
尝试
{
Monitor.Enter(oAllSessions);
字符串sPassword=null;
Console.WriteLine(“密码保护此存档(Y/N)?”;
ConsoleKeyInfo-oCKI=Console.ReadKey();
if((oCKI.KeyChar=='y')| |(oCKI.KeyChar=='y'))
{
Console.WriteLine(\n输入密码:);
sPassword=Console.ReadLine();
Console.WriteLine(String.Format(“\n使用密码进行加密:{0}',sPassword));
}
Console.WriteLine();
bSuccess=Utilities.WriteSessionArchive(sFilename,oAllSessions.ToArray(),sPassword,false);
}
最后
{
监视器。退出(oAllSessions);
}
WriteCommand响应(bSuccess?(“写入:+sFilename:”)(“未能保存:+sFilename”);
}
捕获(例外情况除外)
{
Console.WriteLine(“保存失败:+eX.Message”);
}
}
#恩迪夫
公共静态bool安装证书()
{
如果(!CertMaker.rootCertExists())
{
如果(!CertMaker.createRootCert())
返回false;
如果(!CertMaker.trustRootCert())
返回false;
}
返回true;
}
公共静态bool卸载证书()
{
if(CertMaker.rootCertExists())
{
如果(!CertMaker.removeFiddlerGeneratedCerts(true))
返回false;
}
返回true;
}
私有静态void WriteSessionList(列出所有会话)
{
ConsoleColor oldColor=Console.ForegroundColor;
Console.ForegroundColor=ConsoleColor.White;
WriteLine(“会话列表包含…”);
尝试
{
Monitor.Enter(oAllSessions);
foreach(oAllSessions中的会话操作系统)
{
Write(String.Format(“{0}{1}{2}\n{3}{4}\n\n”、oS.id、oS.oRequest.headers.HTTPMethod、Ellipsize(oS.fullUrl,60)、oS.responseCode、oS.oreponse.MIMEType));
}
}
最后
{
监视器。退出(oAllSessions);
}
Console.WriteLine();
Console.ForegroundColor=oldColor;
}
专用静态bool setMachineTrust(X509Certificate2或OTCert)
{
尝试
{
//X509Certificate2 cert=X509Certificate2(“C:\Path\my.pfx”,“密码”);
X509Store certStore=新的X509Store(StoreName.Root,StoreLoca