等了两年,Cloudflare 终于给规则引擎加上了通配符
有些功能不是技术上难而是做对了才算真难。通配符Wildcard匹配就是这样。它的概念简单得不能再简单——用一个*号代表任意内容——但要在一个服务数千万域名的规则引擎里把它做对背后藏着一连串工程上的权衡。2024 年 8 月Cloudflare 在 Ruleset Engine 全系列产品上正式上线了通配符支持并把自研的wildcard库作为开源 crate 发布。这篇文章把这件事从头到尾讲清楚。原文链接https://blog.cloudflare.com/wildcard-rules/wildcard cratehttps://crates.io/crates/wildcard开源仓库https://github.com/cloudflare/wildcard先说通配符是什么通配符模式匹配里*表示匹配任意内容包括空内容。一个单独的模式https://example.com/*/t*st可以同时覆盖https://example.com/en/testhttps://example.com/images/toasthttps://example.com/blog/trust每个*捕获的内容可以用${1}、${2}这样的语法在目标表达式里引用。这在 URL 重定向里尤其有用源 URL 模式https://example.com/*/t*st 目标 URL https://${1}.example.com/t${2}st这条规则会把https://example.com/uk/test重定向到https://uk.example.com/testhttps://example.com/images/toast重定向到https://images.example.com/toast一条规则覆盖无数变体。这就是通配符的价值。没有通配符之前用户有多痛苦Cloudflare 在 2012 年推出的 Page Rules 原生支持通配符匹配。彼时把旧路径重定向到新路径只需要两行配置源 URL https://example.com/old-path/* 目标 URLhttps://example.com/new-path/$12022 年Cloudflare 推出了基于 Ruleset Engine 的 Single Redirects作为 Page Rules URL 转发功能的现代替代品。新产品在性能和表达能力上更强但当时不支持通配符。要在 Single Redirects 里实现同样的旧路径转新路径写法变成了这样过滤条件 (http.host eq example.com and starts_with(http.request.uri.path, /old-path/)) 目标表达式 concat(/new-path/, substring(http.request.uri.path, 10)) // 其中 10 是 /old-path/ 的字符长度需要手动计算对于有正则表达式基础的开发者来说这个写法勉强可以接受。但对于绝大多数用户而言starts_with、substring、concat嵌套起来还要手动数字符串长度——这已经超出了配置规则的认知范畴变成了写代码。用户的反馈持续了两年通配符支持是 Cloudflare Rules 产品收到最多的功能请求之一。这次发布的三个新能力1. 两个新的匹配操作符在 Ruleset Engine 的过滤表达式里新增了两个操作符wildcard大小写不敏感匹配时忽略大小写test和TesT视为相同。行为和老版 Page Rules 一致方便迁移。strict wildcard大小写敏感严格匹配test不等于TesT。这两个操作符可以作用于 Ruleset Engine 里所有的字符串字段包括完整 URI、Host、HTTP 请求头、Cookie、User-Agent、来源国家等。一个典型的 WAF 规则示例——匹配特定 User-Agent 格式的请求http.user_agent wildcard Mozilla/*(*Macintosh; Intel Mac OS*)*Gecko/*Firefox/*这条规则可以匹配所有符合该模式的 Firefox 请求同时忽略大小写差异。2. wildcard_replace() 函数在 Single Redirects 里新增了wildcard_replace()函数允许在重定向目标 URL 里引用通配符匹配到的片段wildcard_replace( http.request.full_uri, https://example.com/*/page/*, https://example.com/products/${1}?page${2} )这一条配置就能把所有符合模式的 URL 动态转换为新格式不需要concat、substring不需要数字符串长度。3. 简化的可视化界面对于不想写函数表达式的用户Cloudflare 在 Single Redirects 的控制台界面里新增了通配符模式入口直接填写源 URL 模式和目标 URL 模式逻辑和 Page Rules 时代完全一致。从视觉上看和 Page Rules 几乎没有学习成本背后运行的是更高性能的 Ruleset Engine。覆盖的产品范围Cache Rules、Compression Rules、Configuration Rules、Custom Errors、Origin Rules、Redirect Rules、Snippets、Transform Rules、WAF、Waiting Room 以及其他基于 Ruleset Engine 的产品全部适用。且对所有套餐用户免费开放。工程实现为什么要自己写一个通配符库Ruleset Engine 核心用 Rust 实现。加入通配符支持时团队首先评估了现有的 Rust crate。为什么不用 regex crateregexcrate 是 Rust 生态里最成熟的正则表达式库。但问题在于通配符模式需要先转换为正则表达式——*转为.*同时还要对其他在正则里有特殊含义的字符做转义处理。这层转换增加了额外复杂度而且引入了通配符语义和正则语义之间不必要的摩擦。为什么不用 wildmatch cratewildmatch是专门为通配符匹配设计的 Rust 库不需要转换为正则也处理了通配符匹配的时间复杂度问题——在最坏情况下是 O(p ℓ s·ℓ)其中 p 是模式长度ℓ 是输入串长度s 是*号的数量。但wildmatch有两个关键限制无法满足需求只支持 UTF-8 字符串Ruleset Engine 需要字节级别的匹配不能假设输入是合法的 UTF-8不支持转义序列用户有时需要匹配字面量的*应该能用\*来表达wildmatch不支持这个还有一个更根本的问题wildcard_replace()函数需要的不只是是否匹配而是匹配到了什么——需要把每个*对应的捕获片段提取出来以便在目标 URL 里替换。wildmatch没有这个能力。自研的选择Kurt 算法 Krauss 优化Cloudflare 最终决定自行实现一个 wildcard crate基于 Kurt 2016 年的迭代算法结合 Krauss 2014 年算法的优化改进。实现支持字节级匹配不限制输入必须是合法 UTF-8转义序列\*表示字面量星号\\表示字面量反斜杠捕获匹配段每个*匹配的子串都可以被提取供wildcard_replace()使用安全设计Ruleset Engine 将单个模式里的*数量上限设为 8 个。这个限制有两层意义一是控制最坏情况下的时间复杂度保证规则执行的性能下界二是防止恶意用户通过构造极端复杂的模式和输入字符串来消耗过量 CPU是一种主动的滥用防护设计。总结这次更新的表面是一个功能发布背后是一次从用户体验出发的完整工程决策链用户反馈 → 找到根本问题规则表达式对普通用户过于复杂→ 评估现有方案两个主流 crate 均不满足→ 自研并开源精确满足需求同时回馈生态→ 在多个产品和所有套餐上同步上线。对于 Cloudflare 的用户最直接的收益是URL 重定向这件事终于可以像十二年前用 Page Rules 一样简单直接地做到同时享受新引擎的性能优势。对于 Rust 开发者wildcardcrate 已经开源字节级匹配、转义支持、捕获组提取可以直接用于任何有类似需求的项目。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2589304.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!