Commit Graph
12 Commits
Author SHA1 Message Date
chenxin 292b8c656f 🧪 test(algos): 新增签名算法 golden 测试
固定输入与时间戳断言 Gorgon/8404/Ladon 输出及 Argus 哈希层。
Go 1.25 起 rand.Seed 默认 no-op,用 //go:debug randseednop=0 钉住随机序列;
Argus 因 protobuf 按 map 迭代序编码无法全量 golden,仅测其确定性哈希。
2026-10-08 13:50:46 +08:00
chenxin 5bcc8a962e ♻️ refactor(handlers): status 与 review 页面模板化
- HTML 提取至 templates/status.html、templates/review.html(go:embed 内嵌)
- status.go 1022→271 行、review.go 1281→438 行,动态数据全部经 html/template 按上下文自动转义
- 评论循环/作者徽章/贴纸/图片条件渲染翻译为模板 range/if;emojiMap 以 template.JS 注入
- 与旧版渲染输出实测对比:22 条评论结构完全一致;差异仅为 JS 上下文安全转义(& 等)与 html/template 剥除 CSS 注释,均无功能影响
- 其余文件为 gofmt 顺手格式化
2026-09-30 00:25:09 +08:00
chenxin ad6d28fd85 ⚡️ perf(media): 音频代理改为流式转发
- downloadMedia 拿到响应头即返回 Body,音频不再全量驻留内存,改由 io.Copy 流式写出
- 重试仅覆盖响应阶段;Body 读取中途失败由客户端自行重试
- 请求头设置提取为 setMediaHeaders 复用;data_uri 模式保持全量读取(本就需驻留内存)
- 漫画代理因需解密后输出,维持原有全量方式
2026-09-30 00:25:09 +08:00
chenxin f89bee8ddc ✨ feat(server): 新增每 IP 请求限流
- 新增 RateLimit 中间件:golang.org/x/time/rate 令牌桶,超出返回 429
- server.rate_limit_qps 配置(默认 0 不限制,突发 10),公网部署建议开启
- 业务路由统一接入 限流 → 鉴权 中间件链;/healthz 与静态资源不限流
- X-Forwarded-For 优先取真实客户端 IP(反代场景),visitor 表定时清理防泄漏
- config.yaml 补齐 protect_all 与 rate_limit_qps 配置项(此前仅存在于代码)
2026-09-30 00:24:58 +08:00
chenxin 8bc6f5c2ae 🐛 fix(search): 按 tab_type 过滤搜索结果
- 上游 search/tab/v/ 固定返回所有 tab 的 search_tabs,此前原样转发导致传 tab_type 仍返回全部结果
- 新增 filterSearchTabs 只保留匹配项,无匹配时保留原样兜底
- 过滤路径用 UseNumber 解析重组,避免 19 位 book_id 经 float64 丢精度;解析失败退回原样转发
- 新增测试:过滤正确性、无匹配兜底、大整数精度保持
2026-09-29 23:54:27 +08:00
chenxin 586b714f3c ✨ feat(cache): 幂等只读接口接入缓存
- 新增 withCache 包装:命中直接返回,miss 回源后写入,仅缓存成功响应
- 详情/目录/批量详情/章节摘要缓存 24 小时;搜索/分类列表/分类详情短缓存 10 分钟
- 7 个 fqapi 处理函数原函数体不动、改名 fetchXxx,外层套缓存壳
- redisGetCache 补 3 秒读超时,与写路径一致,防远程 Redis 网络抖动拖垮请求
- 新增 TestWithCache:验证命中不回源、失败响应不缓存
2026-09-29 23:43:56 +08:00
chenxin f0d89b462b ⚡️ perf(fqapi): 移除缓存层全局串行锁
- 删除 cache_manager/audio_proxy/device_key_pool 中 21 处 cacheMutex:database/sql 连接池本身并发安全,SQLite 已配 WAL + busy_timeout,PostgreSQL 无并发写限制
- contentRequestCount 三函数由互斥锁改为 atomic.Int64
- cache_manager 中 config.GetConfig() 改为 GetAppConfig(),消除配置未初始化时 log.Fatal 崩溃整个进程的隐患
- VACUUM 与写操作的低频并发冲突由 busy_timeout 兜底(已注释说明)
- 新增 TestConcurrentCacheAccess:8 goroutine 并发读写缓存,-race 验证无死锁无竞争
2026-09-29 23:21:10 +08:00
chenxin 24c7e4b6fd 🔒️ security(server): 业务接口保护开关与存活探针
- access_key 改用 subtle.ConstantTimeCompare 常量时间比较,防时序攻击
- 新增 server.protect_all 配置:开启后业务接口(/search、/content 等)也要求访问密钥
- 代理路由(/audio/proxy/、/manga/image/)不参与保护,其 URL 由服务端生成不含 key
- 新增 /healthz 存活探针(不校验密钥,供容器/反代使用)
- openapi.yaml 补 /healthz 定义,Unauthorized 描述说明 protect_all 行为
- 新增 3 个测试:保护开关放行、healthz、错误响应行为
2026-09-29 22:51:39 +08:00
chenxin d1774a3902 🐛 fix(handlers): 统一错误响应为安全 JSON 并补参数校验
- 新增 respondError:JSON 安全编码,客户端错误返回 400,服务端错误返回 500
- 收编 book/content/media/category 中 13 处 fmt.Fprintf 内联 JSON,修复错误信息含引号/换行时产出非法 JSON 的问题
- search/detail/catalog/multi-detail/content/multi-content/item-summary/audio/video 补必需参数校验,缺参返回 400
- search 的 offset/tab_type 非数字时返回 400,不再静默置 0
- 补齐 multi-detail/multi-content 的请求统计计数
- 新增 error_response_test.go:3 个测试锁定错误响应行为
- openapi.yaml 新增 ServerError 响应组件,15 个业务接口补 400/500 响应定义

BREAKING CHANGE: 业务接口错误不再返回 HTTP 200,缺参返回 400,上游失败返回 500
2026-09-29 22:47:01 +08:00
chenxin 1eccebedf9 ✨ feat(cache): 新增 Redis 缓存与 PostgreSQL 后端支持
- 新增 cache.redis 配置(独立 host/port/password/db 字段),启用后正文缓存与音频代理缓存走 Redis,键前缀 fq:cache:/fq:audio:,TTL 自动过期
- 新增 cache.backend: sqlite|postgres 切换,PG 连接用 net/url 构造 DSN,密码特殊字符自动转义;SQLite 顺手启用 WAL 与 busy_timeout
- SQL 方言收敛:q() 将 ? 占位符转换为 $n、INSERT OR IGNORE 与查询再插入统一为 ON CONFLICT、LastInsertId 改为 RETURNING id、建表 DDL 双版本分派
- PG 下 VACUUM 走 autovacuum 说明、状态页大小改查 pg_database_size
- 修复 PG 下设备保存失败:is_valid 列为 INTEGER,写入点补 boolToInt 转换
- 新增 .env 支持:敏感配置(密码/主机/访问密钥)由环境变量覆盖 config.yaml,.env 进 gitignore,仓库附 .env.example 模板
- 新增 openapi.yaml(OpenAPI 3.1):覆盖全部 24 个路径,含参数、响应结构与鉴权方案,README 增加指引
- 删除死代码 InitDevicePoolTable;新增 rebind_test.go 单测
- 更新 README 与 config.yaml 配置示例,go.mod 新增 go-redis/v9 与 pgx/v5 依赖
2026-09-29 20:33:37 +08:00
chenxin d710d382ee 🐛 fix(server): 增加优雅退出与请求超时保护
- 新增 SIGINT/SIGTERM 信号处理与 http.Server.Shutdown,退出前确保统计数据保存、数据库正常关闭
- 为 http.Server 设置 ReadHeaderTimeout/ReadTimeout/WriteTimeout/IdleTimeout,防止慢客户端长期占用连接
- 全局配置指针改为 atomic.Pointer 并提供 GetAppConfig 访问器,消除配置热更新时的数据竞争,同时删除冗余的 manager.config 字段
- 请求统计九组计数器重构为 map[string]*atomic.Int64,统一 incrementStat/getStatsSnapshot 访问,精简约 40 行样板代码
- go mod tidy 清理 go.mod 与 go.sum 中的冗余依赖条目
2026-09-29 19:47:04 +08:00
chenxin 6981148727 🔧 chore: 初始化番茄小说 API 项目结构
新增项目基础框架,包含核心 API 实现、算法模块、HTTP 处理器等完整功能模块
2026-08-28 15:22:22 +08:00