Skip to content

fix(QQwTool): 改用 POST JSON API 解析 QQ 邮箱云盘链接#188

Merged
qaiu merged 94 commits into
qaiu:mainfrom
yukaidi1220:fix/qqwtool-json-api
May 29, 2026
Merged

fix(QQwTool): 改用 POST JSON API 解析 QQ 邮箱云盘链接#188
qaiu merged 94 commits into
qaiu:mainfrom
yukaidi1220:fix/qqwtool-json-api

Conversation

@yukaidi1220
Copy link
Copy Markdown
Contributor

问题

QQwTool 旧实现通过 GET 请求获取 HTML 并正则提取 JS var 声明来解析文件信息,但 QQ 邮箱云盘接口已改为返回 JSON,导致所有字段为 null,触发 NumberFormatException: Cannot parse null string

修复

改为 POST 请求 https://wx.mail.qq.com/s,body 为 f=json&k={shareKey},解析 JSON 响应:

  • head.ret 校验状态码
  • body.url / body.name / body.size 提取文件信息
  • 使用 postAbs() 正确处理 HTTPS
  • 使用 asJson() 兼容 gzip 响应
  • 使用 complete() 正确存储 downloadUrl
  • 添加 User-Agent 请求头
  • shareKey 做 URL 编码

JarFile 在手动 close() 时若中间抛异常会导致文件句柄未关闭,
改为 try-with-resources 确保无论正常或异常都能释放资源。
日志列表 Collections.synchronizedList 无容量限制,长时间运行会无界增长。
新增 addLog() 方法,在添加前检查容量,超过 1000 条时移除最早的条目。
readConfig() 中 onSuccess 回调未关闭 ConfigRetriever,
文件监听器和底层资源无法释放,现在成功和失败路径均调用 close()。
Router 声明为 static final 会在类加载时提前创建,
与 Vert.x 实例生命周期不匹配,改为在 start() 中初始化为实例字段。
…vent loop

sayOk() 中使用 Thread.sleep(4000) 会阻塞 Vert.x event loop 线程,
改为 vertx.setTimer 异步延迟完成 promise。
…重复创建

CacheManager 和 ServerApi 无请求级状态,每次 new 会造成不必要的对象分配,
改为 static final 字段复用;同时修复 viewURL 中内联 new ServerApi()。
- HttpProxyVerticle: err.printStackTrace() / e.printStackTrace() -> LOGGER.error()
- RouterHandlerFactory: 5处 printStackTrace() -> LOGGER.error()
- CommonUtil: e.printStackTrace() -> LOGGER.error()
- ReflectionUtil: 新增 LOGGER,3处 printStackTrace() -> LOGGER.error()
- CreateDatabase: e.printStackTrace() -> LOGGER.error()
- URLUtil: 新增 LOGGER,e.printStackTrace() -> LOGGER.error()
- LzTool: e.printStackTrace() -> log.error()
- MkwTool: 3处 System.out.println + 1处 printStackTrace -> log.debug()/log.error()
- PdbTool: e.printStackTrace() -> log.error()
- ParserApi: t.printStackTrace() -> log.error()
- CacheManager: 2处 Throwable::printStackTrace -> LOGGER.error()
- QQTool: 3处 System.out.println -> log.debug()
- FjTool: System.out.println -> log.debug()
去掉 USER appuser,entrypoint 以 root 身份运行,先 chown 修复
volume 挂载目录的权限,再通过 su 降权到 appuser 执行应用。
审查发现:
- EXPOSE 6400 误导用户映射后端端口,实际只需 6401(反向代理)
- TZ 环境变量不如 JVM -Duser.timezone 可靠
Home.vue、Playground.vue、parser/pom.xml 中的 qaiu/netdisk-fast-download
URL 全部替换为 yukaidi1220/netdisk-fast-download。
matcher.group(PWD) 在正则未定义 PWD 命名组时抛出
IllegalArgumentException 而非 IllegalStateException,原 catch 未覆盖
导致无提取码的链接(如QQ文件分享)返回 500。
前端:vue.config.js 通过 DefinePlugin 注入 VUE_APP_GITHUB_REPO_URL,
Home.vue/Playground.vue 中硬编码的 GitHub URL 全部改为动态变量。
后端:parser/pom.xml 添加 gmavenplus-plugin 在 initialize 阶段从
git remote origin 解析 github.owner/github.repo,SCM 字段引用 property。
RouterHandlerFactory 的 onFailure 和 catch 两处均丢弃了
e.getMessage(),导致前端无法获知具体报错原因。
项目版本(pom.xml revision)和parser版本(parserVersion)统一为单一来源,
前端构建时自动同步,发版只需改根pom.xml的两个属性。
- app-dev.yml 注释掉默认 domainName
- ParserApi 添加 getLinkPrefix() 支持 X-Forwarded-Host 反向代理
- ServerApi 传递 _requestOrigin 到 otherParam 供 parser 层使用
- URLParamUtil.addParam() 读不到配置时用 _requestOrigin 兜底
- AppMain 启动日志 domainName 为空时显示本地端口地址
- ServerApi 添加 resolveOrigin() 统一处理 X-Forwarded-Host 头
- ParserApi.parse() 补设 _requestOrigin,修复 /v2/linkInfo 路径遗漏
- 清理 app-dev.yml 残留注释
- clientLinks 无 auth 时调用 URLParamUtil.addParam() 注入代理/认证配置
- clientLink 补设 _requestOrigin 并调用 addParam()
- getFileList/getFileDownUrl 补设 _requestOrigin 保持一致性
- getDownLink 回退地址补上端口号
当 app.yml 在当前目录不存在时,自动回退到 resources/app.yml,
解决 Docker 部署时配置文件在 resources/ 子目录导致启动失败的问题。
当文件系统直接读取 app.yml 失败时(如 Docker 卷挂载场景),
ConfigUtil.readConfig 现在会自动尝试 resources/ 子目录作为
fallback,确保配置文件在各种部署方式下都能被正确加载。
- fix: Home.vue 组件名 'App' → 'Home'
- fix: DirectoryTree selectAll 补 parserUrl 空值检查
- fix: 提取 previewBaseUrl 到 utils/constants.js,解除 ShowFile 对 Home 的耦合
- fix: Home.vue focus 事件监听器改为命名函数,加 beforeUnmount 移除
- fix: Playground.vue MutationObserver 保存引用,onUnmounted 中 disconnect
- chore: 删除未使用的 api.js
- chore: 删除 ClientLinks.vue 死代码 downloadClient/shouldShowDownloadButton
- chore: 删除 DirectoryTree.vue 死代码 buildTree
- 前端 axios 对 HTTP 非2xx直接reject,catch块丢失后端错误信息,从 error.response.data.msg 提取实际错误展示给用户

- QQscTool extractFilesetId 正则未适配 Nuxt 转义JSON格式
旧实现通过 GET 请求获取 HTML 并正则提取 JS 变量,但接口已改为返回 JSON,
导致 NumberFormatException。改为 POST 请求 `https://wx.mail.qq.com/s`,
body 为 `f=json&k={shareKey}`,解析 JSON 响应中的 body.url/name/size。

- 使用 postAbs() 替代 request() 以正确处理 HTTPS
- 使用 asJson() 兼容 gzip 响应
- 使用 complete() 正确存储 downloadUrl
- 添加 User-Agent、URL 编码 shareKey
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates parser behavior and broad supporting infrastructure, centered on replacing QQ 邮箱云盘 parsing with the new POST JSON API, while also applying frontend, Docker, logging, config, and dependency maintenance changes.

Changes:

  • Reworked QQ-related parser behavior, especially QQ 邮箱云盘 and QQ 闪传 handling.
  • Added request-origin/domain fallback handling, safer logging/error output, and frontend UX/security refinements.
  • Updated build/runtime packaging, dependency versions, tests, and documentation version references.

Reviewed changes

Copilot reviewed 78 out of 80 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
parser/src/main/java/cn/qaiu/parser/impl/QQwTool.java Switches QQ 邮箱云盘 parsing to POST JSON API.
parser/src/main/java/cn/qaiu/parser/impl/QQscTool.java Adds QQ 闪传 file-list and directory parsing support.
web-service/src/main/java/cn/qaiu/lz/web/controller/ParserApi.java Adds request-origin-derived link generation.
web-service/src/main/java/cn/qaiu/lz/web/controller/ServerApi.java Passes request origin into parser parameters.
web-service/src/main/java/cn/qaiu/lz/common/util/URLParamUtil.java Falls back to request origin for domain names.
web-service/src/main/java/cn/qaiu/lz/web/service/impl/UserServiceImpl.java Adjusts authentication/user error messages.
Dockerfile Updates container entrypoint and runtime layout.
docker-entrypoint.sh Adds direct Java container startup script.
web-front/src/views/Home.vue Adds dynamic repo/version display and paste/error UX updates.
web-front/src/components/DirectoryTree.vue Adds direct-link copy support and clearer errors.
pom.xml / parser/pom.xml Centralizes parser version and bumps dependencies.
Other changed Java/Vue/docs files Mostly logging cleanup, safer comparisons, lifecycle cleanup, and documentation/version updates.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docker-entrypoint.sh

# Run Java directly - entrypoint is PID 1, exec makes Java PID 1
# Docker SIGTERM goes directly to Java, triggering ShutdownHook
exec java -Xmx${JVM_XMX:-512M} ${JVM_OPTS} -Duser.timezone=${TZ:-Asia/Shanghai} -jar /app/netdisk-fast-download.jar
.put("sort_order", 0)))))
.put("support_folder_status", true);

MultiMap headers = GET_FILE_LIST_HEADERS.set("Referer", shareLinkInfo.getShareUrl());
.onSuccess(rows -> {
if (rows.size() == 0) {
promise.fail("用户不存在");
promise.fail("用户名或密码错误");
.onSuccess(rows -> {
if (rows.size() == 0) {
promise.fail("用户不存在");
promise.fail("用户名或密码错误");
@qaiu qaiu merged commit d19d857 into qaiu:main May 29, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants