OkHttp PublicSuffix包的后缀列表处理

PublicSuffixDatabase.list 是公共后缀列表(Public Suffix List,PSL)的文件之一,以下是 PublicSuffixDatabase.list 文件及一些常见的开源处理库的介绍:

PublicSuffixDatabase.list 文件

  • 概念 :公共后缀列表是一个包含所有已知公共后缀的列表,它定义了互联网上用户可以注册的域名后缀范围,这些后缀是域名体系中的公共部分,例如.com、.cn、.co.uk 等。
  • 作用 :最初是为了满足浏览器制造商的需求而创建,用于帮助浏览器解决如避免为高级域名后缀设置破坏隐私的"supercookies"、突出显示用户界面中域名最重要的部分、按站点准确排序历史记录条目等问题。现在,它已成为互联网域名管理的一项重要资源,广泛应用于网络安全、域名解析、Cookie 管理等诸多领域。
  • 维护 :由 Mozilla 发起并维护,作为社区资源,由志愿者提交和更新数据,以确保其准确性和时效性。
  • 格式 :它是一个纯文本文件,每行定义一个规则。规则主要分为三类,一类是普通规则,如 ".com" 表示所有以.com 结尾的域名都属于公共后缀;一类是以 "!" 开头的例外规则,用于表示某些特定的域名虽然符合公共后缀的规则,但实际上是可注册的域名,如 "!example.com" 表示 example.com 是一个可注册的域名,而不是公共后缀;还有一类是以 "." 开头的通配符规则,用于表示某个域及其所有子域都属于公共后缀,如 ".example.com" 表示所有以.example.com 结尾的域名都是公共后缀。

开源处理库

以下是部分常见的开源处理库:

PublicSuffixList JavaScript 版本

  • 特性 :提供了一个简单易用的接口,可以快速判断一个域名是否属于公共后缀,并且能够解析域名的各个组成部分,如注册域、子域等。它遵循公共后缀列表的格式和规则,确保了域名解析的准确性和一致性。体积小巧,性能高效,适合在各种 JavaScript 环境中使用,包括浏览器和 Node.js。
  • 安装 :npm install public-suffix-list
  • 使用方法
    • 导入模块:const { PublicSuffixList } = require('public-suffix-list')
    • 创建实例并加载默认的公共后缀列表:const psl = new PublicSuffixList() 或者 const psl = PublicSuffixList.getDefault()
    • 使用方法判断域名是否有效、解析域名等,如 psl.isValid('example.com') 判断域名是否有效,psl.parse('www.example.co.uk') 解析域名结构。

PublicSuffixList Ruby 版本

  • 特性 :提供了丰富的功能,可以方便地判断域名是否符合公共后缀列表规则、解析域名的各个部分等。它具有良好的可读性和可维护性,便于开发者理解和使用。并且,它可以与其他 Ruby 库无缝集成,方便在 Ruby 项目中进行域名处理。
  • 安装 :gem install public_suffix
  • 使用方法
    • 需要先加载公共后缀列表,可以通过 PublicSuffix::List.default 获取默认的列表。
    • 然后可以使用 PublicSuffix::Domain.new(domain, list: list) 创建一个域名对象,进而调用其方法来获取域名的各个部分,如 domain.tld 获取顶级域,domain.sld 获取二级域等。

PublicSuffix Python 版本

  • 特性 :提供了简单易用的 API,可以方便地判断域名是否有效、解析域名的各个组成部分等。它具有良好的兼容性,能够与 Python 的其他网络库和工具无缝配合使用。同时,它的性能也较为出色,能够快速处理大量的域名数据。
  • 安装 :pip install publicsuffixlist
  • 使用方法
    • 导入模块:from publicsuffixlist import PublicSuffixList
    • 创建公共后缀列表对象:psl = PublicSuffixList()
    • 使用方法判断域名是否有效、解析域名等,如 psl.privatesuffix(domain) 判断域名是否为私有后缀,psl.get_public_suffix(domain) 获取域名的公共后缀。

PublicSuffix Go 版本

  • 特性 :具有高性能和高并发处理能力,能够快速处理大量的域名数据。它的代码结构清晰,易于理解和使用,并且提供了丰富的文档和示例,方便开发者快速上手。同时,它也遵循公共后缀列表的最新规范,确保了域名解析的准确性和一致性。
  • 安装 :go get github.com/xeipuuv/go-publicsuffix
  • 使用方法
    • 导入包:import "github.com/xeipuuv/go-publicsuffix"
    • 使用函数如 publicsuffix.List.DomainInfo(domain) 来获取域名的注册管理机构信息,包括注册域、公共后缀等。

PublicSuffix PHP 版本

  • 特性 :提供了一个简单易用的接口,可以方便地判断域名是否符合公共后缀列表规则、解析域名的各个组成部分等。它与 PHP 的其他网络库和工具具有良好的兼容性,能够方便地集成到现有的 PHP 项目中。同时,它的代码也较为简洁,易于维护和扩展。
  • 安装 :通过 Composer 安装,composer require "ிலவு/public-suffix"
  • 使用方法
    • 导入类:use Ilav\PublicSuffix\PublicSuffix;
    • 创建公共后缀对象:$publicSuffix = new PublicSuffix;
    • 使用方法如 $publicSuffix->getPublicSuffix('www.example.com') 获取域名的公共后缀。

OkHttp 的 PublicSuffix 包是一个可以用于处理公共后缀列表的 Kotlin 版本的开源库,其具体介绍如下:

基本情况

OkHttp 是一个流行的 HTTP 客户端库,它提供了对 HTTP 请求和响应的高效处理,而其中的 PublicSuffix 包则是专门用于处理公共后缀相关问题的。

主要功能

  • 域名解析 :可以获取域名的有效顶级域名加一(Effective TLD Plus One),即注册域名,例如对于域名 "www.example.com",其有效顶级域名加一是 "example.com";对于 "shop.example.co.uk",有效顶级域名加一是 "example.co.uk"。
  • 同源策略支持 :帮助确定哪些域名应被视为 "同源",这对于确保网络安全、进行跨域资源共享(CORS)决策等非常重要。
  • 防止安全漏洞 :可阻止潜在的会话固定攻击、减少跨站请求伪造(CSRF)风险等,有助于提高网络应用的安全性。

使用方法

  • 引入库 :在项目中添加 OkHttp 的依赖,即可引入其 PublicSuffix 包。
  • 获取 PublicSuffixDatabase 对象 :通过 PublicSuffixDatabase.get() 方法获取一个 PublicSuffixDatabase 对象。
  • 解析域名 :调用 PublicSuffixDatabase 对象的 getEffectiveTldPlusOne(domain) 方法,传入需要解析的域名,即可得到该域名的有效顶级域名加一。

跨平台设计优势

  • 代码复用与平台特化的平衡 :OkHttp 的 PublicSuffix 包采用了 Kotlin Multiplatform 架构,核心逻辑在共享代码中实现,平台特定代码仅处理资源加载等平台差异,实现了 75% 的代码复用。
  • 统一 API :所有平台使用相同的接口,通过 PublicSuffixList.Default 提供统一访问点,方便开发者在不同平台上以一致的方式使用该库。
  • 可扩展性 :可以轻松添加新平台支持,且平台特定优化不影响其他平台。
  • 维护性 :平台特定代码与通用代码分离,关注点分离,便于维护。
  • 性能优化 :具有延迟加载、并发处理、中断处理等性能优化措施,确保数据只在需要时加载,减少内存占用,并保证数据加载的正确性和效率。

使用示例

使用 OkHttp 中的 PublicSuffix 包来获取域名的有效顶级域名加一的代码示例如下:

kotlin 复制代码
val domain1 = "www.example.com"
val result1 = PublicSuffixDatabase.get().getEffectiveTldPlusOne(domain1)
println(result1) // 输出 example.com

val domain2 = "shop.example.co.uk"
val result2 = PublicSuffixDatabase.get().getEffectiveTldPlusOne(domain2)
println(result2) // 输出 example.co.uk

val domain3 = "com"
val result3 = PublicSuffixDatabase.get().getEffectiveTldPlusOne(domain3)
println(result3) // 输出 null

OkHttp PublicSuffix的后缀列表处理源码分析

1. 整体域名解析流程

此图展示了从输入域名到最终获取有效顶级域名加一级域名(eTLD+1)的完整流程。

流程图

flowchart TD A([开始]) --> B[输入域名] B --> C[转换为 Unicode] C --> D[拆分标签] D --> E[匹配公共后缀规则] E --> F{公共后缀?} F -->|是| G[返回 null] F -->|否| H{异常规则?} H -->|是| I[偏移量=标签数-规则长度] H -->|否| J[偏移量=标签数-规则长度-1] I --> K[拆分原始标签] J --> K K --> L[截取标签] L --> M[拼接 eTLD+1] M --> N[返回结果] G --> O([结束]) N --> O class A,O startend class B,C,D,E,I,J,K,L,M process class F,H decision class G,N result classDef startend fill:#2,stroke:#BE8FED,stroke-width:2px classDef process fill:#5,stroke:#73A6FF,stroke-width:2px classDef decision fill:#6,stroke:#FFBC52,stroke-width:2px,shape:diamond classDef result fill:#8,stroke:#4CAF50,stroke-width:2px

解释

  1. 输入域名后,先将其转换为 Unicode 格式,再拆分成标签列表。
  2. 查找匹配的公共后缀规则,判断该域名是否为公共后缀,若是则直接返回 null
  3. 若不是公共后缀,判断规则是否为异常规则,根据不同情况计算首个标签偏移量。
  4. 按原始域名拆分标签列表,从偏移量位置开始截取标签并连接成字符串,最终返回 eTLD+1。

时序图

sequenceDiagram participant Client participant PublicSuffixDatabase participant PublicSuffixList Client->>PublicSuffixDatabase: getEffectiveTldPlusOne(domain) PublicSuffixDatabase->>PublicSuffixDatabase: 将域名转换为 Unicode PublicSuffixDatabase->>PublicSuffixDatabase: 拆分域名成标签列表 PublicSuffixDatabase->>PublicSuffixDatabase: findMatchingRule(domainLabels) PublicSuffixDatabase->>PublicSuffixList: ensureLoaded() PublicSuffixList-->>PublicSuffixDatabase: 列表已加载 PublicSuffixDatabase->>PublicSuffixList: bytes.binarySearch(...) PublicSuffixList-->>PublicSuffixDatabase: 匹配规则 PublicSuffixDatabase->>PublicSuffixDatabase: 判断域名是否为公共后缀 alt 域名是公共后缀 PublicSuffixDatabase-->>Client: null else 域名不是公共后缀 PublicSuffixDatabase->>PublicSuffixDatabase: 判断规则是否为异常规则 PublicSuffixDatabase->>PublicSuffixDatabase: 计算首个标签偏移量 PublicSuffixDatabase->>PublicSuffixDatabase: 按原始域名拆分标签列表 PublicSuffixDatabase->>PublicSuffixDatabase: 从偏移量位置开始截取标签列表 PublicSuffixDatabase->>PublicSuffixDatabase: 将截取的标签列表用点连接 PublicSuffixDatabase-->>Client: eTLD+1 end

解释

  1. 客户端调用 PublicSuffixDatabasegetEffectiveTldPlusOne 方法。
  2. PublicSuffixDatabase 进行域名转换、拆分标签列表等操作,调用 findMatchingRule 方法查找匹配规则。
  3. findMatchingRule 方法中会调用 PublicSuffixListensureLoaded 方法确保列表已加载,再通过 binarySearch 方法查找匹配规则。
  4. 根据匹配规则判断域名是否为公共后缀,若不是则计算偏移量并处理标签列表,最终将结果返回给客户端。

2. 规则匹配逻辑细节

该图详细展示了查找匹配规则时,精确匹配、通配符匹配和异常匹配的处理顺序。

flowchart TD classDef startend fill:#4,stroke:#BE8FED,stroke-width:2px; classDef process fill:#5,stroke:#73A6FF,stroke-width:2px; classDef decision fill:#6,stroke:#FFBC52,stroke-width:2px; A(开始查找规则):::process --> B(尝试精确匹配):::process B --> C{是否找到精确匹配?}:::decision C -->|是| D(记录精确匹配规则):::process C -->|否| E(尝试通配符匹配):::process D --> F(尝试异常匹配):::process E --> F F --> G{是否找到异常匹配?}:::decision G -->|是| H(使用异常匹配规则):::process G -->|否| I{精确匹配和通配符匹配哪个规则更长?}:::decision I -->|精确匹配长| J(使用精确匹配规则):::process I -->|通配符匹配长| K(使用通配符匹配规则):::process I -->|都未匹配| L(使用默认规则):::process H --> M(结束查找):::process J --> M K --> M L --> M

解释

  • 先进行精确匹配,若找到则记录该规则。
  • 若未找到精确匹配,进行通配符匹配。
  • 不管精确匹配是否成功,都尝试异常匹配。
  • 若找到异常匹配,优先使用该规则;否则比较精确匹配和通配符匹配规则的长度,使用较长的规则;若都未匹配,则使用默认规则。

3. 多段式后缀处理示例

www.example.co.uk 为例,展示如何处理多段式公共后缀。

graph LR classDef box fill:#f9f,stroke:#333,stroke-width:2px,color:#FFF classDef circle fill:#6f0,stroke:#FA0,stroke-width:2px,rx:15px A[[输入域名]]:::box --> B{拆分标签} B --> C{{识别后缀}}:::circle C --> D[计算eTLD+1] D --> E[[example.co.uk]]

解释

  • 输入域名被拆分成标签列表。
  • 查找规则时发现 co.uk 是公共后缀。
  • 根据规则计算出 eTLD+1 为 example.co.uk 并输出。

通过这些图,你可以更直观地理解公共后缀列表处理的核心逻辑和关键步骤。

相关推荐
coderlin_3 小时前
BI布局拖拽 (1) 深入react-gird-layout源码
android·javascript·react.js
2501_915918413 小时前
Fiddler中文版全面评测:功能亮点、使用场景与中文网资源整合指南
android·ios·小程序·https·uni-app·iphone·webview
wen's5 小时前
React Native安卓刘海屏适配终极方案:仅需修改 AndroidManifest.xml!
android·xml·react native
编程乐学6 小时前
网络资源模板--基于Android Studio 实现的聊天App
android·android studio·大作业·移动端开发·安卓移动开发·聊天app
没有了遇见8 小时前
Android 通过 SO 库安全存储敏感数据,解决接口劫持问题
android
hsx6668 小时前
使用一个 RecyclerView 构建复杂多类型布局
android
hsx6668 小时前
利用 onMeasure、onLayout、onDraw 创建自定义 View
android
守城小轩8 小时前
Chromium 136 编译指南 - Android 篇:开发工具安装(三)
android·数据库·redis
whysqwhw8 小时前
OkHttp平台抽象机制分析
android
hsx6669 小时前
Android 内存泄漏避坑
android