关于埋点,我的第一个Fiddler插件


前言

埋点是业务测试过程中,算是一个比较繁琐的环节,一般情况下检查埋点,可以通过网络抓包,或者埋点数据落库去检查数据库去校验,但是我觉得这些都比较麻烦,对我这种比较懒的人来说,简直不太友好,基于这些想在网络抓包的时候可以再做一层过滤对请求做处理,以表格的形式展示埋点信息,让我可以很清晰的看清埋点是否有上报


一、效果图

别的不说先上图看看最终的成果吧。
在这里插入图片描述
主要功能,从图中也可以看出,就是抓取指定的URL,然后对URL进行解析,取出埋点参数,展示到表单中

二、如何实现的?

1.开发语言C#

C#是好久没有碰到过的东西了,大学的时候也是简单的接触过,不过为了让自己更加懒一点,还是感觉恶补一波

主要核心部分代码

代码如下(示例):

using Fiddler;
using System;
using System.Windows.Forms;
using System.IO;
using System.Text;
using System.Threading;
using System.Text.RegularExpressions;

namespace FiddlerExtension
{
    public class Class1 : IAutoTamper
    {
        private TabPage tabPage; //创建插件的选项卡页
        private UserControl1 myCtrl; //MyControl自定义控件
        private string filePath;
        //private FileStream fs;
        //private StreamWriter sw;
        private StringBuilder contentSBTrue;
        private StringBuilder contentSBFalse;
        private Boolean isUseSBFlag;
        private int currentCount;
        public const int WRITE_FILE_THRESHOLD = 1;

        public Class1()
        {
            //构造函数中实例化对象
            this.tabPage = new TabPage("MyFiddlerExtension");//选项卡的名字为Test
            this.myCtrl = new UserControl1();
            filePath = AppDomain.CurrentDomain.BaseDirectory + "output" + ".csv";
            //StringBuilder sb = new StringBuilder();
            //fs = new FileStream(path, FileMode.Create);
            //sw = new StreamWriter(fs);
            contentSBTrue = new StringBuilder();
            contentSBFalse = new StringBuilder();
            isUseSBFlag = true;
            currentCount = 0;
        }

        public void OnLoad()
        {
            //将用户控件添加到选项卡中
            this.tabPage.Controls.Add(this.myCtrl);
            //为选项卡添加icon图标,这里使用Fiddler 自带的
            this.tabPage.ImageIndex = (int)Fiddler.SessionIcons.Timeline;
            //将tabTage选项卡添加到Fidder UI的Tab 页集合中
            FiddlerApplication.UI.tabsViews.TabPages.Add(this.tabPage);
        }

        public void OnBeforeUnload()
        {

        }
        public static string GetValue(string str, string s, string e) //截取字符串指定区间
        {
             Regex rg = new Regex("(?<=(" + s + "))[.\\s\\S]*?(?=(" + e + "))", RegexOptions.Multiline | RegexOptions.Singleline);
             return rg.Match(str).Value;
        }

    // Called before the user can edit a request using the Fiddler Inspectors
    public void AutoTamperRequestBefore(Session oSession)
        {
            // this.myCtrl.textBox1.Text += oSession.fullUrl + "\r\n";
            // 过滤满足条件的host
            if (this.myCtrl.Filter != "")
            {
                string url = oSession.fullUrl;
                foreach (string filterString in this.myCtrl.FilterArray)
                {
                    if (url.Contains(filterString))
                    {
                        ListViewItem item = new ListViewItem(this.myCtrl.listView1.Items.Count + "");
                        //item.SubItems.Add(oSession.host); // 加入host
                        //item.SubItems.Add(oSession.fullUrl); // 加入fullUrl
                        item.SubItems.Add(System.Web.HttpUtility.UrlDecode(GetValue(url, "&pageId=", "&defined_name")));//解析参数pageId
                        item.SubItems.Add(System.Web.HttpUtility.UrlDecode(GetValue(url, "&defined_name=", "&defined_value")));//解析参数defined_name
                        item.SubItems.Add(System.Web.HttpUtility.UrlDecode(GetValue(url, "&defined_value=", "&deviceInfo")));//解析参数defined_value
                        item.SubItems.Add(oSession.id + "");// 加入packetNo
                        item.SubItems.Add(DateTime.Now.ToString()); // 加入time
                                                                    
                        this.myCtrl.listView1.Items.Add(item);
                        string temp = oSession.id + "," + oSession.fullUrl + "," + DateTime.Now.ToString(); // 取出url的数据进行保存
                        currentCount++;
                        //sw.WriteLine(temp);
                        //sw.Flush();
                        if (isUseSBFlag) // 写出到contentSBTrue中
                        {
                            AppendSB(contentSBTrue, temp);
                        }
                        else  // 写出到contentSBFalse中
                        {
                            AppendSB(contentSBFalse, temp);
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 写入到StringBuilder中,满足一定条件后写出到文件中
        /// </summary>
        /// <param name="contentSB">StringBuilder</param>
        /// <param name="temp">追加到contentSB的string</param>
        /// <returns></returns>
        private void AppendSB(StringBuilder contentSB, string temp)
        {
            contentSB.AppendLine(temp);
            if (currentCount >= WRITE_FILE_THRESHOLD)
            {
                isUseSBFlag = !isUseSBFlag;
                // 线程统一写出到文件中
                currentCount = 0;
                Thread thexp = new Thread(() => WriteToFile(ref contentSB, this.filePath)) { IsBackground = true };
                thexp.Start();
            }
        }


        /// <summary>
        /// 写入记事本
        /// </summary>
        /// <param name="contentSB">写出的内容</param>
        /// <param name="filePath">文件路径(含文件名)</param>
        /// <returns></returns>
        private static void WriteToFile(ref StringBuilder contentSB, string filePath)
        {
            try
            {
                File.AppendAllText(filePath, contentSB.ToString(), Encoding.UTF8);
                //MessageBox.Show("已保存完毕,路径:" + filePath);
                contentSB.Remove(0, contentSB.Length); // 清空
            }
            catch
            {
                //MessageBox.Show("遇到问题,未保存到文件中");
            }
        }

        // Called after the user has had the chance to edit the request using the Fiddler Inspectors, but before the request is sent
        public void AutoTamperRequestAfter(Session oSession) { }


        // Called before the user can edit a response using the Fiddler Inspectors, unless streaming.
        public void AutoTamperResponseBefore(Session oSession) { }


        // Called after the user edited a response using the Fiddler Inspectors.  Not called when streaming.
        public void AutoTamperResponseAfter(Session oSession) { }


        // Called Fiddler returns a self-generated HTTP error (for instance DNS lookup failed, etc)
        public void OnBeforeReturningError(Session oSession) { }
    }
}

2.插件界面部分代码

代码如下(示例):

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace FiddlerExtension
{
    public partial class UserControl1 : UserControl
    {
        private string filter = "";
        private string[] filterArray;
        private bool isBeginFilter = false;
        public UserControl1()
        {
            InitializeComponent();
        }
        public string Filter
        {
            get
            {
                return filter;
            }

            set
            {
                filter = value;
            }
        }
        public string[] FilterArray
        {
            get
            {
                return filterArray;
            }

            set
            {
                filterArray = value;
            }
        }

        private void button1_Click_1(object sender, EventArgs e)
        {
            if (!isBeginFilter) // beginFilter
            {
                isBeginFilter = !isBeginFilter;
                Filter = this.textBox2.Text;
                // 拆分成字符串数组
                FilterArray = Filter.Split('|');
                this.button1.Text = "停止捕获";
            }
            else
            {
                isBeginFilter = !isBeginFilter;
                Filter = "";
                this.button1.Text = "开始捕获";
            }
        }
        private void button2_Click(object sender, EventArgs e)
        {
            // 把当前listview中的数据保存到output.txt中
            if (this.listView1.Items.Count == 0)
            {
                MessageBox.Show("列表为空!");
            }
            else
            {
                List<string> list = new List<string>();
                foreach (ListViewItem item in this.listView1.Items)
                {
                    string temp = item.SubItems[1].Text+"," +item.SubItems[2].Text+","+ item.SubItems[3].Text; // 取pageId,defined_name,defined_value
                    list.Add(temp);
                }
                Thread thexp = new Thread(() => export(list)) { IsBackground = true };
                thexp.Start();
            }
        }
        private void button3_Click(object sender, EventArgs e)
        {
            // 把当前listview中的数据保存到output.txt中
            if (this.listView1.Items.Count == 0)
            {
                MessageBox.Show("列表已空,无需再清空!");
            }
            else
            {
                this.listView1.Items.Clear();
                MessageBox.Show("列表已清空!");
            }
        }
        private void export(List<string> list)
        {
            string path = AppDomain.CurrentDomain.BaseDirectory + "url_" + Guid.NewGuid().ToString() + ".csv";
            StringBuilder sb = new StringBuilder();
            foreach (string urlString in list)
            {
                sb.AppendLine(urlString);
            }
            System.IO.File.WriteAllText(path, sb.ToString(), Encoding.UTF8);
            MessageBox.Show("已保存完毕,路径:" + path);
        }

    }
}


总结

路漫漫,其修远兮。第一次写插件的小记录

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
写一个 Fiddler 插件需要掌握 C# 编程语言和 Fiddler 的 API,下面是一个简单的示例插件: 1. 创建一个类库项目 2. 在项目引用中添加 FiddlerCore.dll 和 Fiddler.dll 3. 在项目中添加一个类,继承自 Fiddler.IAutoTamper ``` using Fiddler; public class MyPlugin : IAutoTamper { public void OnLoad() { // 插件加载时执行的代码 } public void OnBeforeRequest(Session oSession) { // 请求发送前执行的代码 } public void OnBeforeResponse(Session oSession) { // 响应接收前执行的代码 } public void OnAfterSessionComplete(Session oSession) { // 会话结束后执行的代码 } public void OnBeforeReturningError(Session oSession) { // 返回错误前执行的代码 } public void OnUnloaded() { // 插件卸载时执行的代码 } } ``` 4. 实现需要的方法,在这里可以实现自定义的逻辑。例如,可以在 OnBeforeRequest 方法中修改请求头信息: ``` public void OnBeforeRequest(Session oSession) { if (oSession.oRequest.headers.Exists("User-Agent")) { oSession.oRequest.headers.Remove("User-Agent"); } oSession.oRequest.headers.Add("User-Agent", "MyPlugin/1.0"); } ``` 5. 在 Fiddler 中加载插件,具体步骤是:Tools -> Fiddler Options -> Extensions -> Add,选择插件的 .dll 文件,然后点击 OK。 6. 启动 Fiddler插件就会自动加载并开始运行。可以通过 Fiddler 界面的日志窗口查看插件的输出。 这只是一个简单的示例插件,实际上可以根据需要编写更复杂的插件来扩展 Fiddler 的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值