Filter讲解4

一、使用.NET代码扩展Fiddler

使用Fiddler的可扩展性机制添加到Fiddler的UI,自动修改请求或响应,并创建自定义检查器,以启用特定于方案的显示和手动修改请求和响应。

要求

  • Visual Studio .NET 2005+或免费的.NET Framework v2命令行编译器
  • Fiddler的最新版本
  • 对于Visual Studio 2010或更高版本:将项目更改为以.NET2.0 / 3.5框架为目标。
  • 如果以.NET Framework 3.5为目标:确保用户已安装.NET Framework 3.5。
  • 如果扩展64位Fiddler:Target AnyCPU。

请参阅构建扩展程序集以在Fiddler 2和4中运行

调试

直接Fiddler加载扩展程序集

  • 要使扩展可供计算机上的所有用户使用,请将扩展程序集DLL安装到:

    %Program Files%\Fiddler2\Scripts
  • 要使扩展仅对当前用户可用,请将扩展程序集DLL安装到:

    %USERPROFILE%\My Documents\Fiddler2\Scripts
  • 在AssemblyInfo.cs文件(或代码中的其他位置)中设置Fiddler.RequiredVersion属性,如下所示:

    using Fiddler;
    
    // Extension requires Fiddler 2.2.8.6+ because it uses types introduced in v2.2.8...
    [assembly: Fiddler.RequiredVersion("2.2.8.6")]

     

示例扩展:一步一步

  1. 启动Visual Studio 2005或更高版本。

  2. 创建一个Visual C#类库类型的新项目。

  3. 在解决方案资源管理器中右键单击项目的References文件夹。

  4. 单击“ 浏览”选项卡,然后在C:\ Program Files \ Fiddler2文件夹中选择Fiddler.exe。

  5. 单击“ 确定”以添加引用。

  6. 如果您的扩展程序修改了Fiddler的UI:

    • 再次右键单击解决方案资源管理器中项目的References文件夹
    • 在.NET选项卡上,选择System.Windows.Forms。
    • 单击“确定”以添加引用。
    • 在解决方案资源管理器中,右键单击该项目。选择属性。
    • 在“构建事件”选项卡上,将以下内容添加到“构建后事件”命令行:

      复制“$(TargetPath)”“%userprofile%\ My Documents \ Fiddler2 \ Scripts \ $(TargetFilename)”

修改项目中的默认class1.cs(或创建一个新类),如下所示:

using System;
using System.Windows.Forms;
using Fiddler;

[assembly: Fiddler.RequiredVersion("2.3.5.0")]

public class Violin : IAutoTamper    // Ensure class is public, or Fiddler won't see it!
{
  string sUserAgent = "";

  public Violin(){
  /* NOTE: It's possible that Fiddler UI isn't fully loaded yet, so don't add any UI in the constructor.

     But it's also possible that AutoTamper* methods are called before onl oad (below), so be
     sure any needed data structures are initialized to safe values here in this constructor */

     sUserAgent = "Violin";
  }

  public void onl oad(){ /* Load your UI here */ }
  public void OnBeforeUnload() { }

  public void AutoTamperRequestBefore(Session oSession){
    oSession.oRequest["User-Agent"] = sUserAgent;
  }
  public void AutoTamperRequestAfter(Session oSession){}
  public void AutoTamperResponseBefore(Session oSession){}
  public void AutoTamperResponseAfter(Session oSession){}
  public void OnBeforeReturningError(Session oSession){}
}

 



二、
实现Fiddler接口

在Fiddler执行期间实现Fiddler接口以加载程序集。

启动期间的负载扩展

实现IFiddlerExtension接口的程序集中的公共类将在启动期间由Fiddler加载。

  public interface IFiddlerExtension
    {
      // Called when Fiddler User Interface is fully available
      void onl oad();

      // Called when Fiddler is shutting down
      void OnBeforeUnload();
    }

 

  • 该的OnLoad当小提琴手加载完成其UI是完全可用的功能将被调用。此时,您可以安全地将菜单项,选项卡式页面或其他元素添加到Fiddler UI。

  • 该OnBeforeUnload函数将被调用时,提琴手被关闭和卸载所有扩展。

每个Web请求的呼叫扩展

  • 为每个HTTP / HTTPS请求和响应调用实现IAutoTamper接口(扩展IFiddlerExtension)的扩展,从而启用修改,日志记录或其他操作。

    警告:此接口中的函数在后台非UI线程上调用。要更新UI,请使用 Invoke或 BeginInvoke更新UI。另请注意,可以在调用 OnLoad事件之前调用IAutoTamper :: *函数 -Fiddler允许流量在UI完全可用之前流动。

      public interface IAutoTamper : IFiddlerExtension
      {
        // Called before the user can edit a request using the Fiddler Inspectors
        void AutoTamperRequestBefore(Session oSession);
    
        // Called after the user has had the chance to edit the request using the Fiddler Inspectors, but before the request is sent
        void AutoTamperRequestAfter(Session oSession);
    
        // Called before the user can edit a response using the Fiddler Inspectors, unless streaming.
        void AutoTamperResponseBefore(Session oSession);
    
        // Called after the user edited a response using the Fiddler Inspectors.  Not called when streaming.
        void AutoTamperResponseAfter(Session oSession);
    
        // Called Fiddler returns a self-generated HTTP error (for instance DNS lookup failed, etc)
        void OnBeforeReturningError(Session oSession);
      }

     

  • 当响应头可用时,将调用实现IAutoTamper2接口(扩展IAutoTamper)的扩展。

    /// <summary>
    /// Interface for AutoTamper extensions that want to "peek" at response headers
    /// </summary>
    public interface IAutoTamper2 : IAutoTamper
    {
    /// <summary>
    /// Called when the response headers become available
    /// </summary>
    /// <param name="oSession">The Session object for which the response headers are available</param>
    void OnPeekAtResponseHeaders(Session oSession);
    }

     

  • 当请求标头可用时,将调用实现IAutoTamper3接口(扩展IAutoTamper2)的扩展。

    /// <summary>
    /// Interface for AutoTamper extensions that want to "peek" at request headers
    /// </summary>
    public interface IAutoTamper3 : IAutoTamper2
    {
    /// <summary>
    /// Called when the request headers become available
    /// </summary>
    /// <param name="oSession">The Session object for which the request headers are available</param>
    void OnPeekAtRequestHeaders(Session oSession);
    }

     

用户进入QuickExec命令时调用扩展

  • 当用户在QuickExec框中输入命令时,将调用实现IHandleExecAction接口的扩展。要对命令作出反应(并防止其他扩展和Fiddler本身进一步处理),请从此方法返回true。

    public interface IHandleExecAction
    {
      // return TRUE if handled. 
      bool OnExecAction(string sCommand); 
    }

     

  • Fiddler.Utilities类包含一个辅助函数Parameterize(),它有助于解释sCommand参数。

    [CodeDescription("Tokenize a string into tokens. Delimits on whitespace; Quotation marks are dropped unless preceded by a \ character.")] 
    public static string[] Parameterize(string sCommand)

     

三、创建Fiddler扩展项目

按照以下步骤创建示例Fiddler扩展,修改所有出站请求的User-Agent字符串:

添加对Fiddler的引用

  1. 启动Visual Studio 2005或更高版本。

  2. 创建一个Visual C#类库类型的新项目。

  3. 在解决方案资源管理器中右键单击项目的References文件夹。

  4. 单击“ 浏览”选项卡,然后在C:\ Program Files \ Fiddler2文件夹中选择Fiddler.exe。

  5. 单击“ 确定”以添加引用。

添加对System.Windows.Forms的引用

如果您的扩展程序修改了Fiddler的UI:

  1. 再次右键单击解决方案资源管理器中项目的References文件夹。

  2. 在.NET选项卡上,选择System.Windows.Forms。

  3. 单击“ 确定”以添加引用。

添加构建事件

  1. 在解决方案资源管理器中,右键单击该项目。

  2. 单击属性。

  3. 单击“ 构建事件”选项卡。

  4. 将以下内容添加到Post-build事件命令行:

    copy "$(TargetPath)" "%userprofile%\My Documents\Fiddler2\Scripts\$(TargetFilename)"

     

实现Fiddler接口

修改项目中的默认class1.cs(或创建一个新类),如下所示:

 using System;
    using System.Windows.Forms;
    using Fiddler;

    [assembly: Fiddler.RequiredVersion("2.3.5.0")]

    public class Violin : IAutoTamper    // Ensure class is public, or Fiddler won't see it!
    {
      string sUserAgent = "";

      public Violin(){
      /* NOTE: It's possible that Fiddler UI isn't fully loaded yet, so don't add any UI in the constructor.

         But it's also possible that AutoTamper* methods are called before onl oad (below), so be
         sure any needed data structures are initialized to safe values here in this constructor */

         sUserAgent = "Violin";
      }

      public void onl oad(){ /* Load your UI here */ }
      public void OnBeforeUnload() { }

      public void AutoTamperRequestBefore(Session oSession){
        oSession.oRequest["User-Agent"] = sUserAgent;
      }
      public void AutoTamperRequestAfter(Session oSession){}
      public void AutoTamperResponseBefore(Session oSession){}
      public void AutoTamperResponseAfter(Session oSession){}
      public void OnBeforeReturningError(Session oSession){}
    }

 

请参阅Fiddler接口

编译和加载扩展

在Fiddler中编译和加载扩展

 

四、在扩展程序选项卡中添加一个图标

使用现有图标

设置.ImageIndex属性,如下所示:

   public void onl oad()
    {
    oPage = new TabPage("Timeline");
    oPage.ImageIndex = (int)Fiddler.SessionIcons.Timeline;
    oView = new TimelineView();
    oPage.Controls.Add(oView);
    oView.Dock = DockStyle.Fill;
    FiddlerApplication.UI.tabsViews.TabPages.Add(oPage); 
    }

 

添加自定义图像

  1. 将图像添加到imglSessionIcons。

  2. 设置.ImageIndex属性,如下所示:

    public void onl oad()
    {
    oPage = new TabPage("Timeline");
    oPage.ImageIndex = (int)Fiddler.SessionIcons.Timeline;
    oView = new TimelineView();
    oPage.Controls.Add(oView);
    oView.Dock = DockStyle.Fill;
    FiddlerApplication.UI.tabsViews.TabPages.Add(oPage); 
    }

     

五、在Fiddler中加载扩展

  1. 编译您的项目。

  2. 将程序集.DLL复制到正确的Scripts文件夹:

    • 使用\ My Documents \ Fiddler2 \ Scripts使扩展可供当前用户使用。

    • 使用\ Program Files \ Fiddler2 \ Scripts使扩展可供计算机上的所有用户使用。

  3. 重启Fiddler。

六、构建自定义检查器

  1. 创建一个Fiddler扩展项目

  2. 更改代码以从Inspector2类派生并实现IResponseInspector2或IRequestInspector2。

    using Fiddler;
    
    [assembly: Fiddler.RequiredVersion("2.3.0.0")]
    
    public class WebViewer: Inspector2, IResponseInspector2
    {
        public Viewers()
        {
        //
        // TODO: Add constructor logic here
        //
        }
    }

     

  3. 在课堂内,创建一个新方法。通过键入公共覆盖,您将获得需要编写的方法的自动完成列表。

  4. 在解决方案资源管理器中,右键单击项目,然后单击添加>用户控件。

  5. 使用工具箱将控件添加到用户控件。这些将显示有关正在检查的HTTP消息的数据。

  6. 在body {set}和headers {set}属性中,您应该更新控件的请求或响应的可视化表示。

  7. 在Fiddler中编译并加载您的扩展

 

七、导入器和导出器接口

线程安全和FiddlerCore

  • 目前,在MAIN UI线程上调用ISessionImporter和ISessionExporter接口。这几乎肯定会在将来发生变化,因此您应该确保您的类是线程安全的,并且他们不会尝试直接操作Fiddler UI。

  • 对Fiddler UI的操纵还是不明智的,因为Fiddler本身可能无法加载; FiddlerCore可能直接托管您的进口商/出口商。为了支持FiddlerCore,建议您在dictOptions参数中支持Filename键(具有完全限定路径的字符串值),并考虑支持Silent键(值为boolean)。

ISessionImporter接口

当用户使用“ 文件”>“导入”菜单选项时,将调用实现ISessionImporter接口(实现IDisposable接口)的扩展。

public interface ISessionImporter : IDisposable
{
   Session[] ImportSessions(string sImportFormat, Dictionary<string, object> dictOptions,
         EventHandler<ProgressCallbackEventArgs> evtProgressNotifications);
}

 

该方法返回从导入数据创建的Session对象数组。

所述dictOptions字典可以为空,也可以含有一组字符串键控对象。大多数进口商都支持文件名的规范。例如:

dictOptions["Filename"] = "C:\\test.file"

ISessionExporter接口

此类由Fiddler定义,允许您报告导入或导出操作的进度。

如果无法确定完成率,只需传递0或0到1.0之间的“猜测”。

如果在传递给evtProgressNotifications回调后在ProgressCallbackEventArgs对象上设置了Cancel标志,则导入或导出应该尽快正常终止。

public class ProgressCallbackEventArgs: EventArgs
{
  public ProgressCallbackEventArgs(float flCompletionRatio, string sProgressText)
  public string ProgressText { get; }
  public string PercentComplete { get; }
  public bool Cancel { get; set; }
}

 



八、
构建自定义导入程序或导出程序

样本扩展

  1. 创建一个Fiddler扩展项目

  2. 修改项目中的默认class1.cs(或创建一个新类),如下所示:

    using System;
    using System.IO;
    using System.Text;
    using System.Windows.Forms;
    using Fiddler;
    using System.Diagnostics;
    using System.Reflection;
    [assembly: AssemblyVersion("1.0.0.0")]
    [assembly: Fiddler.RequiredVersion("2.4.0.0")]
    
    
    [ProfferFormat("TAB-Separated Values", "Session List in Tab-Delimited Format")]
    [ProfferFormat("Comma-Separated Values", 
        "Session List in Comma-Delimited Format; import into Excel or other tools")]
    
    public class CSVTranscoder: ISessionExporter  // Ensure class is public, or Fiddler won't see it!
    {
      public bool ExportSessions(string sFormat, Session[] oSessions, Dictionary<string, object> dictOptions,
          EventHandler<ProgressCallbackEventArgs> evtProgressNotifications)
      {
        bool bResult = false; 
        string chSplit;
    
        // Determine if we already have a filename from the dictOptions collection
        string sFilename = null;
        if (null != dictOptions && dictOptions.ContainsKey("Filename"))
        {
          sFilename = dictOptions["Filename"] as string;
        }
    
        if (sFormat == "Comma-Separated Values")
        {
          chSplit = ",";
          if (string.IsNullOrEmpty(sFilename)) sFilename = Fiddler.Utilities.ObtainSaveFilename("Export As " + sFormat, "CSV Files (*.csv)|*.csv");
        }
        else
        {
          chSplit = "\t";
          if (string.IsNullOrEmpty(sFilename)) sFilename = Fiddler.Utilities.ObtainSaveFilename("Export As " + sFormat, "TSV Files (*.tsv)|*.tsv");
        }
    
        if (String.IsNullOrEmpty(sFilename)) return false;
    
        try
        {
          StreamWriter swOutput = new StreamWriter(sFilename, false, Encoding.UTF8);
          int iCount = 0;
          int iMax = oSessions.Length;
    
          #region WriteColHeaders
          bool bFirstCol = true;
          foreach (ColumnHeader oLVCol in FiddlerApplication.UI.lvSessions.Columns)
          {
            if (!bFirstCol)
            {
            swOutput.Write(chSplit);
            }
            else
            {
            bFirstCol = false;
            }
            swOutput.Write(oLVCol.Text.Replace(chSplit, ""));
            }
            swOutput.WriteLine();
            #endregion WriteColHeaders
    
            #region WriteEachSession
            foreach (Session oS in oSessions)
            {
            iCount++;
            if (null != oS.ViewItem)
            {
            bFirstCol = true;
            ListViewItem oLVI = (oS.ViewItem as ListViewItem);
            if (null == oLVI) continue;
            foreach (ListViewItem.ListViewSubItem oLVC in oLVI.SubItems)
            {
              if (!bFirstCol)
            {
              swOutput.Write(chSplit);
            }
            else
            {
              bFirstCol = false;
            } 
    
              swOutput.Write(oLVC.Text.Replace(chSplit,""));}
    
            swOutput.WriteLine();}if(null!= evtProgressNotifications){
            evtProgressNotifications(null,newProgressCallbackEventArgs(,));ProgressCallbackEventArgs PCEA =newProgressCallbackEventArgs((iCount/(float)iMax),"wrote "+ iCount.ToString()+" records.");
            evtProgressNotifications(null, PCEA);if(PCEA.Cancel){ swOutput.Close();returnfalse;}}}#endregion WriteEachSession
    
        swOutput.Close();
        bResult =true;}catch(Exception eX){MessageBox.Show(eX.Message,"Failed to export");
          bResult =false;}}return bResult;}publicvoidDispose(){}}

     

  3. 在Fiddler中编译并加载您的扩展

也可以看看

构建扩展程序集以在Fiddler 2和4中运行

 

九、将参数传递给Importer或Exporter Extension

  • 转码器(实现导入器或导出器接口的对象)可以在字典对象中传递参数。例如,FiddlerScript可以调用HTTPArchive转码器,传递文件名字符串和最大响应大小整数,如下所示:

    var oSessions = FiddlerApplication.UI.GetAllSessions();
    var oExportOptions = FiddlerObject.createDictionary();
    oExportOptions.Add("Filename", "C:\\users\\ericlaw\\desktop\\out1.har");
    oExportOptions.Add("MaxTextBodyLength", 1024);
    oExportOptions.Add("MaxBinaryBodyLength", 16384);
    FiddlerApplication.DoExport("HTTPArchive v1.2", oSessions, oExportOptions, null);

     

  • 代码转换器扩展可以按如下方式收集这些选项:

    public bool ExportSessions(string sFormat, Session[] oSessions, 
        Dictionary<string, object> dictOptions, EventHandler<ProgressCallbackEventArgs> evtProgressNotifications)
    {
    
    //...
    
      if (null != dictOptions)
      { 
        if (dictOptions.ContainsKey("Filename"))
        {
        sFilename = dictOptions["Filename"] as string;
        }
    
        if (dictOptions.ContainsKey("MaxTextBodyLength"))
        {
          iMaxTextBodyLength = (int)dictOptions["MaxTextBodyLength"];
        }
    
        if (dictOptions.ContainsKey("MaxBinaryBodyLength"))
        {
           iMaxBinaryBodyLength = (int)dictOptions["MaxBinaryBodyLength"];
        }
      }

     

十、为Fiddler v2和v4构建扩展程序集

  • 如果您希望扩展程序集在Fiddler2和Fiddler4中运行,请为.NET Framework v2构建它,并避免对在更高版本的Framework中删除或移动的任何类具有任何依赖性。(我所知道的唯一一个实例是Microsoft JScript.NET代码编译器,其类移动了一下)。

    您还需要确保如果使用任何不推荐使用的方法(例如,使用带有Evidence参数的重载调用Assembly.LoadFrom),则只能有条件地执行此操作。例如:

      if (CONFIG.bRunningOnCLRv4)
        {
          a = Assembly.LoadFrom(oFile.FullName);
        }
        else
        {
          a = Assembly.LoadFrom(oFile.FullName, evidenceFiddler);
        }

     

    来自Fiddler网站的所有扩展都是针对Fiddler v2编译的。

  • 或者,您可以简单地构建两个版本的DLL,一个版本针对.NET Framework v4,另一个针对.NET Framework v2。

    这就是Fiddler本身的构建方式。基本上,只需将v2目标项目的“克隆”版本添加到同一解决方案中。使用“ 添加”>“现有项”上下文菜单将.CS文件从以v2为目标的项目添加到以v4为目标的项目,但在选择文件时,请务必使用文件选取器对话框中的拆分按钮,然后选择“ 添加为”。链接。在v4项目的“ 属性”>“构建”选项卡上,添加像DOTNET4这样的条件编译符号。然后,您可以将任何特定于.NETv4的代码置于条件编译之后:

     #if DOTNET4
    
          // ... code targeting .NETv4
    
        #else
    
          // ... code targeting .NETv2
    
        #endif

     

    您的扩展程序可能会根据在其中找到的InstalledVersion注册表项的内容安装适当目标的版本:

      HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Fiddler2 

    .NET2版的Fiddler目前比.NETv4版本更受欢迎。当.NET Framework v4.5发布时,我可能会将v4项目移到v4.5。除此之外,这将允许我在后面的框架中利用新的内置.ZIP类。

  • RequiredVersion属性怎么样?

    Fiddler v4是“聪明的” - 如果您的扩展指定

      [assembly: Fiddler.RequiredVersion("2.1.0.1")]

    当Fiddler v4加载它时,它将需要4.3.9.9或更高版本。

十一、示例扩展

要查看一些示例扩展,请查看Fiddler Add-Ons页面Privacy Scanner Add-On代码

 

十二、向Fiddler添加规则

自定义规则

要将自定义列添加到Fiddler UI,修改请求或响应,测试应用程序性能以及各种其他自定义任务,请在FiddlerScript中向Fiddler的JScript.NET CustomRules.js文件添加规则。

  1. 按此规则>自定义规则...。

  2. 在相应的函数内输入FiddlerScript代码。

  3. 保存文件。

Fiddler会自动重新加载规则。

使用其他.NET程序集

要在脚本中使用其他.NET程序集:

  1. 单击工具>提琴选项。

  2. 单击“ 扩展”选项卡。

  3. 编辑参考列表。

  4. 或者:

    • 在GAC中注册程序集; 要么

    • 将程序集复制到包含Fiddler.exe的文件夹。

要在不完全限定它们的情况下使用新程序集的函数,请更新脚本顶部的#import子句。

更改从“ 规则”菜单启动的JScript编辑器

  1. 单击工具>提琴选项。

  2. 编辑编辑器字符串。

恢复默认规则

  1. 删除〜/ Documents / Fiddler2 / Scripts中的CustomRules.js文件。

  2. 重启Fiddler。

注意:Fiddler的默认规则存储在〜/ Program Files / Fiddler2 / Scripts / SampleRules.js中。

 

十三、添加菜单项

要将菜单操作添加到“ 工具”菜单或上下文菜单,或者将选项添加到“ 规则”菜单:

  1. 创建并执行.REG文件,如下所示:

    [HKEY_CURRENT_USER\Software\Microsoft\Fiddler2\MenuExt\&YourMenuItemName]
    "Command"="YourExeName.exe"
    "Parameters"="Your Parameters To Pass To The EXE"

     

  2. 重启Fiddler。

十四、在FiddlerScript中使用.NET程序集

要使用.NET插件(对于此示例,修改用户代理字符串的C#插件):

添加参考

  1. 关闭提琴手。

  2. 保存.NET文件(例如,此文件名为UASimulator.cs):

    using System;
    using System.Windows.Forms;
    using Fiddler;
    
    namespace FiddlerUtility{
    
          public class UASimulator {
                string m_sUAString;
                public UASimulator(string s_UAString){
                      m_sUAString = s_UAString;
                }
    
                public bool OverwriteUA(Session oSession){
                      oSession.oRequest["User-Agent"] = m_sUAString;
                      return true;
                }
          }
    }

     

  3. 在VS命令提示符下,转到找到.CS文件的文件夹。

  4. 输入命令以在VS命令提示符中创建DLL。例如:

    csc /target:library /out:c:\UASim.dll UASimulator.cs /reference:"C:\program files\fiddler2\fiddler.exe"
  5. 在Fiddler中,单击工具> Fiddler选项。

  6. 单击“ 扩展”选项卡。

  7. 在“ 引用”字段中,输入DLL的位置。例如:

    C:\UASim.dll

更新提琴手规则

向Fiddler添加规则以更新脚本。例如:

 import System;
    import System.Windows.Forms;
    import Fiddler;
    import FiddlerUtility;

    class Handlers{

          static var UASim = new UASimulator("Mozilla/12.0");

          static function OnBeforeRequest(oSession:Fiddler.Session){

                UASim.OverwriteUA(oSession);

          }

       static function Main(){

           var today: Date = new Date();      

           FiddlerObject.StatusText = " CustomRules.js was loaded at: " + today;

       }

    }

 



十五、
构建Cookie扫描扩展

以下是Fiddler Privacy Scanner插件的代码。

 using System;
    using System.Collections;
    using System.Globalization;
    using System.Collections.Generic;
    using System.Windows.Forms;
    using System.Text;
    using Fiddler;
    using System.IO;
    using System.Diagnostics;
    using Microsoft.Win32;
    using System.Reflection;
    using System.Text.RegularExpressions;

    [assembly: Fiddler.RequiredVersion("2.3.9.0")]
    [assembly: AssemblyVersion("1.0.1.0")]
    [assembly: AssemblyTitle("PrivacyScanner")]
    [assembly: AssemblyDescription("Scans for Cookies and P3P")]
    [assembly: AssemblyCompany("Eric Lawrence")]
    [assembly: AssemblyProduct("PrivacyScanner")]

    public class TagCookies : IAutoTamper2
    {
        private bool bEnabled = false;
        private bool bEnforceP3PValidity = false;
        private bool bCreatedColumn = false;
        private System.Windows.Forms.MenuItem miEnabled;
        private System.Windows.Forms.MenuItem miEnforceP3PValidity;
        private System.Windows.Forms.MenuItem mnuCookieTag;

        public void onl oad()
        {
            /*
     * NB: You might not get called here until ~after~ one of the AutoTamper methods was called.
     * This is okay for us, because we created our mnuContentBlock in the constructor and its simply not
     * visible anywhere until this method is called and we merge it onto the Fiddler Main menu.
     */
            FiddlerApplication.UI.mnuMain.MenuItems.Add(mnuCookieTag);
        }

        public void OnBeforeUnload() {  /*noop*/   }

        private void InitializeMenu()
        {
            this.miEnabled = new System.Windows.Forms.MenuItem("&Enabled");
            this.miEnforceP3PValidity = new System.Windows.Forms.MenuItem("&Rename P3P header if invalid");

            this.miEnabled.Index = 0;
            this.miEnforceP3PValidity.Index = 1;

            this.mnuCookieTag = new System.Windows.Forms.MenuItem();
            this.mnuCookieTag.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.miEnabled, this.miEnforceP3PValidity });
            this.mnuCookieTag.Text = "Privacy";

            this.miEnabled.Click += new System.EventHandler(this.miEnabled_Click);
            this.miEnabled.Checked = bEnabled;

            this.miEnforceP3PValidity.Click += new System.EventHandler(this.miEnforceP3PValidity_Click);
            this.miEnforceP3PValidity.Checked = bEnforceP3PValidity;
        }

        public void miEnabled_Click(object sender, EventArgs e)
        {
            miEnabled.Checked = !miEnabled.Checked;
            bEnabled = miEnabled.Checked;
            this.miEnforceP3PValidity.Enabled = bEnabled;
            if (bEnabled) { EnsureColumn(); }
            FiddlerApplication.Prefs.SetBoolPref("extensions.tagcookies.enabled", bEnabled);
        }publicvoid miEnforceP3PValidity_Click(object sender,EventArgs e){
            miEnforceP3PValidity.Checked=!miEnforceP3PValidity.Checked;
            bEnforceP3PValidity = miEnforceP3PValidity.Checked;FiddlerApplication.Prefs.SetBoolPref("extensions.tagcookies.EnforceP3PValidity", bEnforceP3PValidity);}privatevoidEnsureColumn(){if(bCreatedColumn)return;FiddlerApplication.UI.lvSessions.AddBoundColumn("Privacy Info",1,120,"X-Privacy");

            bCreatedColumn =true;}publicTagCookies(){this.bEnabled =FiddlerApplication.Prefs.GetBoolPref("extensions.tagcookies.enabled",false);this.bEnforceP3PValidity =FiddlerApplication.Prefs.GetBoolPref("extensions.tagcookies.EnforceP3PValidity",true);InitializeMenu();if(bEnabled){EnsureColumn();}else{this.miEnforceP3PValidity.Enabled=false;}}privatevoidSetP3PStateFromHeader(string sValue,ref P3PState oP3PState){if(string.IsNullOrEmpty(sValue)){return;}string sUnsatCat =String.Empty;string sUnsatPurpose =String.Empty;
            sValue = sValue.Replace('\'','"');string sCP =null;Regex r =newRegex("CP\\s?=\\s?[\"]?(?<TokenValue>[^\";]*)");Match m = r.Match(sValue);if(m.Success&&(null!= m.Groups["TokenValue"])){
                sCP = m.Groups["TokenValue"].Value;}if(String.IsNullOrEmpty(sCP)){return;}// Okay, we've got a compact policy token.

            oP3PState = P3PState.P3POk;string[] sTokens = sCP.Split(newchar[]{' '},StringSplitOptions.RemoveEmptyEntries);foreach(string sToken in sTokens){// Reject clearly invalid tokens...if((sToken.Length<3)||(sToken.Length>4)){
                    oP3PState = P3PState.P3PMalformed;return;}if(",PHY,ONL,GOV,FIN,".IndexOf(","+ sToken +",",StringComparison.OrdinalIgnoreCase)>-1){
                    sUnsatCat +=(sToken +" ");continue;}if(",SAM,OTR,UNR,PUB,IVA,IVD,CON,TEL,OTP,".IndexOf(","+ sToken +",",StringComparison.OrdinalIgnoreCase)>-1){
                    sUnsatPurpose +=(sToken +" ");continue;}// TODO: Look up the token in the complete collection and check validity}// If a cookie contains an unsatisfactory purpose and an unsatisfactory category, mark it// https://msdn.microsoft.com/en-us/library/ie/ms537343(v=vs.85).aspx#unsatisfactory_cookiesif((sUnsatCat.Length>0)&&(sUnsatPurpose.Length>0)){if(oP3PState == P3PState.P3POk){
                    oP3PState = P3PState.P3PUnsatisfactory;}}}privateenum P3PState
        {NoCookies,NoP3PAndSetsCookies,
            P3POk,
            P3PUnsatisfactory,
            P3PMalformed
        }publicvoidOnPeekAtResponseHeaders(Session oSession){if(!bEnabled)return;

            P3PState oP3PState = P3PState.NoCookies;if(!oSession.oResponse.headers.Exists("Set-Cookie")){return;}

            oP3PState = P3PState.NoP3PAndSetsCookies;if(oSession.oResponse.headers.Exists("P3P")){SetP3PStateFromHeader(oSession.oResponse.headers["P3P"],ref oP3PState);}switch(oP3PState){case P3PState.P3POk:
                    oSession["ui-backcolor"]="#ACDC85";
                    oSession["X-Privacy"]="Sets cookies & P3P";break;case P3PState.NoP3PAndSetsCookies:
                    oSession["ui-backcolor"]="#FAFDA4";
                    oSession["X-Privacy"]="Sets cookies without P3P";break;case P3PState.P3PUnsatisfactory:
                    oSession["ui-backcolor"]="#EC921A";
                    oSession["X-Privacy"]="Sets cookies; P3P unsatisfactory for 3rd-party use";break;case P3PState.P3PMalformed:
                    oSession["ui-backcolor"]="#E90A05";if(bEnforceP3PValidity){
                        oSession.oResponse.headers["MALFORMED-P3P"]= oSession.oResponse.headers["P3P"];
                        oSession["X-Privacy"]="MALFORMED P3P: "+ oSession.oResponse.headers["P3P"];
                        oSession.oResponse.headers.Remove("P3P");}break;}}publicvoidAutoTamperRequestBefore(Session oSession){}publicvoidAutoTamperRequestAfter(Session oSession){/*noop*/}publicvoidAutoTamperResponseAfter(Session oSession){/*noop*/}publicvoidAutoTamperResponseBefore(Session oSession){/*noop*/}publicvoidOnBeforeReturningError(Session oSession){/*noop*/}}
 
上一篇:fidder保存请求和保存响应结果


下一篇:【转】Fiddler 教程