mirror of
https://github.com/qaiu/netdisk-fast-download.git
synced 2026-08-30 05:22:01 +00:00
- 修复 12 处 NPE 风险: FjTool/FsTool/IzTool/LzTool/MkwTool/P115Tool/PdbTool/QQTool/ParserCreate/CommonUtils/ShareLinkInfo/URLParamUtil - 修复 4 处 Vert.x 资源泄漏: 测试类中 Vertx 实例未关闭 - 修复 CacheManager 防重入和 registerPeriodicCleanup 就绪检查 - 修复 ParserApi 中 redirectUrl()/viewUrl() Promise 未 complete - 修复 CacheManager.updateTotalByField Promise 永不完成 - 修复 AppMain ShutdownHook 注册,确保 Vert.x 先于 JDBCPoolInit 关闭 - 修复 RouterHandlerFactory failureHandler 恢复返回 failure message - 修复 ParserCreate/LzTool 收窄 catch 异常类型 - 修复 IzTool/FjTool/IzToolWithAuth 并发安全 (volatile + header 副本) - 修复 P115Tool UA 为 null 时的 NPE,添加默认 User-Agent - Font Awesome CDN 换源为 s4.zstatic.net,避免 bootcdn 投毒风险 - DirectoryTree selectAll 补 parserUrl 检查,Home 组件名 App→Home
93 lines
3.7 KiB
Java
93 lines
3.7 KiB
Java
package cn.qaiu.parser.impl;
|
|
|
|
import cn.qaiu.entity.ShareLinkInfo;
|
|
import cn.qaiu.parser.PanBase;
|
|
import cn.qaiu.util.StringUtils;
|
|
import io.netty.handler.codec.http.QueryStringDecoder;
|
|
import io.vertx.core.Future;
|
|
import io.vertx.core.MultiMap;
|
|
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
|
|
/**
|
|
* <a href="https://wx.mail.qq.com/">QQ邮箱</a>
|
|
*/
|
|
public class QQTool extends PanBase {
|
|
|
|
public static final String REDIRECT_URL_TEMP = "https://iwx.mail.qq.com/ftn/download?func=4&key={key}&code={code}";
|
|
|
|
public QQTool(ShareLinkInfo shareLinkInfo) {
|
|
super(shareLinkInfo);
|
|
}
|
|
|
|
public Future<String> parse() {
|
|
// QQ mail 直接替换为302链接 无需请求
|
|
QueryStringDecoder queryStringDecoder = new QueryStringDecoder(shareLinkInfo.getShareUrl(), StandardCharsets.UTF_8);
|
|
Map<String, List<String>> prms = queryStringDecoder.parameters();
|
|
if (prms.containsKey("key") && prms.containsKey("code") && prms.containsKey("func")) {
|
|
log.info(prms.get("func").get(0));
|
|
promise.complete(REDIRECT_URL_TEMP.replace("{key}",
|
|
prms.get("key").get(0)).replace("{code}", prms.get("code").get(0)));
|
|
} else {
|
|
fail("key 不合法");
|
|
}
|
|
|
|
|
|
// 通过请求URL获取文件信息和直链 暂时不需要
|
|
// getFileInfo(key);
|
|
|
|
return promise.future();
|
|
}
|
|
|
|
private void getFileInfo(String key) {
|
|
// 设置基础HTTP头部
|
|
var userAgent2 = "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, " +
|
|
"like " +
|
|
"Gecko) Chrome/111.0.0.0 Mobile Safari/537.36";
|
|
|
|
MultiMap headers = MultiMap.caseInsensitiveMultiMap();
|
|
headers.set("User-Agent", userAgent2);
|
|
headers.set("sec-ch-ua-platform", "Android");
|
|
headers.set("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2");
|
|
headers.set("sec-ch-ua-mobile", "sec-ch-ua-mobile");
|
|
|
|
// 获取下载中转站页面
|
|
client.getAbs(key).putHeaders(headers).send().onSuccess(res -> {
|
|
if (res.statusCode() == 200) {
|
|
String html = res.bodyAsString();
|
|
|
|
// 匹配文件信息
|
|
String filename = StringUtils.StringCutNot(html, "var filename = \"", "\"");
|
|
String filesize = StringUtils.StringCutNot(html, "var filesize = ", "\n");
|
|
String fileurl = StringUtils.StringCutNot(html, "var url = \"", "\"");
|
|
|
|
if (filename != null && filesize != null && fileurl != null) {
|
|
// 设置所需HTTP头部
|
|
headers.set("Referer", "https://" + StringUtils.StringCutNot(key, "https://", "/") + "/");
|
|
headers.set("Host", StringUtils.StringCutNot(fileurl, "https://", "/"));
|
|
res.headers().forEach((k, v) -> {
|
|
if (k.equalsIgnoreCase("set-cookie")) {
|
|
headers.set("Cookie", "mail5k=" + StringUtils.StringCutNot(v, "mail5k=", ";") + ";");
|
|
}
|
|
});
|
|
|
|
// 调试匹配的情况
|
|
log.debug("文件名称: {}", filename);
|
|
log.debug("文件大小: {}", filesize);
|
|
log.debug("文件直链: {}", fileurl);
|
|
|
|
// 提交
|
|
promise.complete(fileurl.replace("\\x26", "&"));
|
|
} else {
|
|
this.fail("匹配失败,可能是分享链接的方式已更新");
|
|
}
|
|
} else {
|
|
this.fail("HTTP状态不正确,可能是分享链接的方式已更新");
|
|
}
|
|
}).onFailure(this.handleFail(key));
|
|
}
|
|
|
|
}
|