Fulguris广告拦截源码深度剖析:ABP过滤器匹配引擎完整指南

发布时间:2026/10/11 18:44:17

Fulguris广告拦截源码深度剖析:ABP过滤器匹配引擎完整指南 Fulguris广告拦截源码深度剖析ABP过滤器匹配引擎完整指南【免费下载链接】Fulguris⚡Web Browser项目地址: https://gitcode.com/gh_mirrors/fu/FulgurisFulguris 是一款极致轻量的开源 Android 浏览器它的广告拦截能力完全构建在 ABPAdblock Plus过滤器语法之上。这篇文章将带你深入 Fulguris 源码拆解从网络请求拦截到过滤器匹配引擎的完整链路为什么它能毫秒级判定一个请求是广告被拦截的广告又是怎么被空资源替换的即使你从未读过 Kotlin也能看懂这套匹配引擎的设计精髓。Fulguris 广告拦截模块整体架构广告拦截的全部代码集中在两个包中模块路径职责拦截管理器AbpBlockerManager.kt请求入口、第三方检测、响应生成判定引擎AbpBlocker.kt五级优先级决策链用户规则AbpUserRules.kt类似 uBo 的动态过滤列表更新AbpListUpdater.kt下载/解析 EasyList 等过滤列表匹配引擎FilterContainer.kt标签索引 域名哈希查找统一过滤器UnifiedFilter.kt内容类型/第三方/域名三重校验匹配引擎部分源自 Yuzu 浏览器并做了深度优化位于app/src/main/java/jp/hazuki/yuzubrowser/adblock/目录。第一关拦截每一个网络请求一切从AdBlocker接口开始。AdBlocker.kt 只定义了一个方法shouldBlock(request, pageUrl)——浏览器每发起一个资源请求都会先问它这个请求能放行吗AbpBlockerManager.kt 的shouldBlock做了三件关键事白名单短路特殊 URL、应用内 scheme、favicon 缓存目录直接放行不进入匹配流程构造ContentRequest把原生请求包装成引擎能理解的结构包含 URL、页面主机、内容类型位掩码、第三方标志第三方判定用 PublicSuffix 公共后缀库比较两个域名的 effective TLD1 是否相同结果放入容量 100 的 LRU 缓存避免重复计算内容类型用位运算表示定义在 ContentRequest.kt脚本是0x02、图片是0x04、文档是0x20……多个类型可以用or组合一次位与运算就能判定类型是否命中。第二关ABP 过滤器匹配引擎如何工作引擎的核心是FilterContainer——一个按标签分桶的哈希表。每条 ABP 过滤器加载时会由 Tag 类 根据模式生成最优标签纯域名过滤器标签就是域名本身同标签的过滤器用next指针串成链表。匹配时 FilterContainer.get 分两条快速路径域名链查找从请求域名的完整形式逐级向上截取ads.example.com→example.com→com每一级只做哈希表 O(1) 查找——这正是||example.com^这类规则秒判的秘诀标签桶遍历若容器混有非域名规则再按请求 URL 生成的标签集合遍历对应桶命中候选过滤器后UnifiedFilter.isMatch 执行三重短路校验contentType and request.type位与运算——类型不符直接返回 falsecheckThird——是否匹配第一方/第三方约束checkDomain——页面域名是否在过滤器的域名白/黑名单内全部通过才比对 URL 模式忽略大小写的规则会预先小写化 URL避免运行时重复转换。此外容器还维护一个domainOnly标志纯域名列表可以跳过标签遍历源码注释标明这让加载提速 20–50%。第三关五级优先级的决策链AbpBlocker.shouldBlock 是整条链路的大脑判定顺序严格遵循 ABP 规范用户规则 → important白名单 → important拦截 → 普通白名单 → 普通拦截 → 修改过滤器各桶的文件前缀定义在 AbpUtils.ktb_拦截、w_白名单、i_/ia_important 拦截/放行、m_/me_修改/修改例外以及r_/re_重定向。其中有个容易忽略的细节important 拦截会被页面级例外规则否决第 30–35 行这与 AdGuard 官方文档的行为保持一致。而用户规则拥有最高优先级——AbpUserRules.kt 实现了 uBo 风格的动态过滤每条规则就是一个独立过滤器以页面主机作为标签实现只在这个网站屏蔽这个域名的精细控制。第四关被拦截的请求去哪了拦截不等于拒绝而是资源替换。AbpBlockerManager.kt 按内容类型返回不同的空包图片 → 1x1 透明 gif脚本 → 空noop.js媒体 → 静音的noop-0.1s.mp3iframe → 空noop.html这些占位资源存放在app/src/main/assets/blocker_resources/BlockerResponse.kt 还支持把 Google Analytics、Chartbeat 等追踪脚本重定向到对应的解毒空脚本。若是主框架整个页面被拦则生成一个自带样式的说明页展示被拦 URL 和拦截原因恶意软件列表/广告列表/用户规则见 createMainFrameDummy。进阶能力修改过滤器与列表自动更新修改过滤器能做的不止拦截。removeparam可以剥离 URL 中的追踪参数如 Facebook 的fbclid$header系列可以增删请求/响应头。当 ModifyResponse 生效时浏览器会用 OkHttp 重新发起修改后的请求——因为WebResourceRequest本身不可变只能代理转发。过滤列表更新由 AbpListUpdater.kt 负责用If-Modified-Since头做增量检查服务器返回 304 即跳过下载尊重仅 Wi-Fi 更新设置流量计费网络不自动更新列表若不是 ABP 格式自动回退到 HostsFileParser 解析 hosts 文件加载时用bf_badfilter 前缀清洗误杀规则并把各列表合并去重成联合列表避免每次请求重复扫描多个文件总结这套广告拦截引擎值得学什么位掩码代替 if-else内容类型、第三方属性全部用整数位运算判定成本趋近于零哈希分桶 域名链纯域名规则只需几次哈希查找这是大规模列表仍保持流畅的关键五级决策链用户规则 important 白名单 黑名单语义清晰且易于扩展资源替换而非粗暴拒绝按类型返回占位资源页面布局不会塌陷从 AbpBlockerManager.kt 的请求入口到 FilterContainer.kt 的匹配核心Fulguris 用不到千行代码实现了一个教科书级的 ABP 过滤引擎——对想理解浏览器广告拦截原理的你来说这是绝佳的学习样本。【免费下载链接】Fulguris⚡Web Browser项目地址: https://gitcode.com/gh_mirrors/fu/Fulguris创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/10/11 18:43:31

SpringBoot汽车租赁系统开发实战:从数据库设计到并发控制

1. 项目定位与整体设计思路 1.1 毕业设计题目的核心需求拆解 先把这个题目的关键词掰开揉碎。汽车租赁系统的设计与实现,本质上是要你从零搭建一套能跑的完整业务系统,不是写个CRUD Demo交差。评委和导师真正想看的是你对业务流程的理解、对技术栈的把控…

2026/10/11 18:43:31

C#实现零配置网络:链路本地地址与mDNS服务发现

简介:ZeroConfiOS是一个面向C#开发者、聚焦网络服务自动化部署的开源工具库,专为解决动态网络环境下服务发布与IP地址自适应分配难题而设计,适用于物联网设备、跨平台微服务及多网卡终端场景。资源包共43个文件,以32个C#源码文件&…

2026/10/11 18:43:31

800G以太网规格深度解读:PAM4、RS-FEC与多通道对齐实战

1. 从一张规格书说起:800G以太网到底在解决什么问题第一次拿到 800G 以太网规格文档的时候,我盯着那几十页的表格和状态机图看了整整一个下午。说实话,单看标题会觉得这不过是一份"速率翻倍"的升级说明,但真正读进去才发…

2026/10/11 18:43:31

概率统计公式实战手册:面向工程师的可执行公式集

简介:本资源是一份系统、精炼的概率论与数理统计核心公式汇编文档,面向高校数学、统计、计算机及相关专业本科生与考研学生,解决课程复习、考前速记与公式快速检索等实际需求。文档以清晰逻辑分章组织,覆盖随机事件与概率基础&…

2026/10/11 18:43:31

JIRA Scrum敏捷项目管理:看板搭建与Sprint执行全流程

简介:基于JIRA的敏捷开发项目管理是一份面向项目经理、Scrum Master及开发团队成员的实操型文档,系统讲解如何借助JIRA落地Scrum增量迭代流程。内容围绕Scrum的角色分工(产品负责人、Scrum Master、开发测试团队)与五步开发法展开…

2026/10/11 18:38:30

PyQt5+OpenPose太极拳姿态识别系统实战指南

简介:这是一套面向Python初学者与计算机视觉爱好者的太极拳姿态识别实践项目,聚焦运动分析与人机交互场景,助力武术教学数字化与动作规范性评估。资源包含115个文件,以13个核心Python脚本(如ProcessImage.py姿态提取、…

2026/10/11 0:02:13

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/11 0:02:13

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/11 0:02:13

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

2026/10/11 0:02:13

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/11 0:02:13

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/11 0:02:13

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑