Compare commits

...

25 Commits

Author SHA1 Message Date
qaiu
1ae2c89d4f - 更新版本号: 0.1.5->0.1.6 2023-07-16 03:11:41 +08:00
qaiu
2de5790b2a - WebServer: PanTool优化异常处理
- Core: Vertx事件循环线程数调整
2023-07-16 02:47:39 +08:00
qaiu
e5b892c9d1 Merge pull request #5 from qaiu/dependabot/maven/com.h2database-h2-2.2.220
Bump h2 from 2.1.214 to 2.2.220
2023-07-10 06:05:17 +08:00
qaiu
1ab5059a41 Merge pull request #4 from qaiu/dependabot/maven/core-database/com.h2database-h2-2.2.220
Bump h2 from 2.1.214 to 2.2.220 in /core-database
2023-07-10 06:04:58 +08:00
dependabot[bot]
1d10e7ab50 Bump h2 from 2.1.214 to 2.2.220
Bumps [h2](https://github.com/h2database/h2database) from 2.1.214 to 2.2.220.
- [Release notes](https://github.com/h2database/h2database/releases)
- [Commits](https://github.com/h2database/h2database/compare/version-2.1.214...version-2.2.220)

---
updated-dependencies:
- dependency-name: com.h2database:h2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-07 22:01:48 +00:00
dependabot[bot]
0477cc4815 Bump h2 from 2.1.214 to 2.2.220 in /core-database
Bumps [h2](https://github.com/h2database/h2database) from 2.1.214 to 2.2.220.
- [Release notes](https://github.com/h2database/h2database/releases)
- [Commits](https://github.com/h2database/h2database/compare/version-2.1.214...version-2.2.220)

---
updated-dependencies:
- dependency-name: com.h2database:h2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-07 22:00:11 +00:00
QAIU
9d3fce3dee 解决一些 warning jdk14对可序列化对象添加@Serial 2023-06-21 16:49:01 +08:00
QAIU
e07d427f85 Merge remote-tracking branch 'origin/main' 2023-06-21 15:40:42 +08:00
QAIU
998c6e4627 musetransfer api test 2023-06-21 15:40:24 +08:00
qaiu
e284dfca63 Zzz 2023-06-21 02:53:58 +00:00
qaiu
cccacde288 Cow解析重复创建实例VertxHolder.getVertxInstance() 2023-06-21 02:53:24 +00:00
qaiu
ee99599d4f cow parse fail return 2023-06-21 02:50:19 +00:00
QAIU
574d5861f5 add mu pan 2023-06-14 17:47:20 +08:00
QAIU
c3173b7f93 Zzz 2023-06-14 16:14:37 +08:00
qaiu
6dc647d0be Update README.md 2023-06-14 15:48:21 +08:00
qaiu
ba5ad53529 Update README.md 2023-06-14 15:48:08 +08:00
qaiu
3c5a0d9c9d Update README.md 2023-06-14 15:40:08 +08:00
qaiu
bb1c296872 Create LICENSE 2023-06-14 15:23:59 +08:00
QAIU
b36e3628bd Zzz 2023-06-14 11:57:58 +08:00
QAIU
837a265fd8 Zzz 2023-06-14 11:56:33 +08:00
QAIU
208c430875 Zzz 2023-06-14 11:53:27 +08:00
QAIU
639f8df534 依赖打包优化 2023-06-14 11:26:33 +08:00
qaiu
4f5e23ebb6 修复Linux运行脚本 2023-06-14 10:30:16 +08:00
QAIU
d86c67314c Linux部署服务模板修改 2023-06-13 15:11:32 +08:00
qaiu
d1ba790d05 Update README.md 2023-06-13 13:58:26 +08:00
34 changed files with 433 additions and 154 deletions

3
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,3 @@
{
"java.compile.nullAnalysis.mode": "automatic"
}

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 qaiu
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,41 +1,45 @@
# netdisk-fast-download
# 网盘快速下载器--直链解析
[![Java CI with Maven](https://github.com/qaiu/netdisk-fast-download/actions/workflows/maven.yml/badge.svg)](https://github.com/qaiu/netdisk-fast-download/actions/workflows/maven.yml)
[![jdk](https://img.shields.io/badge/jdk-%3E%3D17-blue)](https://www.oracle.com/cn/java/technologies/downloads/)
[![vert.x](https://img.shields.io/badge/vert.x-4.4.1-blue)](https://vertx-china.github.io/)
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/qaiu/netdisk-fast-download)](https://github.com/qaiu/netdisk-fast-download/releases/tag/0.1.6-releases)
## 网盘支持情况:
`网盘名称(网盘标识):`
- 蓝奏云 (lz)
- [蓝奏云 (lz)](https://pc.woozooo.com/)
- [ ] 登录, 上传, 下载, 分享
- [X] 直链解析
- 奶牛快传 (cow)
- [奶牛快传 (cow)](https://cowtransfer.com/)
- [ ] 登录, 上传, 下载, 分享
- [X] 直链解析
- 移动云空间 (ec)
- [移动云空间 (ec)](https://www.ecpan.cn/web)
- [ ] 登录, 上传, 下载, 分享
- [X] 直链解析
- UC网盘 (uc)
- [UC网盘 (uc)](https://fast.uc.cn/)
- [ ] 登录, 上传, 下载, 分享
- [X] 直链解析
- 小飞机网盘 (fj)
- [小飞机网盘 (fj)](https://www.feijipan.com/)
- [ ] 登录, 上传, 下载, 分享
- [X] 直链解析
- 亿方云 (fc)
- [亿方云 (fc)](https://www.fangcloud.com/)
- [ ] 登录, 上传, 下载, 分享
- [X] 直链解析
- 123云盘 (ye)
- [123云盘 (ye)](https://www.123pan.com/)
- [ ] 登录, 上传, 下载, 分享
- [X] 直链解析
- 文叔叔 (ws)
- 夸克网盘 (qk)
- TODO
- [文叔叔 (ws) 开发中](https://www.wenshushu.cn/)
- [夸克网盘 (qk) 开发中](https://pan.quark.cn/)
技术栈:
**TODO:**
- 登录接口, 文件上传/下载/分享后端接口
- 短地址服务
- 前端界面(正则规划)
**技术栈:**
Jdk17+Vert.x4.4.1
Core模块集成Vert.x实现类spring的注解式路由API
Core模块集成Vert.x实现类spring的注解式路由API
API接口
@@ -46,9 +50,9 @@ parser接口可以直接解析分享链接: 加密分享需要加上参数pwd=
1. 解析并自动302跳转 :
http(s)://your_host/parser?url=分享链接(&pwd=xxx)
http(s)://your_host/网盘标识/分享id(@分享密码)
http(s)://your_host/网盘标识/分享key(@分享密码)
2. 获取解析后的直链--JSON格式
http(s)://your_host/json/网盘标识/分享id(@分享密码)
http(s)://your_host/json/网盘标识/分享key(@分享密码)
3. 特别注意的地方:
- 有些网盘的加密分享的密码可以忽略: 如移动云空间,小飞机网盘
- 移动云空间(ec)使用parser?url= 解析时因为分享链接比较特殊(链接带有参数且含有#符号)所以要么对#进行转义%23要么直接去掉# 或者URL直接是主机名+'/'跟一个data参数
@@ -96,17 +100,17 @@ GET http://127.0.0.1:6400/json/fc/e5079007dc31226096628870c7@QAIU
# 网盘对比
| 网盘名称 | 可直接下载分享 | 加密分享 | 初始网盘空间 | 单文件大小限制 | 登录接口 |
|------------|------------|----------|-----------|---------|------|
| 蓝奏云 | √ | √ | 不限空间 | 100M | TODO |
| 奶牛快传 | √ | X | 10G | 不限大小 | TODO |
| 移动云空间 | √ | √(密码可忽略) | 5G(个人) | 不限大小 | TODO |
| UC网盘 | √ | √ | 10G | 不限大小 | TODO |
| 小飞机网盘 | √ | √(密码可忽略) | 10G | 不限大小 | TODO |
| 360亿方云 | √(注意有流量限制) | √(密码可忽略) | 100G(须实名) | 不限大小 | TODO |
| 123云盘 | √ | √ | 2T | 不限大小 | TODO |
| 文叔叔(TODO) | √(注意有时间限制) | √ | 10G | 不限大小 | TODO |
| 夸克网盘(TODO) | 需要登录 | √ | 10G | 不限大小 | TODO |
| 网盘名称 | 可直接下载分享 | 加密分享 | 初始网盘空间 | 单文件大小限制 | 登录接口 |
|------------|------------------------|----------|-----------|---------|------|
| 蓝奏云 | √ | √ | 不限空间 | 100M | TODO |
| 奶牛快传 | √ | X | 10G | 不限大小 | TODO |
| 移动云空间 | √ | √(密码可忽略) | 5G(个人) | 不限大小 | TODO |
| UC网盘 | √ | √ | 10G | 不限大小 | TODO |
| 小飞机网盘 | √ | √(密码可忽略) | 10G | 不限大小 | TODO |
| 360亿方云 | √(试用账号有时间限制企业版需要599续费) | √(密码可忽略) | 100G(须实名) | 不限大小 | TODO |
| 123云盘 | √ | √ | 2T | 100G | TODO |
| 文叔叔(TODO) | √(注意有时间限制) | √ | 10G | 5GB | TODO |
| 夸克网盘(TODO) | 需要登录 | √ | 10G | 不限大小 | TODO |
# 打包部署
@@ -123,15 +127,34 @@ mvn package
> 注意: netdisk-fast-download.service中的ExecStart的路径改为实际路径
```shell
cd ~
wget -O netdisk-fast-download-0.1.5-bin.zip https://github.com/qaiu/netdisk-fast-download/releases/download/0.1.5-releases/netdisk-fast-download-0.1.5-bin.zip
wget -O netdisk-fast-download-0.1.6-bin.zip https://github.com/qaiu/netdisk-fast-download/releases/download/0.1.6-releases/netdisk-fast-download-0.1.6-bin.zip
unzip netdisk-fast-download-*-bin.zip
cd netdisk-fast-download-*-bin
bash service-install.sh
```
服务相关命令:
1、查看服务状态
systemctl status netdisk-fast-download.service
2、控制服务
启动服务
systemctl start netdisk-fast-download.service
重启服务
systemctl restart netdisk-fast-download.service
停止服务
systemctl stop netdisk-fast-download.service
开机启动服务
systemctl enable netdisk-fast-download.servic
停止开机启动
systemctl disable netdisk-fast-download.servic
## Windows服务部署
1. 解压netdisk-fast-download-0.1.5-bin.zip
2. 进入netdisk-fast-download-0.1.5-bin目录
1. 下载并解压releases版本netdisk-fast-download-0.1.6-bin.zip
2. 进入netdisk-fast-download-0.1.6-bin目录
3. 使用管理员权限运行nfd-service-install.bat
如果不想使用服务运行可以直接运行run.bat

View File

@@ -7,8 +7,8 @@ Wants=network-online.target
[Service]
Type=simple
# User=USER
# 注意修改为自己的路径
ExecStart=/usr/bin/java -server -Xmx128m -jar /root/java/netdisk-fast-download/netdisk-fast-download*.jar
# 需要JDK17及以上版本 注意修改为自己的路径
ExecStart=/root/java/jdk-17.0.2/bin/java -server -Xmx128m -jar /root/java/netdisk-fast-download-0.1.6/netdisk-fast-download-0.1.6.jar
ExecStop=/bin/kill -s QUIT $MAINPID
Restart=always
StandOutput=syslog

View File

@@ -1,5 +1,6 @@
#!/bin/sh
#!/bin/bash
# set -x
LAUNCH_JAR="netdisk-fast-download-*.jar"
LAUNCH_JAR="netdisk-fast-download-0.1.6.jar"
nohup java -Xmx512M -jar "$LAUNCH_JAR" "$@" >startup.log 2>&1 &
tail -f startup.log

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>netdisk-fast-download</artifactId>
<groupId>cn.qaiu</groupId>
<version>0.1.5</version>
<version>0.1.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -30,7 +30,7 @@
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.1.214</version>
<version>2.2.220</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.zaxxer/HikariCP -->

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>netdisk-fast-download</artifactId>
<groupId>cn.qaiu</groupId>
<version>0.1.5</version>
<version>0.1.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<version>1.0.8</version>

View File

@@ -63,7 +63,7 @@ public final class Deploy {
var activeMode = conf.getString("active");
if ("dev".equals(activeMode)) {
LOGGER.info("---------------> development environment <--------------\n");
System.setProperty("vertxweb.environment","dev");
System.setProperty("vertxweb.environment", "dev");
} else {
LOGGER.info("---------------> Production environment <--------------\n");
}
@@ -109,7 +109,14 @@ public final class Deploy {
LOGGER.info("配置读取成功");
customConfig = globalConfig.getJsonObject(ConfigConstant.CUSTOM);
var vertxOptions = new VertxOptions(globalConfig.getJsonObject(ConfigConstant.VERTX));
JsonObject vertxConfig = globalConfig.getJsonObject(ConfigConstant.VERTX);
Integer vertxConfigELPS = vertxConfig.getInteger(ConfigConstant.EVENT_LOOP_POOL_SIZE);
var vertxOptions = vertxConfigELPS == 0 ?
new VertxOptions() : new VertxOptions(vertxConfig);
LOGGER.info("vertxConfigEventLoopPoolSize: {}, eventLoopPoolSize: {}, workerPoolSize: {}", vertxConfigELPS,
vertxOptions.getEventLoopPoolSize(),
vertxOptions.getWorkerPoolSize());
var vertx = Vertx.vertx(vertxOptions);
VertxHolder.init(vertx);
//配置保存在共享数据中
@@ -123,6 +130,7 @@ public final class Deploy {
bch.complete("other handle complete");
});
// 部署 路由、异步service、反向代理 服务
var future1 = vertx.deployVerticle(RouterVerticle.class, getWorkDeploymentOptions("Router"));
var future2 = vertx.deployVerticle(ServiceVerticle.class, getWorkDeploymentOptions("Service"));
var future3 = vertx.deployVerticle(ReverseProxyVerticle.class, getWorkDeploymentOptions("proxy"));

View File

@@ -21,6 +21,7 @@ import io.vertx.ext.web.Router;
import io.vertx.ext.web.RoutingContext;
import io.vertx.ext.web.handler.BodyHandler;
import io.vertx.ext.web.handler.CorsHandler;
import io.vertx.ext.web.handler.StaticHandler;
import io.vertx.ext.web.handler.sockjs.SockJSHandler;
import io.vertx.ext.web.handler.sockjs.SockJSHandlerOptions;
import javassist.CtClass;
@@ -73,6 +74,19 @@ public class RouterHandlerFactory implements BaseHttpApi {
*/
public Router createRouter() {
Router router = Router.router(VertxHolder.getVertxInstance());
// 静态资源
String path = SharedDataUtil.getJsonConfig("server")
.getString("staticResourcePath");
if (!StringUtils.isEmpty(path)) {
// 静态资源
router.route("/*").handler(StaticHandler
.create(path)
.setCachingEnabled(true)
.setDefaultContentEncoding("UTF-8"));
}
router.route().handler(ctx -> {
LOGGER.debug("The HTTP service request address information ===>path:{}, uri:{}, method:{}",
ctx.request().path(), ctx.request().absoluteURI(), ctx.request().method());
@@ -116,6 +130,7 @@ public class RouterHandlerFactory implements BaseHttpApi {
.error("Method Not Allowed", 405)));
router.errorHandler(404, ctx -> ctx.response().setStatusCode(404).setChunked(true)
.end("Internal server error: 404 not found"));
return router;
}

View File

@@ -3,6 +3,7 @@ package cn.qaiu.vx.core.model;
import org.apache.commons.lang3.StringUtils;
import java.io.Serial;
import java.io.Serializable;
/**
@@ -13,6 +14,7 @@ import java.io.Serializable;
*/
public class JsonResult<T> implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
private static final int SUCCESS_CODE = 200;

View File

@@ -3,6 +3,8 @@ package cn.qaiu.vx.core.util;
public interface ConfigConstant {
String CUSTOM = "custom";
String VERTX = "vertx";
String EVENT_LOOP_POOL_SIZE = "eventLoopPoolSize";
String LOCAL = "local";
String SERVER = "server";
String GLOBAL_CONFIG = "globalConfig";

View File

@@ -7,7 +7,7 @@
<groupId>cn.qaiu</groupId>
<artifactId>netdisk-fast-download</artifactId>
<packaging>pom</packaging>
<version>0.1.5</version>
<version>0.1.6</version>
<modules>
<module>core</module>

View File

@@ -5,10 +5,10 @@
<parent>
<artifactId>netdisk-fast-download</artifactId>
<groupId>cn.qaiu</groupId>
<version>0.1.5</version>
<version>0.1.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<version>0.1.5</version>
<version>0.1.6</version>
<artifactId>web-service</artifactId>
<properties>
@@ -58,7 +58,7 @@
<dependency>
<groupId>cn.qaiu</groupId>
<artifactId>core-database</artifactId>
<version>0.1.5</version>
<version>0.1.6</version>
</dependency>
@@ -133,8 +133,7 @@
</goals>
<configuration>
<!--打包时排除的依赖作用域-->
<excludeScope>test</excludeScope>
<excludeScope>provided</excludeScope>
<includeScope>runtime</includeScope>
<outputDirectory>
${packageDirectory}/lib/
</outputDirectory>

View File

@@ -10,7 +10,7 @@ import io.vertx.core.json.JsonObject;
* 程序入口
* <br>Create date 2021-05-08 13:00:01
*
* @author qiu
* @author qaiu
*/
public class AppMain {

View File

@@ -2,9 +2,10 @@ package cn.qaiu.lz.common.parser.impl;
import cn.qaiu.lz.common.parser.IPanTool;
import cn.qaiu.lz.common.util.CommonUtils;
import cn.qaiu.lz.common.util.PanExceptionUtils;
import cn.qaiu.vx.core.util.VertxHolder;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.core.Vertx;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.client.WebClient;
import lombok.extern.slf4j.Slf4j;
@@ -24,7 +25,7 @@ public class CowTool implements IPanTool {
public Future<String> parse(String data, String code) {
Promise<String> promise = Promise.promise();
WebClient client = WebClient.create(Vertx.vertx());
WebClient client = WebClient.create(VertxHolder.getVertxInstance());
String key = CommonUtils.adaptShortPaths(SHARE_URL_PREFIX, data);
client.getAbs(API_REQUEST_URL + "?uniqueUrl=" + key).send().onSuccess(res -> {
JsonObject resJson = res.bodyAsJsonObject();
@@ -41,15 +42,21 @@ public class CowTool implements IPanTool {
if (StringUtils.isNotEmpty(downloadUrl)) {
log.info("cow parse success: {}", downloadUrl);
promise.complete(downloadUrl);
return;
}
} else {
log.error("cow parse fail: {}; json: {}", url2, res2Json);
log.error("cow parse fail: {}; downloadUrl is empty", url2);
promise.fail("cow parse fail: " + url2 + "; downloadUrl is empty");
return;
}
log.error("cow parse fail: {}; json: {}", url2, res2Json);
promise.fail("cow parse fail: " + url2 + "; json:" + res2Json);
});
} else {
log.error("cow parse fail: {}; json: {}", key, resJson);
return;
}
});
log.error("cow parse fail: {}; json: {}", key, resJson);
promise.fail("cow parse fail: " + key + "; json:" + resJson);
}).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Cow", key, t)));;
return promise.future();
}

View File

@@ -2,6 +2,7 @@ package cn.qaiu.lz.common.parser.impl;
import cn.qaiu.lz.common.parser.IPanTool;
import cn.qaiu.lz.common.util.CommonUtils;
import cn.qaiu.lz.common.util.PanExceptionUtils;
import cn.qaiu.vx.core.util.VertxHolder;
import io.vertx.core.Future;
import io.vertx.core.Promise;
@@ -35,32 +36,28 @@ public class EcTool implements IPanTool {
JsonObject fileInfo = jsonObject
.getJsonObject("var")
.getJsonObject("chainFileInfo");
if (!fileInfo.containsKey("errMesg")) {
JsonObject cloudpFile = fileInfo.getJsonObject("cloudpFile");
JsonArray fileIdList = JsonArray.of(cloudpFile);
// 构造请求JSON {"extCodeFlag":0,"isIp":0}
JsonObject requestBodyJson = JsonObject.of("extCodeFlag", 0, "isIp", 0);
requestBodyJson.put("shareId", Integer.parseInt(fileInfo.getString("shareId"))); // 注意shareId
// 数据类型
requestBodyJson.put("groupId", cloudpFile.getString("groupId"));
requestBodyJson.put("fileIdList", fileInfo.getJsonArray("cloudpFileList"));
// 第二次请求 获取下载链接
client.postAbs(DOWNLOAD_REQUEST_URL)
.sendJsonObject(requestBodyJson).onSuccess(res2 -> {
JsonObject jsonRes = res2.bodyAsJsonObject();
log.debug("ecPan get download url -> {}", res2.body().toString());
promise.complete(jsonRes.getJsonObject("var").getString("downloadUrl"));
}).onFailure(t -> promise.fail(new RuntimeException("解析异常: key = " + dataKey, t.fillInStackTrace())));
} else {
if (fileInfo.containsKey("errMesg")) {
promise.fail(new RuntimeException(DOWNLOAD_REQUEST_URL + " 解析失败: "
+ fileInfo.getString("errMesg")) + " key = " + dataKey);
return;
}
JsonObject cloudpFile = fileInfo.getJsonObject("cloudpFile");
JsonArray fileIdList = JsonArray.of(cloudpFile);
// 构造请求JSON {"extCodeFlag":0,"isIp":0}
JsonObject requestBodyJson = JsonObject.of("extCodeFlag", 0, "isIp", 0);
requestBodyJson.put("shareId", Integer.parseInt(fileInfo.getString("shareId"))); // 注意shareId
// 数据类型
requestBodyJson.put("groupId", cloudpFile.getString("groupId"));
requestBodyJson.put("fileIdList", fileInfo.getJsonArray("cloudpFileList"));
// 第二次请求 获取下载链接
client.postAbs(DOWNLOAD_REQUEST_URL).sendJsonObject(requestBodyJson).onSuccess(res2 -> {
JsonObject jsonRes = res2.bodyAsJsonObject();
log.debug("ecPan get download url -> {}", res2.body().toString());
promise.complete(jsonRes.getJsonObject("var").getString("downloadUrl"));
}).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Ec", dataKey, t)));
}
).onFailure(t -> {
promise.fail(new RuntimeException("解析异常: key = " + dataKey, t.fillInStackTrace()));
});
).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Ec", dataKey, t)));;
return promise.future();
}
}

View File

@@ -2,6 +2,7 @@ package cn.qaiu.lz.common.parser.impl;
import cn.qaiu.lz.common.parser.IPanTool;
import cn.qaiu.lz.common.util.CommonUtils;
import cn.qaiu.lz.common.util.PanExceptionUtils;
import cn.qaiu.vx.core.util.VertxHolder;
import io.vertx.core.Future;
import io.vertx.core.MultiMap;
@@ -20,7 +21,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 亿方云
* 360亿方云
*/
public class FcTool implements IPanTool {
@@ -58,15 +59,15 @@ public class FcTool implements IPanTool {
if (res2.statusCode() == 302) {
sClient.getAbs(res2.getHeader("Location")).send().onSuccess(res3 -> {
getDownURL(dataKey, promise, res3, sClient);
});
} else {
promise.fail(SHARE_URL_PREFIX + " 密码跳转后获取重定向失败 \n" + html);
}).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Fc", dataKey, t)));
return;
}
});
promise.fail(SHARE_URL_PREFIX + " 密码跳转后获取重定向失败 \n" + html);
}).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Fc", dataKey, t)));
return;
}
getDownURL(dataKey, promise, res, sClient);
});
}).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Fc", dataKey, t)));
return promise.future();
}
@@ -102,6 +103,6 @@ public class FcTool implements IPanTool {
return;
}
promise.complete(resJson.getString("download_url"));
});
}).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Fc", dataKey, t)));
}
}

View File

@@ -3,6 +3,7 @@ package cn.qaiu.lz.common.parser.impl;
import cn.qaiu.lz.common.parser.IPanTool;
import cn.qaiu.lz.common.util.AESUtils;
import cn.qaiu.lz.common.util.CommonUtils;
import cn.qaiu.lz.common.util.PanExceptionUtils;
import cn.qaiu.vx.core.util.VertxHolder;
import io.vertx.core.Future;
import io.vertx.core.MultiMap;
@@ -70,8 +71,8 @@ public class FjTool implements IPanTool {
return;
}
promise.complete(headers.get("Location"));
});
});
}).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Fj", dataKey, t)));
}).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Fj", dataKey, t)));
return promise.future();
}

View File

@@ -1,11 +1,11 @@
package cn.qaiu.lz.common.parser.impl;
import cn.qaiu.lz.common.parser.IPanTool;
import cn.qaiu.lz.common.util.PanExceptionUtils;
import cn.qaiu.vx.core.util.VertxHolder;
import io.vertx.core.Future;
import io.vertx.core.MultiMap;
import io.vertx.core.Promise;
import io.vertx.core.Vertx;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.client.WebClient;
import io.vertx.ext.web.client.WebClientOptions;
@@ -32,11 +32,11 @@ public class LzTool implements IPanTool {
client.getAbs(key).send().onSuccess(res -> {
String html = res.bodyAsString();
// 匹配iframe
Pattern compile = Pattern.compile("src=\"(/fn\\?[a-zA-Z0-9_+/=]{16,})\"");
Pattern compile = Pattern.compile("src=\"(/fn\\?[a-zA-Z\\d_+/=]{16,})\"");
Matcher matcher = compile.matcher(html);
if (!matcher.find()) {
// 没有Iframe说明是加密分享, 匹配sign通过密码请求下载页面
Pattern compile2 = Pattern.compile("sign=([0-9a-zA-Z_]{16,})");
Pattern compile2 = Pattern.compile("sign=(\\w{16,})");
Matcher matcher2 = compile2.matcher(html);
if (!matcher2.find()) {
promise.fail(key + ": sign正则匹配失败, 可能分享已失效: " + html);
@@ -50,15 +50,15 @@ public class LzTool implements IPanTool {
client.getAbs(SHARE_URL_PREFIX + iframePath).send().onSuccess(res2 -> {
String html2 = res2.bodyAsString();
System.out.println(html);
Matcher matcher2 = Pattern.compile("'sign'\s*:\s*'([0-9a-zA-Z_]+)'").matcher(html2);
Matcher matcher2 = Pattern.compile("'sign'\s*:\s*'(\\w+)'").matcher(html2);
if (!matcher2.find()) {
promise.fail(SHARE_URL_PREFIX + iframePath + " -> " + key + ": sign正则匹配失败, 可能分享已失效: " + html2);
return;
}
String sign = matcher2.group(1);
getDownURL(promise, code, key, client, sign);
});
});
}).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Lz", key, t)));
}).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Lz", key, t)));
return promise.future();
}
@@ -83,9 +83,9 @@ public class LzTool implements IPanTool {
return;
}
String downUrl = urlJson.getString("dom") + "/file/" + urlJson.getString("url");
client.getAbs(downUrl).putHeaders(headers).send().onSuccess(res3 -> {
promise.complete(res3.headers().get("Location"));
});
});
client.getAbs(downUrl).putHeaders(headers).send()
.onSuccess(res3 -> promise.complete(res3.headers().get("Location")))
.onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Lz", key, t)));
}).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Lz", key, t)));
}
}

View File

@@ -2,6 +2,7 @@ package cn.qaiu.lz.common.parser.impl;
import cn.qaiu.lz.common.parser.IPanTool;
import cn.qaiu.lz.common.util.CommonUtils;
import cn.qaiu.lz.common.util.PanExceptionUtils;
import cn.qaiu.vx.core.util.VertxHolder;
import io.vertx.core.Future;
import io.vertx.core.Promise;
@@ -12,7 +13,7 @@ import io.vertx.uritemplate.UriTemplate;
import lombok.extern.slf4j.Slf4j;
/**
* 移动云空间解析
* UC网盘解析
*/
@Slf4j
public class UcTool implements IPanTool {
@@ -74,13 +75,11 @@ public class UcTool implements IPanTool {
return;
}
promise.complete(resJson3.getJsonArray("data").getJsonObject(0).getString("download_url"));
})
.onFailure(t -> promise
.fail(new RuntimeException("解析异常: ", t.fillInStackTrace())));
}).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Uc", dataKey, t)));
}).onFailure(t -> promise.fail(new RuntimeException("解析异常: ", t.fillInStackTrace())));
}
).onFailure(t -> promise.fail(new RuntimeException("解析异常: key = " + dataKey, t.fillInStackTrace())));
).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Uc", dataKey, t)));
return promise.future();
}
}

View File

@@ -2,12 +2,14 @@ package cn.qaiu.lz.common.parser.impl;
import cn.qaiu.lz.common.parser.IPanTool;
import cn.qaiu.lz.common.util.CommonUtils;
import cn.qaiu.lz.common.util.PanExceptionUtils;
import cn.qaiu.vx.core.util.VertxHolder;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.client.WebClient;
import io.vertx.uritemplate.UriTemplate;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import java.net.MalformedURLException;
@@ -19,6 +21,7 @@ import java.util.regex.Pattern;
/**
* 123网盘
*/
@Slf4j
public class YeTool implements IPanTool {
public static final String SHARE_URL_PREFIX = "https://www.123pan.com/s/";
public static final String FIRST_REQUEST_URL = SHARE_URL_PREFIX + "{key}.html";
@@ -39,7 +42,7 @@ public class YeTool implements IPanTool {
Matcher matcher = compile.matcher(html);
if (!matcher.find()) {
System.out.println("err");
promise.fail(html + "\n Ye: " + dataKey + " 正则匹配失败");
return;
}
String fileInfoString = matcher.group(1);
@@ -48,7 +51,7 @@ public class YeTool implements IPanTool {
JsonObject resListJson = fileInfoJson.getJsonObject("reslist");
if (resJson == null || resJson.getInteger("code") != 0) {
promise.fail(dataKey + " 解析到异常JSON: "+resJson);
promise.fail(dataKey + " 解析到异常JSON: " + resJson);
return;
}
String shareKey = resJson.getJsonObject("data").getString("ShareKey");
@@ -61,13 +64,14 @@ public class YeTool implements IPanTool {
.send().onSuccess(res2 -> {
JsonObject infoJson = res2.bodyAsJsonObject();
if (infoJson.getInteger("code") != 0) {
promise.fail("Ye: " + dataKey + " 状态码异常" + infoJson);
return;
}
JsonObject getFileInfoJson =
infoJson.getJsonObject("data").getJsonArray("InfoList").getJsonObject(0);
getFileInfoJson.put("ShareKey", shareKey);
getDownUrl(promise, client, getFileInfoJson);
});
}).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Ye", dataKey, t)));
} else {
promise.fail(dataKey + " 该分享需要密码");
}
@@ -77,13 +81,13 @@ public class YeTool implements IPanTool {
JsonObject reqBodyJson = resListJson.getJsonObject("data").getJsonArray("InfoList").getJsonObject(0);
reqBodyJson.put("ShareKey", shareKey);
getDownUrl(promise, client, reqBodyJson);
});
}).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Ye", dataKey, t)));
return promise.future();
}
private static void getDownUrl(Promise<String> promise, WebClient client, JsonObject reqBodyJson) {
System.out.println(reqBodyJson);
log.info(reqBodyJson.encodePrettily());
client.postAbs("https://www.123pan.com/a/api/share/download/info").sendJsonObject(reqBodyJson).onSuccess(res2 -> {
JsonObject downURLJson = res2.bodyAsJsonObject();
System.out.println(downURLJson);
@@ -99,6 +103,6 @@ public class YeTool implements IPanTool {
} catch (MalformedURLException e) {
promise.fail("urlParams解析异常" + e.getMessage());
}
});
}).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Ye", reqBodyJson.encodePrettily(), t)));
}
}

View File

@@ -10,6 +10,7 @@ import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.HexFormat;
import java.util.Random;
/**
* AES加解密工具类
@@ -236,4 +237,25 @@ public class AESUtils {
}
return result;
}
// ========================== musetransfer加密相关 ===========================
//length用户要求产生字符串的长度
public static String getRandomString(int length){
String str="abcdefghijklmnopqrstuvwxyz0123456789";
Random random=new Random();
StringBuilder sb=new StringBuilder();
for(int i=0;i<length;i++){
int number=random.nextInt(36);
sb.append(str.charAt(number));
}
return sb.toString();
}
public static String getRandomString(){
return getRandomString(10);
}
}

View File

@@ -0,0 +1,12 @@
package cn.qaiu.lz.common.util;
/**
* @author <a href="https://qaiu.top">QAIU</a>
* @date 2023/7/16 1:53
*/
public class PanExceptionUtils {
public static RuntimeException fillRunTimeException(String name, String dataKey, Throwable t) {
return new RuntimeException(name + ": 请求异常: key = " + dataKey, t.fillInStackTrace());
}
}

View File

@@ -7,7 +7,6 @@ import cn.qaiu.lz.web.service.UserService;
import cn.qaiu.vx.core.annotaions.RouteHandler;
import cn.qaiu.vx.core.annotaions.RouteMapping;
import cn.qaiu.vx.core.enums.RouteMethod;
import cn.qaiu.vx.core.model.JsonResult;
import cn.qaiu.vx.core.util.AsyncServiceUtil;
import io.vertx.core.Future;
import io.vertx.core.Promise;

View File

@@ -10,25 +10,29 @@ server:
# 反向代理服务器配置路径(不用加后缀)
proxyConf: server-proxy
# vertx线程配置 事件循环线程配置为0: eventLoopPoolSize将会采用默认配置(CPU核心*2) workerPoolSize将会采用默认20
vertx:
eventLoopPoolSize: 8
workerPoolSize: 20
eventLoopPoolSize: 0
workerPoolSize: 0
custom:
asyncServiceInstances: 8
# 异步服务线程数
asyncServiceInstances: 4
# server路由(controller层)所在包路径
routerLocations: cn.qaiu.lz.web.http
# 拦截器包路径
interceptorClassPath: cn.qaiu.lz.common.interceptorImpl.DefaultInterceptor
# server层包路径
handlerLocations: cn.qaiu.lz.web.service
# 匹配规则
ignoresReg:
- .*/login$
- .*/test.*$
# 实体类包路径匹配正则
entityPackagesReg:
- ^cn\.qaiu\.lz\.web\.model\..*
errorPage404: /index.html
indexPage: /test2
sharedLogin: true
lzConfig:
config: '111'
# 数据源配置
dataSource:
provider_class: io.vertx.ext.jdbc.spi.impl.HikariCPDataSourceProvider
jdbcUrl: jdbc:h2:tcp://127.0.0.1:9095/./db/myData;MODE=MySQL;DATABASE_TO_LOWER=FALSE

View File

@@ -2,6 +2,6 @@
active: dev
# 框架版本号 和主版本号
version_vertx: 4.4.1
version_app: 0.1.5
version_app: 0.1.6
# 公司名称 -> LOGO版权文字
copyright: QAIU

View File

@@ -10,3 +10,18 @@ content-type: application/x-www-form-urlencoded;
task=5&folder_id=-1
###
POST https://wwsd.lanzoue.com/ajaxm.php
Accept: application/json, text/javascript, */*
Content-Type: application/x-www-form-urlencoded
action=downprocess&sign=AGYHOQk4BjdTWgQ7BzcGOlU_bATVSNQMxBDFQZgZoBj4HMFEgWnMOZ1I1A2NWOgUxB20HMlM_aUGoLOgQz&p=e4k4
###
https://developer.lanzoug.com/file/?VDJbZVxtADFSWwY+U2YHa1FuU2tTYgBnBnUGZFNmWylSOVMpCTJQZQQhBSdQKQFkBjMOfAMyA21VPVs8V28BLVRkWyJcMAB6UjcGfVNlB29RZVN4U3YAawZxBiZTaVszUj5TYQkLUG0ENgVuUDUBMQZkDjsDbgMxVWBbZFc8ASZUMlt/XDwAZVIyBmFTNwc3UTtTYFM8ACQGcQZwUzJbaFJiUzYJZ1ArBGIFZlArATIGaQ4kAz8DMlVnWz9XMwE1VGZbOFw3AG1SPQY0UzcHMVFqUzdTbwBmBjEGMVNsW2NSM1MzCWxQNwRkBWVQNwEwBmQOPwNyA3tVO1stVy0BdVQnW2lccwA9UmAGbVM2BzZRPlNvUzgAOwY5BiZTe1szUj9TYQkyUDkEYwVjUDQBMAZsDiUDcgMnVTRbMVd8AT1UZVs6XDkAYVI0BmBTNQc/UTlTZVMqAHcGcQZ3UzJba1JkUzwJYVA0BGIFYVA0ATAGaw4tAykDaFUiW2BXOgExVGZbIlwzAGdSNgZ%2BUzYHMlE9U3hTOwA6
###
https://developer.lanzoug.com/file/?VTNVa1tqAjMFDAM7BDEAbAE+U2tfbgZhBnVbOQUwVCYEb1IoAToCNwQhVnRXLlcyVWAEdl9uVzkEbFYxVm5VeVVlVSxbNwJ4BWADeAQyAGgBNVN4X3oGbQZxW3sFP1Q8BGhSYAEDAj8ENlY9VzJXZ1U3BDFfMldlBDFWaVY9VXJVM1VxWzsCZwVlA2QEYAAwAWtTYF8wBiIGcVstBWRUZwQ0UjcBbwJ5BGJWNVcsV2RVOgQuX2NXZgQ2VjJWMlVhVWdVNlswAm8FagMxBGAANgE6UzdfYwZgBjFbbAU6VGwEZVIyAWQCZQRkVjZXMFdmVTcENV8uVy8EalYgVixVIVUmVWdbdAI/BTcDaARhADEBblNvXzQGPQY5W3sFLVQ8BGlSYAE6AmsEY1Y2VztXY1U/BDFfM1dnBDRWZFYkVXpVc1VkW2oCIQVuA2QEZgA5AW5TZl8wBjYGMFtkBWFUcwRxUnUBKwJrBGNWNlc7V2NVPwQxXzJXZQQzVmdWLFUhVTxVcls7AmcFYgNnBH4AMwFoU2RfLgY1BjVbawV3VGIEPA==

View File

@@ -0,0 +1,56 @@
###
POST https://service.tezign.com/transfer/share/download
Content-Type: application/json;charset=UTF-8
X-Transfer-Device:a14a17ccc07
X-Transfer-Sign:bea1e0bece50692b5d062d6d809cdb75
{"code":"a85hmqm1g"}
###
POST https://service.tezign.com/transfer/share/download
Content-Type: application/json;charset=UTF-8
X-Transfer-Device:xz9ynai8bi
X-Transfer-Sign:923690974149080012f9eba9ddc0cd82
{"code":"81nq4gm8j", "pwd":"3184"}
###
https://musetransfer.com/s/a85hmqm1g
###
#https://musetransfer.com/s/81nq4gm8j 密码3184请点击链接获取《无主题 - sdgsEasyManual.doc》, 有效期至2024年6月13日
#https://musetransfer.com/s/a85hmqm1g 请点击链接获取《111》, 有效期至2024年6月13日
# a85hmqm1g
# X-Transfer-Device:a14a17cc207
# X-Transfer-Sign:fc29338ac476fb1bee7d2eb12bb30bca
#
# MD5(L3RyYW5zZmVyL3NoYXJlL2Rvd25sb2Fk|eyJjb2RlIjoiYTg1aG1xbTFnIn0=|a14a17cc207|)=fc29338ac476fb1bee7d2eb12bb30bca
#
# L3RyYW5zZmVyL3NoYXJlL2Rvd25sb2Fk|eyJjb2RlIjoiODFucTRnbThqIn0=|8g54fpq1we|
#
# L3RyYW5zZmVyL3NoYXJlL2Rvd25sb2Fk /transfer/share/download
# eyJjb2RlIjoiYTg1aG1xbTFnIn0= {"code":"a85hmqm1g"}
#
# a14a17cc207 随机数
#
# ƒ u(t){var e="",n=t||11,u=(1+n)/2|0;(!o||i+u>c)&&(o=r(c),i=0);while(u--)e+=a[o[i++]];return e.substring(0,n)}
# 'L3RyYW5zZmVyL3NoYXJlL2Rvd25sb2Fk|eyJjb2RlIjoiODFucTRnbThqIiwgICJwd2QiOiIzMTg0In0=|xz9ynai8bi|'
###
https://transfer.musecdn1.com/a85hmqm1g/d43a1b3baf646501368a7cc2a087ae8e.zip?auth_key=1686790800-YTg1aG1xbTFnOjE1OTU1NA-0-19b281e3e5fefedac6c57272deb6e747&response-content-type=application/octet-stream&response-content-disposition=attachment%3B%20filename%3D%22netdisk-fast-download-0.1.6-bin.zip%22%3B%20filename%2A%3DUTF-8%27%27netdisk-fast-download-0.1.6-bin.zip
Referer:https://musetransfer.com/
###
# @no-cookie-jar
# @no-redirect
https://transfer.musecdn1.com/81nq4gm8j/2333dd8e48fbf52f787d633d506c2d8d.doc?auth_key=1686798000-ODFucTRnbThqOjE1OTU1NA-0-7f9f1174bf1cc9925ed5ad497c6344b8&response-content-type=application/octet-stream&response-content-disposition=attachment%3B%20filename%3D%22sdgsEasyManual.doc%22%3B%20filename%2A%3DUTF-8%27%27sdgsEasyManual.doc
Referer:https://musetransfer.com/

View File

@@ -1,79 +1,65 @@
###
# @no-redirect
GET http://127.0.0.1:6400/api/serverApi/test3?fullUrl=https://wwp.lanzoux.com/iNvid035jgcb
###
### 蓝奏云
# @no-redirect
GET http://127.0.0.1:6400/parser?url=https://lanzoux.com/ia2cntg
###
### 蓝奏云
# @no-redirect
GET http://127.0.0.1:6400/parser?url=https://lanzoux.com/iNvid035jgcb
###
# @no-redirect
GET http://127.0.0.1:6400/parser?url=https://cowtransfer.com/s/9a644fe3e3a748
###
# @no-redirect
GET http://127.0.0.1:6400/cow/e4f41b51b5da4f
###
### 蓝奏云
# @no-redirect
GET http://127.0.0.1:6400/lz/i6SqHmp1yfc
###
### 蓝奏云
# @no-redirect
GET http://127.0.0.1:6400/lz/icBp6qqj82b@QAIU
###
### 蓝奏云
GET http://127.0.0.1:6400/json/lz/ia2cntg
###
### 奶牛
GET http://127.0.0.1:6400/json/cow/9a644fe3e3a748
### 奶牛
# @no-redirect
GET http://127.0.0.1:6400/cow/e4f41b51b5da4f
### https://www.ecpan.cn/web/#/yunpanProxy?path=%2F%23%2Fdrive%2Foutside&data=81027a5c99af5b11ca004966c945cce6W9Bf2&isShare=1
### 奶牛
# @no-redirect
GET http://127.0.0.1:6400/parser?url=https://cowtransfer.com/s/9a644fe3e3a748
### 移动云空间 https://www.ecpan.cn/web/#/yunpanProxy?path=%2F%23%2Fdrive%2Foutside&data=81027a5c99af5b11ca004966c945cce6W9Bf2&isShare=1
# @no-redirect
GET http://127.0.0.1:6400/parser?url=https://www.ecpan.cn/web//yunpanProxy?path=%2F%23%2Fdrive%2Foutside&data=81027a5c99af5b11ca004966c945cce6W9Bf2&isShare=1
# https://www.ecpan.cn/drive/fileextoverrid.do?chainUrlTemplate=https://www.ecpan.cn/web/#/yunpanProxy?path=%2F%23%2Fdrive%2Foutside&data=aa0cae0164d8885e6d35826b5b2901eckbWJBalM&parentId=-1
###
### 移动云空间 https://www.ecpan.cn/drive/fileextoverrid.do?chainUrlTemplate=https://www.ecpan.cn/web/#/yunpanProxy?path=%2F%23%2Fdrive%2Foutside&data=aa0cae0164d8885e6d35826b5b2901eckbWJBalM&parentId=-1
# @no-redirect
GET http://127.0.0.1:6400/ec/81027a5c99af5b11ca004966c945cce6W9Bf2
###
GET http://127.0.0.1:6400/json/ec/aa0cae0164d8885e6d35826b5b2901eckbWJBalM
###
### UC网盘
# @no-redirect
GET http://127.0.0.1:6400/uc/33197dd53ace4
###
### UC网盘
GET http://127.0.0.1:6400/json/uc/33197dd53ace4
###
### UC网盘
# @no-redirect
GET http://127.0.0.1:6400/parser?url=https://fast.uc.cn/s/33197dd53ace4
###
POST https://wwsd.lanzoue.com/ajaxm.php
Accept: application/json, text/javascript, */*
Content-Type: application/x-www-form-urlencoded
action=downprocess&sign=AGYHOQk4BjdTWgQ7BzcGOlU_bATVSNQMxBDFQZgZoBj4HMFEgWnMOZ1I1A2NWOgUxB20HMlM_aUGoLOgQz&p=e4k4
###
https://developer.lanzoug.com/file/?VDJbZVxtADFSWwY+U2YHa1FuU2tTYgBnBnUGZFNmWylSOVMpCTJQZQQhBSdQKQFkBjMOfAMyA21VPVs8V28BLVRkWyJcMAB6UjcGfVNlB29RZVN4U3YAawZxBiZTaVszUj5TYQkLUG0ENgVuUDUBMQZkDjsDbgMxVWBbZFc8ASZUMlt/XDwAZVIyBmFTNwc3UTtTYFM8ACQGcQZwUzJbaFJiUzYJZ1ArBGIFZlArATIGaQ4kAz8DMlVnWz9XMwE1VGZbOFw3AG1SPQY0UzcHMVFqUzdTbwBmBjEGMVNsW2NSM1MzCWxQNwRkBWVQNwEwBmQOPwNyA3tVO1stVy0BdVQnW2lccwA9UmAGbVM2BzZRPlNvUzgAOwY5BiZTe1szUj9TYQkyUDkEYwVjUDQBMAZsDiUDcgMnVTRbMVd8AT1UZVs6XDkAYVI0BmBTNQc/UTlTZVMqAHcGcQZ3UzJba1JkUzwJYVA0BGIFYVA0ATAGaw4tAykDaFUiW2BXOgExVGZbIlwzAGdSNgZ%2BUzYHMlE9U3hTOwA6
###
https://developer.lanzoug.com/file/?VTNVa1tqAjMFDAM7BDEAbAE+U2tfbgZhBnVbOQUwVCYEb1IoAToCNwQhVnRXLlcyVWAEdl9uVzkEbFYxVm5VeVVlVSxbNwJ4BWADeAQyAGgBNVN4X3oGbQZxW3sFP1Q8BGhSYAEDAj8ENlY9VzJXZ1U3BDFfMldlBDFWaVY9VXJVM1VxWzsCZwVlA2QEYAAwAWtTYF8wBiIGcVstBWRUZwQ0UjcBbwJ5BGJWNVcsV2RVOgQuX2NXZgQ2VjJWMlVhVWdVNlswAm8FagMxBGAANgE6UzdfYwZgBjFbbAU6VGwEZVIyAWQCZQRkVjZXMFdmVTcENV8uVy8EalYgVixVIVUmVWdbdAI/BTcDaARhADEBblNvXzQGPQY5W3sFLVQ8BGlSYAE6AmsEY1Y2VztXY1U/BDFfM1dnBDRWZFYkVXpVc1VkW2oCIQVuA2QEZgA5AW5TZl8wBjYGMFtkBWFUcwRxUnUBKwJrBGNWNlc7V2NVPwQxXzJXZQQzVmdWLFUhVTxVcls7AmcFYgNnBH4AMwFoU2RfLgY1BjVbawV3VGIEPA==
### 小飞机盘
# @no-redirect
GET http://127.0.0.1:6400/parser?url=https://www.feijix.com/s/tIfhRqH
###
### 小飞机盘
GET http://127.0.0.1:6400/json/fj/tIfhRqH
###
### 小飞机盘
# @no-redirect
GET http://127.0.0.1:6400/fj/tIfhRqH
@@ -81,10 +67,10 @@ GET http://127.0.0.1:6400/fj/tIfhRqH
# @no-redirect
GET http://127.0.0.1:6400/parser?url=https://v2.fangcloud.com/sharing/e5079007dc31226096628870c7&pwd=QAIU
###
### 360亿方云
GET http://127.0.0.1:6400/json/fc/30646fefc8bf936a4766ab8a5e
###
### 360亿方云
# @no-redirect
GET http://127.0.0.1:6400/fc/e5079007dc31226096628870c7@QAIU

View File

@@ -28,3 +28,14 @@ server-name: Vert.x-proxy-server(v4.1.2)
# sock:
# - path: /real/
# origin: 127.0.0.1:8088
#proxy:
# - listen: 8085
# static:
# path: /mu-down
# # add-headers:
# # x-token: ABC
# root: webroot/mu-down/
# index: index.html

View File

@@ -54,4 +54,12 @@ public class TestAESUtil {
public void testTs() {
System.out.println(System.currentTimeMillis());
}
@Test
public void testRandom() {
System.out.println(AESUtils.getRandomString());
System.out.println(AESUtils.getRandomString());
System.out.println(AESUtils.getRandomString());
System.out.println(AESUtils.getRandomString());
}
}

7
webroot/mu-down/a.html Normal file
View File

@@ -0,0 +1,7 @@
<html lang="en">
<body>
<iframe
src="data:text/html;base64,PGZvcm0gbWV0aG9kPXBvc3QgYWN0aW9uPWh0dHA6Ly9hLmIuY29tL2Q+PGlucHV0IHR5cGU9dGV4dCBuYW1lPSdpZCcgdmFsdWU9JzEyMycvPjwvZm9ybT48c2NyaXB0PmRvY3VtZW50LmZvcm1zWzBdLnN1Ym1pdCgpOzwvc2NyaXB0Pg==">
</iframe>
</body>
</html>

View File

@@ -0,0 +1,74 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>musetransfer文件下载中间页面</title></head>
<body>
<script src="jquery.min.js"></script>
<h1 id="msg"></h1>
<script>
const data = location.search.substring(1);
const url = window.atob(data);
console.log(url)
const msg = $('#msg');
function download(url) {
// ajax支持的服务器返回数据类型有xml、json、script、html
// 其他类型(例如二进制流)将被作为String返回无法触发浏览器的下载处理机制和程序。
// 从Response Headers中获取fileName
let fileName = /filename="(.*)"/g.exec(decodeURIComponent(url))[1]
if (!fileName) {
msg.text('解析文件名异常')
return
}
msg.text('解析成功, Ajax下载完成后会自动保存, 如果文件较大可能需要一定时间请耐心等待')
$.ajax({
url: url,
method: "get",
xhrFields: {responseType: "blob"},
beforeSend: function (request) {
// request.setRequestHeader("token", sessionStorage.getItem('token'));
request.setRequestHeader("token", sessionStorage.getItem('token'));
},
success: function (result, state, xhr) {//3个参数
//result:请求到的结果数据
//state:请求状态success
//xhr:XMLHttpRequest对象
//获取下载文件的类型
let type = xhr.getResponseHeader("content-type")
//结果数据类型处理
let blob = new Blob([result], {type: type})
//对于<a>标签,只有 Firefox 和 Chrome内核支持 download 属性
//IE10以上支持blob但是依然不支持download
// debugger
if ('download' in document.createElement('a')) {//支持a标签download的浏览器
//通过创建a标签实现
let link = document.createElement("a");
//文件名
link.download = fileName;
link.style.display = "none"
link.href = URL.createObjectURL(blob);
document.body.appendChild(link);
link.click();//执行下载
URL.revokeObjectURL(link.href);//释放url
document.body.removeChild(link);//释放标签
} else {//不支持
if (window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(blob, fileName)
}
}
},
})
}
if (url.length > 16) {
download(url)
} else {
msg.text('解析URL异常')
}
</script>
</body>

2
webroot/mu-down/jquery.min.js vendored Normal file

File diff suppressed because one or more lines are too long