Lightbeam的心脏:一个HTTP请求如何从Firefox事件捕获变成图谱上的一个节点
【免费下载链接】lightbeamOrignal unmaintained version of the Lightbeam extension. See lightbeam-we for the new one which works in modern versions of Firefox.项目地址: https://gitcode.com/gh_mirrors/li/lightbeam
Lightbeam 是一款面向 Firefox 的开源浏览器扩展,它能将你在网上浏览时产生的每一次跨站 HTTP 请求,实时可视化成一张「网站追踪图谱」。本文将带你深入它的心脏:看看一个普通的 HTTP 请求,是如何从 Firefox 的事件总线一路流转、被清洗成结构化数据,最终变成图谱上一个可点击、可封禁的节点的。
第一步:在 Firefox 的「事件总线」上搭起听诊器
Lightbeam 的心脏只有几行代码,它注册了 Firefox 的网络事件http-on-examine-response——每当一个 HTTP 响应完成,扩展就会被唤醒:
"This is the heart of Lightbeam, we get all of our data from observing these requests."
这句话就写在 lib/main.js 的源码注释里。扩展在这里把原始请求对象(channel)交给Connection.fromSubject()解析,解析成功就记录一条连接、并向界面页面广播消息。
第二步:把原始请求「洗」成一个 Connection 对象
原始的浏览器请求对象很「毛糙」,lib/connection.js 负责把它清洗成一个干净、可序列化的Connection 对象。它做了四件关键的事:
- 提取域名:借助 Firefox 的 eTLD 服务,从
ads.example.com这类地址中提取出基础域名example.com,让同一公司旗下的子域名归为同一个站点; - 判断首/三方:比较「你正在访问的页面域名」和「请求目标域名」,判定这是一次你自己点的访问,还是一次背后悄悄发出的第三方追踪请求;
- 打上标签:是否携带 Cookie、是否 HTTPS、请求方法、状态码、内容类型……一共15 个字段(见 lib/connection.js 中的字段常量);
- 过滤噪声:
localhost、插件自身的请求、无所属标签页的请求等,都会被标记为无效并丢弃。
字段顺序在 doc/data_format.v1.2.md 中有完整定义,每条连接本质上是一个 14 元组,紧凑得像一行数据库记录。
第三步:跨进程通信,把数据递到界面手里
插件逻辑运行在浏览器后台进程,而图谱界面是一个普通的网页标签页,两者不能直接共享内存。Lightbeam 通过 Mozilla Add-on SDK 的page-mod + port 消息通道解决:
- 后台一侧:lib/ui.js 的
emitForWorker()把连接数据通过 port 发出; - 界面一侧:data/content-script.js 监听
connection事件,把新连接推入allConnections并触发聚合更新。
这套机制还承担了历史数据回传(passStoredConnections)、封禁名单同步(update-blocklist)等任务,是插件与 UI 之间的唯一数据管道。
第四步:从「连接」到「图谱节点」的聚合
一条连接只是「某一刻发生的一次请求」,而图谱需要的是带时间跨度的节点和边。data/aggregate.js 中的onConnection()函数是聚合中枢:
- 节点复用:用
nodemap按域名缓存GraphNode,同一个站点无论出现多少次,在图上永远只有一个节点,新连接只是更新它的firstAccess/lastAccess、Cookie 计数等内容; - 边的合并:
edgemap以「源->目标」为键合并重复边; - 角色判定:根据访问次数占比,给节点打上
site(你访问的站点)、thirdparty(纯追踪方)或both标签,并更新顶栏的统计数字。
第五步:D3 力导向布局,让节点「活」起来
最后登场的是 data/graph.js,它把聚合好的节点和边交给 D3 的d3.layout.force()力导向布局:节点之间互相排斥、被边拉紧,经过几十毫秒的「模拟退火」后,站点关系网自然舒展开来——连接越多的节点(比如大型广告追踪公司)会被更多力拉扯、居于更显著的位置。每来一条新连接,模拟就会重新加热(reheat),图谱随之动态生长。
数据的归宿:本地存储与隐私设计
被捕获的连接并不会无限膨胀。lib/connection.js 采用「批量缓冲」策略:每积累 200 条或每 5 分钟,就把连接写入 lib/persist.js 管理的本地 simple-storage;当存储接近配额上限时,自动丢弃最旧的一半记录。此外,隐私窗口中的连接只可视化、不落盘(见 lib/connection.js)。
小结
回顾这条数据流水线,正是它让 Lightbeam 成为隐私研究者的利器:
HTTP响应 → http-on-examine-response 事件 → Connection 对象(15字段) → port 消息 → GraphNode/GraphEdge 聚合 → D3 力导向图谱从一次毫秒级的网络事件,到屏幕上缓缓成型的追踪网络,每一步都有清晰的分工:事件捕获、数据清洗、跨进程通信、图聚合、可视化渲染。理解了这条管线,你也就掌握了 Lightbeam 的心脏跳动方式。
📌 想动手研究?可以重点阅读 lib/main.js(事件捕获)、lib/connection.js(数据清洗)与 data/aggregate.js(图聚合)这三个文件,它们加起来不到 1000 行,却覆盖了 Lightbeam 的全部核心逻辑。
【免费下载链接】lightbeamOrignal unmaintained version of the Lightbeam extension. See lightbeam-we for the new one which works in modern versions of Firefox.项目地址: https://gitcode.com/gh_mirrors/li/lightbeam
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考