源站与路由架构
R2/B2 双源站、GoEdge CDN 路由规则、TypeD 鉴权与 /res/ /web-res/ 分流机制
源站架构
标清和高清漫画资源存储在不同的对象存储服务中,目录结构一致:
┌─────────────────────────────────────────────┐
│ Cloudflare R2(标清源站) │
│ Bucket: xifanmanga │
│ 路径: /res/{pinyin_name}/{chapter}/{page} │
│ 用于: cdn.hanabimanga.top │
└─────────────────────────────────────────────┘
┌─────────────────────────────────────────────┐
│ Backblaze B2(高清源站) │
│ Bucket: hanabimg │
│ 路径: /res/{pinyin_name}/{chapter}/{page} │
│ 用于: premium.hanabimanga.top │
└─────────────────────────────────────────────┘两个源站均为私有存储,不开放公网直接访问。GoEdge CDN 通过 S3 兼容协议回源,使用各自的 Access Key 认证。
目录结构
{bucket}/
└── res/
└── {pinyin_name}/ ← 漫画拼音名(如 one-piece)
└── {chapter_folder}/ ← 章节目录(如 chapter_042)
├── 001.webp
├── 002.webp
├── 003.webp
└── ...标清和高清是同一部漫画的不同版本,目录结构完全一致。区别在于图片分辨率和质量。标清资源量更大、覆盖更全;高清资源面向 VIP 用户。
GoEdge CDN
项目使用 GoEdge 作为 CDN 平台,负责缓存、鉴权和请求路由。
域名映射
| CDN 域名 | 源站 | 回源协议 | 对应函数 |
|---|---|---|---|
cdn.hanabimanga.top | R2 xifanmanga | S3 | sd-image-url |
premium.hanabimanga.top | B2 hanabimg | S3 | vip-image-url |
TypeD 鉴权
GoEdge 配置了 TypeD 鉴权模式,CDN 节点在返回资源前会校验 URL 中的签名参数:
https://cdn.hanabimanga.top/res/one-piece/chapter_042/001.webp?sign={md5}&t={timestamp}签名算法:
sign = MD5( filePath + "@" + timestamp + "@" + GOEDGE_SIGN_SECRET )filePath:资源路径(如/res/one-piece/chapter_042/001.webp)timestamp:Unix 毫秒时间戳GOEDGE_SIGN_SECRET:CDN 与 Edge Function 共享的签名密钥
签名不匹配或过期的请求会被 CDN 直接拒绝(返回 403),不会回源。
签名由 Edge Function 生成,客户端不参与签名计算。客户端只需使用 Edge Function 返回的完整 URL。鉴权签名的生成逻辑详见 image-url 文档。
路由规则:/res/ 与 /web-res/
GoEdge 通过路由规则对 /res/ 和 /web-res/ 两个路径前缀进行不同处理。
路径决策
路径选择发生在 Edge Function 中,依据客户端签名验证结果:
| 签名验证结果 | 路径前缀 | 含义 |
|---|---|---|
| 通过(真实客户端) | /res/ | 原始图片 |
| 失败(爬虫/伪造请求) | /web-res/ | 混淆图片 |
/res/ — 原始资源
/res/{pinyin_name}/{chapter_folder}/{page}.webp
→ GoEdge 路由到源站的 res/ 目录
→ 返回未处理的原始漫画图片直接对应源站存储路径,1:1 映射。
/web-res/ — 混淆资源
/web-res/{pinyin_name}/{chapter_folder}/{page}.webp
→ GoEdge 路由规则将 /web-res/ 映射到源站对应的混淆资源目录
→ 返回经过网格切片重排的图片/web-res/ 路径下的图片经过预处理:将原图按 4×4 网格切片后打乱重排。爬虫直接下载只能得到打乱的图片。合法的 Web 前端可以使用 Edge Function 返回的 scrambleInfo(seed、gridX、gridY)在 Canvas 上还原。
/web-res/ 和 /res/ 两套资源都存储在源站上,由上传工具在上传原始图片时同时生成混淆版本。GoEdge 只做路由转发,不做图片处理。
完整请求链路
┌──────────┐ ①POST ┌──────────────────────┐
│ 客户端 │ ───────→ │ Edge Function │
│ │ ←─────── │ (sd/vip-image-url) │
└──────────┘ URL列表 │ · 权限验证 │
│ │ · 签名验证 → /res/ │
│ │ 或 /web-res/ │
│ │ · 生成 CDN 签名 URL │
│ └──────────────────────┘
│
│ ②GET 图片(带 sign + t 参数)
▼
┌──────────────────────────────────┐
│ GoEdge CDN │
│ · TypeD 鉴权(校验 sign + t) │
│ · 路由匹配: │
│ /res/ → 源站 res/ 目录 │
│ /web-res/ → 源站混淆资源 │
│ · 缓存命中 → 直接返回 │
│ · 缓存未命中 ↓ │
└──────────┬───────────────────────┘
│ S3 协议回源
┌─────┴──────┐
▼ ▼
┌─────────┐ ┌─────────┐
│ R2 │ │ B2 │
│ 标清源站 │ │ 高清源站 │
└─────────┘ └─────────┘源站回源配置
| 配置项 | 值 |
|---|---|
| 协议 | S3 |
| Endpoint | https://{account_id}.r2.cloudflarestorage.com |
| Bucket | xifanmanga |
| Region | auto |
| 认证 | R2 API Token(Access Key + Secret Key) |
| 配置项 | 值 |
|---|---|
| 协议 | S3 |
| Endpoint | https://s3.{region}.backblazeb2.com |
| Bucket | hanabimg |
| Region | 按实际配置 |
| 认证 | B2 Application Key(keyID + applicationKey) |
回源凭证配置在 GoEdge 管理面板中,不在代码仓库中。变更凭证时需同步更新 GoEdge 配置。
与 Edge Function 的职责划分
CDN 层只负责缓存、鉴权校验和回源,不做任何业务决策:
| 职责 | 由谁负责 |
|---|---|
| 用户权限、VIP 检查、配额控制 | Edge Function |
| 客户端签名验证 → 选择 /res/ 或 /web-res/ | Edge Function |
| CDN URL 签名(sign + t)生成 | Edge Function |
| URL 签名校验(TypeD 鉴权) | GoEdge CDN |
| 路由规则(/res/ vs /web-res/ 分流) | GoEdge CDN |
| 缓存管理与回源 | GoEdge CDN |
| 图片存储 | R2 / B2 |
详细的 Edge Function 逻辑见 sd-image-url / vip-image-url 文档。