fqapp loopback HTTP 适配器实战:如何让 Legado 书源和本机工具共用同一条数据管道

发布时间:2026/10/27 22:17:22
fqapp loopback HTTP 适配器实战:如何让 Legado 书源和本机工具共用同一条数据管道

【免费下载链接】fqapp

内容聚合 Android 客户端:小说/短剧/漫剧/听书/漫画,Flutter UI + 进程内 Rust 核心,无自建服务器、无需 root

项目地址:https://gitcode.com/gh_mirrors/fq/fqapp
点击查看免费下载

fqapp(什锦铺)是一款内容聚合 Android 客户端,覆盖小说、短剧、漫剧、听书、漫画五类内容,采用 Flutter UI + 进程内 Rust 核心的架构,无自建服务器、无需 root。它内置一个 loopback HTTP 适配器,把/api/v1/*只读路由和/src/*缓存资源开放在127.0.0.1:18921,让 Legado 书源、本地工具能直接复用 App 内部的签名、解密与分发管道,不必自己实现任何上游协议。

一条管道、两种入口:fqapp 的 loopback 适配器是什么

fqapp 的所有业务逻辑只有一份实现:Rust 分发器。App 自己走 flutter_rust_bridge 的 FFI 直调;外部客户端则走 loopback HTTP 适配器,两者共用同一个dispatch入口,源码见 rust/src/dispatch.rs 和 rust/src/server.rs。

┌────────────────────────────────────────────┐ │ Flutter App(UI) │ │ ApiClient → BackendTransport │ └───────────────┬────────────────────────────┘ │ flutter_rust_bridge(FFI,进程内) ▼ ┌──────────────────────────┐ │ Rust 核心 fqapi_core │ 签名 · 解密 · 设备池 │ 统一分发器 dispatch │ └──────┬─────────────┬─────┘ │ │ HTTPS 请求上游 loopback │ ▼ 127.0.0.1:18921 上游 API ▼ Legado 书源 / 本机工具 /api/v1/* 只读路由 + /src/* 缓存资源

这个设计带来三个直接好处:

  • 只读复用:Legado 书源无需复刻签名算法(Argus 等)和设备池逻辑,直接拿到归一化 JSON
  • 零部署:不需要自建服务器,不需要 root,端口写死在 assets/config/config.json 的port: 18921
  • 安全分层:读接口对任何本机客户端开放,写接口仍要求每次启动生成的能力值(capability)

如何找到本地接口地址并完成连通性自测

打开 App 后进入「设置 → 服务」,就是本地的 API 控制台(实现见 lib/pages/api_service_page.dart):

  1. 看状态:页面顶部的绿点表示 loopback 服务「运行中」,并显示设备池数量(来自/health)
  2. 抄地址:本机地址形如http://127.0.0.1:18921,点一下即可复制,这是你拼书源 URL 的根地址
  3. 点「自测」:向/health发一次真实请求,成功会提示「通了 · HTTP 200 · N 个设备」

在电脑侧想验证连通性,可以用 ADB 端口转发(文档见 DEVELOPMENT.md 调试技巧一节):

adb forward tcp:18080 tcp:18921 curl http://127.0.0.1:18080/health

返回类似{"status":"ok","devices":3}即说明整条管道就绪。

提示:/health不触达上游、不消耗设备轮换预算,是判断「服务活着没有」最轻量的探针。

Legado 书源可用的 fqapp 接口清单

控制台页面默认收起一份接口参考,展开后列出四条最常用的 GET 路由,完整列表见 DEVELOPMENT.md 的「API 对接说明」:

用途路径说明
搜索/api/v1/search/fanqie?query=关键词关键词搜索,返回归一化条目
详情/api/v1/books/{book_id}书名、作者、简介、封面
目录/api/v1/books/{book_id}/directory章节列表(chapterListWithVolume格式)
正文/api/v1/chapters/{item_id}章节正文与插图

几个对接时值得注意的约定:

  • 响应信封:成功是code=200或code=0,失败为success=false且带error信息
  • { }是变量:book_id、item_id需替换成搜索结果里的实际 ID
  • /src/*静态资源:漫画图片、缓存媒体等走这个前缀,支持 HTTP Range(206 分段),大文件从磁盘流式返回,不占满内存;实现与回归见 rust/tests/static_and_loopback.rs

把 Legado 书源接到 fqapp:3 步配置思路

Legado 书源的核心是把「搜索→详情→目录→正文」四步映射到 HTTP 接口。接 fqapp 的思路非常直接:

  1. 根地址:填设置页复制的本机地址http://127.0.0.1:18921(同一网络其他设备则用下方 LAN 模式给出的http://<手机IP>:18921)
  2. 搜索步:请求/api/v1/search/fanqie?query={{key}},从条目中取 ID 与标题
  3. 目录与正文步:依次请求/api/v1/books/{{id}}/directory与/api/v1/chapters/{{item_id}}

因为路由是纯只读 GET、无参数签名要求,Legado 无需任何特殊头部即可调用;本机工具(脚本、curl、自建聚合页)同理。这也是适配器注释里明确写下的目标场景:「External readers (Legado book sources, local tooling)」。

安全设计:fqapp 如何保证本机 API 不被滥用

loopback 适配器虽然只绑127.0.0.1,但仍实现了完整防护层,全部用例在 rust/tests/loopback_guard.rs 中用真实 socket 回归:

  • Host 守卫:每个请求的Host必须精确指向本监听器(含端口),防止 DNS rebinding——攻击者页面把自己的域名解析到127.0.0.1也读不到响应
  • Origin 守卫:携带Origin的请求必须来自本监听器,挡住跨站表单 POST
  • 读开放、写受控:读路由对任何本机客户端应答;而以设备身份提交动作的写路由(发评论、点赞、段评)仍要求每次启动的能力值,可通过/_session/<token>路径前缀、Authorization: Bearer或会话 Cookie 携带。同机的其他 App 无法冒用你的设备身份发帖
  • 请求体上限:64 MiB,超限直接 413,且逐帧丢弃、不全量缓冲

局域网共享:同一网络的设备怎么读

控制台里有一个「局域网共享」开关。开启后监听器绑定所有网卡,同一 WiFi 下的设备可用http://<手机IP>:18921访问只读路由;页面会列出检测到的局域网地址并附红色提示:无密码、公共 WiFi 建议关闭。守卫在 LAN 模式下改为接受任意 IP 字面量,但域名一律拒绝,DNS rebinding 防护依然生效。

常见问题:fqapp 本地接口连不上或数据异常怎么办

Q:搜索或接口突然失败?内容实时来自上游网站,上游调整或网络波动都会临时影响。fqapp 没有自己的服务器,无法绕过上游变化,过一会儿重试即可。

Q:正文乱码、视频解不开?一般是设备信息过期。清除应用数据后重开会自动重新注册;也可以删除私有目录里的device_pool.json后重启。注意清除数据会同时删除阅读记录与缓存。

Q:403host not allowed是什么意思?请求的Host头没有指向本监听器(端口不对或用了域名)。检查书源根地址是否包含正确端口,且不要使用任何域名形式。

Q:写接口返回 401session required?这是预期行为——发评论、点赞等设备绑定写操作需要 App 内部能力值,外部工具只能使用只读路由。


小结

fqapp 的 loopback HTTP 适配器用一份业务实现同时服务 App 自身与外部生态:Legado 书源、本机脚本共享同一条「签名 → 请求上游 → 解密 → 归一化」的管道,而 Host/Origin 双层守卫和读写分离的能力值机制把安全边界划得很清楚。如果你想把番茄系内容接进自己的阅读器或自动化工具,从「设置 → 服务」复制一个地址、请求一次/health,就是最快的上手路径。

【免费下载链接】fqapp

内容聚合 Android 客户端:小说/短剧/漫剧/听书/漫画,Flutter UI + 进程内 Rust 核心,无自建服务器、无需 root

项目地址:https://gitcode.com/gh_mirrors/fq/fqapp
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考