mirror of
https://github.com/qaiu/netdisk-fast-download.git
synced 2025-12-16 20:33:03 +00:00
Compare commits
53 Commits
0.1.5-rele
...
0.1.6-rele
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8108a4dd3f | ||
|
|
56334fa4a2 | ||
|
|
093b337396 | ||
|
|
4bedf4486b | ||
|
|
b700493a6c | ||
|
|
44b1168bb5 | ||
|
|
a351364faf | ||
|
|
6bd075e17c | ||
|
|
1e77b20e44 | ||
|
|
0c2165dbf3 | ||
|
|
7595345e7b | ||
|
|
d13fe1fc21 | ||
|
|
f0269b1687 | ||
|
|
257147dd75 | ||
|
|
6fe824e705 | ||
|
|
f482982a25 | ||
|
|
e3ec81bd9b | ||
|
|
4771a5b5ce | ||
|
|
1292440f95 | ||
|
|
c2052ddbd8 | ||
|
|
f65dfacf4b | ||
|
|
27c2c1ab29 | ||
|
|
b4471dd9c3 | ||
|
|
69d8b645a4 | ||
|
|
67dc452819 | ||
|
|
60df94ce86 | ||
|
|
d6575d5b81 | ||
|
|
2ffa31f655 | ||
|
|
1ae2c89d4f | ||
|
|
2de5790b2a | ||
|
|
e5b892c9d1 | ||
|
|
1ab5059a41 | ||
|
|
1d10e7ab50 | ||
|
|
0477cc4815 | ||
|
|
9d3fce3dee | ||
|
|
e07d427f85 | ||
|
|
998c6e4627 | ||
|
|
e284dfca63 | ||
|
|
cccacde288 | ||
|
|
ee99599d4f | ||
|
|
574d5861f5 | ||
|
|
c3173b7f93 | ||
|
|
6dc647d0be | ||
|
|
ba5ad53529 | ||
|
|
3c5a0d9c9d | ||
|
|
bb1c296872 | ||
|
|
b36e3628bd | ||
|
|
837a265fd8 | ||
|
|
208c430875 | ||
|
|
639f8df534 | ||
|
|
4f5e23ebb6 | ||
|
|
d86c67314c | ||
|
|
d1ba790d05 |
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"java.compile.nullAnalysis.mode": "automatic"
|
||||
}
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal 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.
|
||||
106
README.md
106
README.md
@@ -1,41 +1,49 @@
|
||||
# netdisk-fast-download
|
||||
|
||||
# 网盘快速下载器--直链解析
|
||||
预览地址 https://lz.qaiu.top
|
||||
|
||||
[](https://github.com/qaiu/netdisk-fast-download/actions/workflows/maven.yml)
|
||||
[](https://www.oracle.com/cn/java/technologies/downloads/)
|
||||
[](https://vertx-china.github.io/)
|
||||
[](https://github.com/qaiu/netdisk-fast-download/releases/tag/0.1.6-releases)
|
||||
|
||||
## 网盘支持情况:
|
||||
> 20230722 UC网盘解析失效,需要登录
|
||||
|
||||
|
||||
`网盘名称(网盘标识):`
|
||||
|
||||
- 蓝奏云 (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 +54,10 @@ 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/parser?url=分享链接(&pwd=xxx)
|
||||
http(s)://your_host/json/网盘标识/分享key(@分享密码)
|
||||
3. 特别注意的地方:
|
||||
- 有些网盘的加密分享的密码可以忽略: 如移动云空间,小飞机网盘
|
||||
- 移动云空间(ec)使用parser?url= 解析时因为分享链接比较特殊(链接带有参数且含有#符号)所以要么对#进行转义%23要么直接去掉# 或者URL直接是主机名+'/'跟一个data参数
|
||||
@@ -56,6 +65,17 @@ parser接口可以直接解析分享链接: 加密分享需要加上参数pwd=
|
||||
http://your_host/parser?url=https://www.ecpan.cn/web/%23/yunpanProxy?path=%2F%23%2Fdrive%2Foutside&data=81027a5c99af5b11ca004966c945cce6W9Bf2&isShare=1
|
||||
http://your_host/parser?url=https://www.ecpan.cn/&data=81027a5c99af5b11ca004966c945cce6W9Bf2&isShare=1
|
||||
```
|
||||
json返回数据格式示例:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"success": true,
|
||||
"count": 0,
|
||||
"data": "https://下载链接",
|
||||
"timestamp": 1690733953927
|
||||
}
|
||||
```
|
||||
|
||||
IDEA HttpClient示例:
|
||||
|
||||
@@ -96,20 +116,26 @@ 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 |
|
||||
|
||||
# 打包部署
|
||||
|
||||
## JDK下载(lz.qaiu.top提供直链云解析服务)
|
||||
- [阿里jdk17(Dragonwell17-windows-x86)](https://lz.qaiu.top/ye/iaKtVv-hbECd)
|
||||
- [阿里jdk17(Dragonwell17-linux-x86)](https://lz.qaiu.top/ye/iaKtVv-AbECd)
|
||||
- [阿里jdk17(Dragonwell17-linux-aarch64)](https://lz.qaiu.top/ye/iaKtVv-HbECd)
|
||||
- [123云盘解析有效性测试用-阿里jdk17(Dragonwell17-linux-aarch64)](https://lz.qaiu.top/json/ye/iaKtVv-HbECd)
|
||||
|
||||
## 开发和打包
|
||||
|
||||
```shell
|
||||
@@ -123,17 +149,37 @@ 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
|
||||
> 注意: 如果jdk环境变量的java版本不是17请修改nfd-service-template.xml中的java命令的路径改为实际路径
|
||||
|
||||
## Docker部署
|
||||
TODO
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<name>netdisk-fast-download</name>
|
||||
<description>netdisk fast download service</description>
|
||||
<executable>java</executable>
|
||||
<arguments>-jar ${jar} -server -Xmx128m </arguments>
|
||||
<arguments> -server -Xmx128m -jar ${jar} </arguments>
|
||||
<logpath>${dd}\logs</logpath>
|
||||
<log mode="roll-by-time">
|
||||
<pattern>yyyyMMdd</pattern>
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 -->
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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";
|
||||
|
||||
2
pom.xml
2
pom.xml
@@ -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>
|
||||
|
||||
23
web-front/.gitignore
vendored
Normal file
23
web-front/.gitignore
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/dist
|
||||
dist.zip
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
24
web-front/README.md
Normal file
24
web-front/README.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# nfd-web
|
||||
当前页面修改自开源项目 https://github.com/HurryBy/CloudDiskAnalysis
|
||||
## Project setup
|
||||
```
|
||||
npm install
|
||||
```
|
||||
|
||||
### Compiles and hot-reloads for development
|
||||
```
|
||||
npm run serve
|
||||
```
|
||||
|
||||
### Compiles and minifies for production
|
||||
```
|
||||
npm run build
|
||||
```
|
||||
|
||||
### Lints and fixes files
|
||||
```
|
||||
npm run lint
|
||||
```
|
||||
|
||||
### Customize configuration
|
||||
See [Configuration Reference](https://cli.vuejs.org/config/).
|
||||
5
web-front/babel.config.js
Normal file
5
web-front/babel.config.js
Normal file
@@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
'@vue/cli-plugin-babel/preset'
|
||||
]
|
||||
}
|
||||
19
web-front/jsconfig.json
Normal file
19
web-front/jsconfig.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"module": "esnext",
|
||||
"baseUrl": "./",
|
||||
"moduleResolution": "node",
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"src/*"
|
||||
]
|
||||
},
|
||||
"lib": [
|
||||
"esnext",
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"scripthost"
|
||||
]
|
||||
}
|
||||
}
|
||||
13855
web-front/package-lock.json
generated
Normal file
13855
web-front/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
50
web-front/package.json
Normal file
50
web-front/package.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"name": "nfd-web",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
"build": "vue-cli-service build",
|
||||
"lint": "vue-cli-service lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^1.2.2",
|
||||
"core-js": "^3.8.3",
|
||||
"element-ui": "^2.15.12",
|
||||
"vue": "^2.6.14",
|
||||
"vue-clipboard2": "^0.3.3",
|
||||
"vue-json-viewer": "^2.2.22"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.12.16",
|
||||
"@babel/eslint-parser": "^7.12.16",
|
||||
"@vue/cli-plugin-babel": "~5.0.0",
|
||||
"@vue/cli-plugin-eslint": "~5.0.0",
|
||||
"@vue/cli-service": "~5.0.0",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-plugin-vue": "^8.0.3",
|
||||
"vue-template-compiler": "^2.6.14",
|
||||
|
||||
"compression-webpack-plugin": "^6.1.1",
|
||||
"filemanager-webpack-plugin": "2.0.5"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"root": true,
|
||||
"env": {
|
||||
"node": true
|
||||
},
|
||||
"extends": [
|
||||
"plugin:vue/essential",
|
||||
"eslint:recommended"
|
||||
],
|
||||
"parserOptions": {
|
||||
"parser": "@babel/eslint-parser"
|
||||
},
|
||||
"rules": {}
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions",
|
||||
"not dead"
|
||||
]
|
||||
}
|
||||
BIN
web-front/public/avator.png
Normal file
BIN
web-front/public/avator.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
BIN
web-front/public/favicon.ico
Normal file
BIN
web-front/public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
170
web-front/public/index.html
Normal file
170
web-front/public/index.html
Normal file
@@ -0,0 +1,170 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>Netdisk fast download</title>
|
||||
<meta name="keywords"
|
||||
content="">
|
||||
<meta name="description"
|
||||
content="">
|
||||
<style>
|
||||
.page-loading-wrap {
|
||||
padding: 120px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.la-timer,
|
||||
.la-timer>div {
|
||||
position: relative;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.la-timer {
|
||||
display: block;
|
||||
font-size: 0;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.la-timer.la-dark {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.la-timer>div {
|
||||
display: inline-block;
|
||||
float: none;
|
||||
background-color: currentColor;
|
||||
border: 0 solid currentColor;
|
||||
}
|
||||
|
||||
.la-timer {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.la-timer>div {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
background: transparent;
|
||||
border-width: 2px;
|
||||
border-radius: 100%;
|
||||
}
|
||||
|
||||
.la-timer>div:before,
|
||||
.la-timer>div:after {
|
||||
position: absolute;
|
||||
top: 14px;
|
||||
left: 14px;
|
||||
display: block;
|
||||
width: 2px;
|
||||
margin-top: -1px;
|
||||
margin-left: -1px;
|
||||
content: "";
|
||||
background: currentColor;
|
||||
border-radius: 2px;
|
||||
-webkit-transform-origin: 1px 1px 0;
|
||||
-moz-transform-origin: 1px 1px 0;
|
||||
-ms-transform-origin: 1px 1px 0;
|
||||
-o-transform-origin: 1px 1px 0;
|
||||
transform-origin: 1px 1px 0;
|
||||
-webkit-animation: timer-loader 1250ms infinite linear;
|
||||
-moz-animation: timer-loader 1250ms infinite linear;
|
||||
-o-animation: timer-loader 1250ms infinite linear;
|
||||
animation: timer-loader 1250ms infinite linear;
|
||||
-webkit-animation-delay: -625ms;
|
||||
-moz-animation-delay: -625ms;
|
||||
-o-animation-delay: -625ms;
|
||||
animation-delay: -625ms;
|
||||
}
|
||||
|
||||
.la-timer>div:before {
|
||||
height: 12px;
|
||||
}
|
||||
|
||||
.la-timer>div:after {
|
||||
height: 8px;
|
||||
-webkit-animation-duration: 15s;
|
||||
-moz-animation-duration: 15s;
|
||||
-o-animation-duration: 15s;
|
||||
animation-duration: 15s;
|
||||
-webkit-animation-delay: -7.5s;
|
||||
-moz-animation-delay: -7.5s;
|
||||
-o-animation-delay: -7.5s;
|
||||
animation-delay: -7.5s;
|
||||
}
|
||||
|
||||
@-webkit-keyframes timer-loader {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@-moz-keyframes timer-loader {
|
||||
0% {
|
||||
-moz-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
-moz-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@-o-keyframes timer-loader {
|
||||
0% {
|
||||
-o-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
-o-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes timer-loader {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
-moz-transform: rotate(0deg);
|
||||
-o-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
-moz-transform: rotate(360deg);
|
||||
-o-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="app">
|
||||
<div class="page-loading-wrap">
|
||||
<div style="color: #4e9ff5" class="la-timer">
|
||||
<div></div>
|
||||
</div>
|
||||
<h4 style="margin-top:20px;font-size:14px;font-weight:400;color: #515a6e;">正在加载资源...</h4>
|
||||
</div>
|
||||
</div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
||||
242
web-front/src/App.vue
Normal file
242
web-front/src/App.vue
Normal file
@@ -0,0 +1,242 @@
|
||||
<template>
|
||||
<div id="app">
|
||||
<el-row :gutter="20">
|
||||
<el-card class="box-card">
|
||||
<div class="demo-basic--circle">
|
||||
<div class="block" style="text-align: center;">
|
||||
<el-avatar :size="150" :src="avatar"></el-avatar>
|
||||
</div>
|
||||
</div>
|
||||
<h3 style="text-align: center;">NFD网盘直链解析(API演示)</h3>
|
||||
<div class="typo">
|
||||
<p><strong>项目地址 </strong><a href="https://github.com/qaiu/netdisk-fast-download" target="_blank"
|
||||
rel="nofollow"><u>点我跳转</u></a></p>
|
||||
<p><strong>当前页面修改自开源项目</strong><a href="https://github.com/HurryBy/CloudDiskAnalysis" target="_blank"
|
||||
rel="nofollow"><u>CloudDiskAnalysis</u></a></p>
|
||||
<p><strong>目前支持 </strong>已支持蓝奏云/奶牛快传/移动云云空间/UC网盘(暂时失效)/小飞机盘/亿方云/123云盘</p>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="main" v-loading="isLoading">
|
||||
<div class="grid-content">
|
||||
<el-input placeholder="请粘贴分享链接" v-model="link" id="url" lass="input-with-select">
|
||||
<strong slot="prepend">分享链接</strong>
|
||||
<el-button slot="append" @click="onSubmit">解析</el-button>
|
||||
</el-input>
|
||||
<el-input placeholder="请输入密码" v-model="password" id="url" lass="input-with-select"></el-input>
|
||||
<el-input v-show="respData.data" placeholder="解析地址" :value="getLink2" id="url" lass="input-with-select">
|
||||
<el-button slot="append" v-clipboard:copy="getLink2"
|
||||
v-clipboard:success="onCopy"
|
||||
v-clipboard:error="onError">点我复制</el-button>
|
||||
</el-input>
|
||||
</div>
|
||||
<div v-show="respData.code" style="margin-top: 10px">
|
||||
<strong>解析结果: </strong>
|
||||
<json-viewer
|
||||
:value="respData"
|
||||
:expand-depth=5
|
||||
copyable
|
||||
boxed
|
||||
sort
|
||||
/>
|
||||
<a :href="downUrl" v-show="downUrl">点击下载</a>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from 'axios'
|
||||
/*
|
||||
蓝奏云 (lz)
|
||||
登录, 上传, 下载, 分享
|
||||
直链解析
|
||||
奶牛快传 (cow)
|
||||
登录, 上传, 下载, 分享
|
||||
直链解析
|
||||
移动云空间 (ec)
|
||||
登录, 上传, 下载, 分享
|
||||
直链解析
|
||||
UC网盘 (uc)似乎已经失效,需要登录
|
||||
登录, 上传, 下载, 分享
|
||||
直链解析
|
||||
小飞机网盘 (fj)
|
||||
登录, 上传, 下载, 分享
|
||||
直链解析
|
||||
亿方云 (fc)
|
||||
登录, 上传, 下载, 分享
|
||||
直链解析
|
||||
123云盘 (ye)
|
||||
登录, 上传, 下载,, 分享
|
||||
*/
|
||||
export default {
|
||||
name: 'App',
|
||||
data() {
|
||||
return {
|
||||
link: "",
|
||||
password: "",
|
||||
isLoading: false,
|
||||
downUrl: null,
|
||||
avatar: "https://q2.qlogo.cn/headimg_dl?dst_uin=736226400&spec=640",
|
||||
select: "lz",
|
||||
respData: {},
|
||||
panList: [
|
||||
{
|
||||
name: "蓝奏云",
|
||||
value: 'lz'
|
||||
},
|
||||
{
|
||||
name: "奶牛快传",
|
||||
value: 'cow'
|
||||
},
|
||||
{
|
||||
name: "移动云空间",
|
||||
value: 'ec'
|
||||
},
|
||||
{
|
||||
name: "UC网盘",
|
||||
value: 'uc',
|
||||
disabled: true
|
||||
},
|
||||
{
|
||||
name: "小飞机网盘",
|
||||
value: 'fj'
|
||||
},
|
||||
{
|
||||
name: "360亿方云",
|
||||
value: 'fc'
|
||||
},
|
||||
{
|
||||
name: "123云盘",
|
||||
value: 'ye'
|
||||
},
|
||||
],
|
||||
getLink: '',
|
||||
getLink2: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onSubmit() {
|
||||
if (!this.link.startsWith("https://")) {
|
||||
this.$message.error("请输入有效链接!")
|
||||
return
|
||||
}
|
||||
this.isLoading = true
|
||||
this.downUrl = ''
|
||||
this.respData = {}
|
||||
this.getLink2 = `${location.protocol}//${location.host}/parser?url=${this.link}`
|
||||
// this.getLink = `${location.protocol}//${location.host}/api/json/parser?url=${this.link}`
|
||||
this.getLink = `${location.protocol}//${location.host}/json/parser?url=${this.link}`
|
||||
if (this.password) {
|
||||
this.getLink += `&pwd=${this.password}`
|
||||
}
|
||||
axios.get(this.getLink).then(
|
||||
response => {
|
||||
this.isLoading = false
|
||||
this.respData = response.data
|
||||
if (response.data.code === 200) {
|
||||
this.$message({
|
||||
message: response.data.msg,
|
||||
type: 'success'
|
||||
})
|
||||
this.downUrl = response.data.data
|
||||
} else {
|
||||
this.$message.error(response.data.msg)
|
||||
}
|
||||
},
|
||||
error => {
|
||||
this.isLoading = false
|
||||
this.$message.error(error.message)
|
||||
}
|
||||
)
|
||||
},
|
||||
onCopy(){
|
||||
this.$message.success('复制成功')
|
||||
},
|
||||
onError(){
|
||||
this.$message.error('复制失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
#app {
|
||||
font-family: 'Avenir', Helvetica, Arial, sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
color: #2c3e50;
|
||||
margin: auto;
|
||||
padding: 1em;
|
||||
max-width: 900px;
|
||||
}
|
||||
|
||||
::selection {
|
||||
background: rgba(0, 149, 255, .1);
|
||||
}
|
||||
|
||||
body:before {
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
opacity: .3;
|
||||
z-index: -1;
|
||||
content: "";
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
.grid-content {
|
||||
margin-top: 1em;
|
||||
border-radius: 4px;
|
||||
min-height: 50px;
|
||||
}
|
||||
|
||||
.el-select .el-input {
|
||||
width: 130px;
|
||||
}
|
||||
|
||||
.input-with-select .el-input-group__prepend {
|
||||
background-color: #fff;
|
||||
|
||||
}
|
||||
|
||||
.box-card {
|
||||
margin-top: 4em !important;
|
||||
margin-bottom: 4em !important;
|
||||
opacity: .8;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 700px) {
|
||||
.box-card {
|
||||
margin-top: 1em !important;
|
||||
margin-bottom: 1em !important;
|
||||
}
|
||||
}
|
||||
|
||||
.download h3 {
|
||||
margin-top: 2em;
|
||||
}
|
||||
|
||||
.download button {
|
||||
margin-right: 0.5em;
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
|
||||
.typo {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.typo a {
|
||||
color: #2c3e50;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
hr {
|
||||
height: 10px;
|
||||
margin-bottom: .8em;
|
||||
border: none;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, .12);
|
||||
}
|
||||
</style>
|
||||
19
web-front/src/main.js
Normal file
19
web-front/src/main.js
Normal file
@@ -0,0 +1,19 @@
|
||||
import Vue from 'vue'
|
||||
import App from './App.vue'
|
||||
import ElementUI from 'element-ui'
|
||||
import 'element-ui/lib/theme-chalk/index.css'
|
||||
import VueClipboard from 'vue-clipboard2'
|
||||
import JsonViewer from 'vue-json-viewer'
|
||||
|
||||
// Import JsonViewer as a Vue.js plugin
|
||||
Vue.use(JsonViewer)
|
||||
|
||||
// or
|
||||
// components: {JsonViewer}
|
||||
|
||||
Vue.use(VueClipboard)
|
||||
Vue.config.productionTip = false
|
||||
Vue.use(ElementUI)
|
||||
new Vue({
|
||||
render: h => h(App),
|
||||
}).$mount('#app')
|
||||
59
web-front/vue.config.js
Normal file
59
web-front/vue.config.js
Normal file
@@ -0,0 +1,59 @@
|
||||
const { defineConfig } = require('@vue/cli-service')
|
||||
const path = require("path");
|
||||
module.exports = defineConfig({
|
||||
transpileDependencies: true,
|
||||
lintOnSave: false
|
||||
})
|
||||
|
||||
function resolve(dir) {
|
||||
return path.join(__dirname, dir)
|
||||
}
|
||||
const CompressionPlugin = require('compression-webpack-plugin');
|
||||
const FileManagerPlugin = require('filemanager-webpack-plugin')
|
||||
|
||||
module.exports = {
|
||||
outputDir: 'nfd-front',
|
||||
devServer: {
|
||||
host: '127.0.0.1',
|
||||
port: 6444,
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'http://127.0.0.1:6400', // 请求本地
|
||||
changeOrigin: true,
|
||||
pathRewrite: {
|
||||
'^/api': '/' //本身的接口地址没有 '/api' 这种通用前缀,所以要rewrite,如果本身有则去掉
|
||||
},
|
||||
ws: true
|
||||
},
|
||||
}
|
||||
},
|
||||
configureWebpack: {
|
||||
// provide the app's title in webpack's name field, so that
|
||||
// it can be accessed in index.html to inject the correct title.
|
||||
name: 'Netdisk fast download',
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': resolve('src')
|
||||
}
|
||||
},
|
||||
|
||||
plugins: [
|
||||
new CompressionPlugin({
|
||||
test: /\.js$|\.html$|\.css/, // 匹配文件
|
||||
threshold: 10240 // 对超过10k文件压缩
|
||||
}),
|
||||
new FileManagerPlugin({ //初始化 filemanager-webpack-plugin 插件实例
|
||||
onEnd: {
|
||||
mkdir: ['./nfd-front'],
|
||||
delete: [ //首先需要删除项目根目录下的dist.zip
|
||||
'./nfd-front.zip',
|
||||
],
|
||||
archive: [ //然后我们选择dist文件夹将之打包成dist.zip并放在根目录
|
||||
{source: './nfd-front', destination: './nfd-front.zip'},
|
||||
]
|
||||
}
|
||||
})
|
||||
]
|
||||
},
|
||||
|
||||
}
|
||||
@@ -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,9 +58,14 @@
|
||||
<dependency>
|
||||
<groupId>cn.qaiu</groupId>
|
||||
<artifactId>core-database</artifactId>
|
||||
<version>0.1.5</version>
|
||||
<version>0.1.6</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.openjdk.nashorn/nashorn-core -->
|
||||
<dependency>
|
||||
<groupId>org.openjdk.nashorn</groupId>
|
||||
<artifactId>nashorn-core</artifactId>
|
||||
<version>15.4</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -133,8 +138,7 @@
|
||||
</goals>
|
||||
<configuration>
|
||||
<!--打包时排除的依赖作用域-->
|
||||
<excludeScope>test</excludeScope>
|
||||
<excludeScope>provided</excludeScope>
|
||||
<includeScope>runtime</includeScope>
|
||||
<outputDirectory>
|
||||
${packageDirectory}/lib/
|
||||
</outputDirectory>
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ public interface IPanTool {
|
||||
return new CowTool();
|
||||
} else if (url.startsWith(EcTool.SHARE_URL_PREFIX)) {
|
||||
return new EcTool();
|
||||
} else if (url.startsWith(FcTool.SHARE_URL_PREFIX)) {
|
||||
} else if (url.startsWith(FcTool.SHARE_URL_PREFIX0)) {
|
||||
return new FcTool();
|
||||
} else if (url.startsWith(UcTool.SHARE_URL_PREFIX)) {
|
||||
return new UcTool();
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,16 +21,18 @@ import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* 亿方云
|
||||
* 360亿方云
|
||||
*/
|
||||
public class FcTool implements IPanTool {
|
||||
|
||||
public static final String SHARE_URL_PREFIX0 = "https://v2.fangcloud.com/s";
|
||||
public static final String SHARE_URL_PREFIX = "https://v2.fangcloud.com/sharing/";
|
||||
public static final String SHARE_URL_PREFIX2 = "https://v2.fangcloud.cn/sharing/";
|
||||
private static final String DOWN_REQUEST_URL = "https://v2.fangcloud.cn/apps/files/download?file_id={fid}" +
|
||||
"&scenario=share&unique_name={uname}";
|
||||
|
||||
public Future<String> parse(String data, String code) {
|
||||
data = data.replace("share","sharing");
|
||||
String dataKey = CommonUtils.adaptShortPaths(SHARE_URL_PREFIX, data);
|
||||
|
||||
Promise<String> promise = Promise.promise();
|
||||
@@ -56,21 +59,21 @@ public class FcTool implements IPanTool {
|
||||
.set("requesttoken", token)
|
||||
.set("password", code)).onSuccess(res2 -> {
|
||||
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);
|
||||
sClient.getAbs(res2.getHeader("Location")).send().onSuccess(res3 ->
|
||||
getDownURL(dataKey, promise, res3, sClient))
|
||||
.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();
|
||||
}
|
||||
|
||||
private static void getDownURL(String dataKey, Promise<String> promise, HttpResponse<Buffer> res,
|
||||
private void getDownURL(String dataKey, Promise<String> promise, HttpResponse<Buffer> res,
|
||||
WebClientSession sClient) {
|
||||
// 从HTML中找到文件id
|
||||
String html = res.bodyAsString();
|
||||
@@ -102,6 +105,6 @@ public class FcTool implements IPanTool {
|
||||
return;
|
||||
}
|
||||
promise.complete(resJson.getString("download_url"));
|
||||
});
|
||||
}).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Fc", dataKey, t)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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,19 +50,19 @@ 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();
|
||||
}
|
||||
|
||||
private static void getDownURL(Promise<String> promise, String code, String key, WebClient client, String sign) {
|
||||
private void getDownURL(Promise<String> promise, String code, String key, WebClient client, String sign) {
|
||||
MultiMap headers = MultiMap.caseInsensitiveMultiMap();
|
||||
var userAgent2 = "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, " +
|
||||
"like " +
|
||||
@@ -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)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,14 +2,21 @@ 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.JsExecUtils;
|
||||
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.ArrayUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openjdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
|
||||
import javax.script.ScriptException;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.Base64;
|
||||
import java.util.Map;
|
||||
@@ -19,12 +26,24 @@ 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";
|
||||
/*
|
||||
private static final String GET_FILE_INFO_URL = "https://www.123pan.com/a/api/share/get?limit=100&next=1&orderBy" +
|
||||
"=file_name&orderDirection=asc&shareKey={shareKey}&SharePwd={pwd}&ParentFileId=0&Page=1&event" +
|
||||
"=homeListFile&operateType=1";
|
||||
private static final String GET_FILE_INFO_URL="https://www.123pan
|
||||
.com/b/api/share/get?limit=100&next=1&orderBy=file_name&orderDirection=asc" +
|
||||
"&shareKey={shareKey}&SharePwd={pwd}&ParentFileId=0&Page=1&event=homeListFile&operateType=1&auth-key
|
||||
={authKey}";
|
||||
*/
|
||||
|
||||
private static final String GET_FILE_INFO_URL = "https://www.123pan.com/b/api/share/get?limit=100&next=1&orderBy" +
|
||||
"=file_name&orderDirection=asc" +
|
||||
"&shareKey={shareKey}&SharePwd={pwd}&ParentFileId=0&Page=1&event=homeListFile&operateType=1";
|
||||
private static final String DOWNLOAD_API_URL = "https://www.123pan.com/b/api/share/download/info?{authK}={authV}";
|
||||
|
||||
public Future<String> parse(String data, String code) {
|
||||
|
||||
@@ -39,7 +58,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 +67,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");
|
||||
@@ -58,16 +77,20 @@ public class YeTool implements IPanTool {
|
||||
client.getAbs(UriTemplate.of(GET_FILE_INFO_URL))
|
||||
.setTemplateParam("shareKey", shareKey)
|
||||
.setTemplateParam("pwd", code)
|
||||
// .setTemplateParam("authKey", AESUtils.getAuthKey("/b/api/share/get"))
|
||||
.putHeader("Platform", "web")
|
||||
.putHeader("App-Version", "3")
|
||||
.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,28 +100,82 @@ 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);
|
||||
client.postAbs("https://www.123pan.com/a/api/share/download/info").sendJsonObject(reqBodyJson).onSuccess(res2 -> {
|
||||
JsonObject downURLJson = res2.bodyAsJsonObject();
|
||||
System.out.println(downURLJson);
|
||||
if (downURLJson.getInteger("code") != 0) {
|
||||
return;
|
||||
}
|
||||
String downURL = downURLJson.getJsonObject("data").getString("DownloadURL");
|
||||
try {
|
||||
Map<String, String> urlParams = CommonUtils.getURLParams(downURL);
|
||||
String params = urlParams.get("params");
|
||||
byte[] decodeByte = Base64.getDecoder().decode(params);
|
||||
promise.complete(new String(decodeByte));
|
||||
} catch (MalformedURLException e) {
|
||||
promise.fail("urlParams解析异常" + e.getMessage());
|
||||
}
|
||||
});
|
||||
log.info(reqBodyJson.encodePrettily());
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
// {"ShareKey":"iaKtVv-6OECd","FileID":2193732,"S3keyFlag":"1811834632-0","Size":4203111,
|
||||
// "Etag":"69c94adbc0b9190cf23c4e958d8c7c53"}
|
||||
jsonObject.put("ShareKey", reqBodyJson.getString("ShareKey"));
|
||||
jsonObject.put("FileID", reqBodyJson.getInteger("FileId"));
|
||||
jsonObject.put("S3keyFlag", reqBodyJson.getString("S3KeyFlag"));
|
||||
jsonObject.put("Size", reqBodyJson.getInteger("Size"));
|
||||
jsonObject.put("Etag", reqBodyJson.getString("Etag"));
|
||||
|
||||
// 调用JS文件获取签名
|
||||
ScriptObjectMirror getSign;
|
||||
try {
|
||||
getSign = JsExecUtils.executeJs("getSign", "/b/api/share/download/info");
|
||||
} catch (ScriptException | IOException | NoSuchMethodException e) {
|
||||
promise.fail(e);
|
||||
return;
|
||||
}
|
||||
if (getSign == null) {
|
||||
promise.fail(ArrayUtils.toString(getSign));
|
||||
return;
|
||||
}
|
||||
log.info("ye getSign: {}={}", getSign.get("0").toString(), getSign.get("1").toString());
|
||||
|
||||
client.postAbs(UriTemplate.of(DOWNLOAD_API_URL))
|
||||
.setTemplateParam("authK", getSign.get("0").toString())
|
||||
.setTemplateParam("authV", getSign.get("1").toString())
|
||||
.putHeader("Platform", "web")
|
||||
.putHeader("App-Version", "3")
|
||||
.sendJsonObject(jsonObject).onSuccess(res2 -> {
|
||||
JsonObject downURLJson = res2.bodyAsJsonObject();
|
||||
|
||||
try {
|
||||
if (downURLJson.getInteger("code") != 0) {
|
||||
promise.fail("Ye: downURLJson返回值异常->" + downURLJson);
|
||||
return;
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
promise.fail("Ye: downURLJson格式异常->" + downURLJson);
|
||||
return;
|
||||
}
|
||||
String downURL = downURLJson.getJsonObject("data").getString("DownloadURL");
|
||||
try {
|
||||
Map<String, String> urlParams = CommonUtils.getURLParams(downURL);
|
||||
String params = urlParams.get("params");
|
||||
byte[] decodeByte = Base64.getDecoder().decode(params);
|
||||
String downUrl2 = new String(decodeByte);
|
||||
|
||||
// 获取直链
|
||||
client.getAbs(downUrl2).send().onSuccess(res3 -> {
|
||||
JsonObject res3Json = res3.bodyAsJsonObject();
|
||||
try {
|
||||
if (res3Json.getInteger("code") != 0) {
|
||||
promise.fail("Ye: downUrl2返回值异常->" + res3Json);
|
||||
return;
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
promise.fail("Ye: downUrl2格式异常->" + downURLJson);
|
||||
return;
|
||||
}
|
||||
|
||||
promise.complete(res3Json.getJsonObject("data").getString("redirect_url"));
|
||||
|
||||
}).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Ye",
|
||||
reqBodyJson.encodePrettily(), t)));
|
||||
|
||||
} catch (MalformedURLException e) {
|
||||
promise.fail("urlParams解析异常" + e.getMessage());
|
||||
}
|
||||
}).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Ye",
|
||||
reqBodyJson.encodePrettily(), t)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,12 +4,16 @@ import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.Key;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Base64;
|
||||
import java.util.Date;
|
||||
import java.util.HexFormat;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* AES加解密工具类
|
||||
@@ -236,4 +240,50 @@ 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);
|
||||
}
|
||||
|
||||
|
||||
//=============================== 123pan加密相关 ===============================
|
||||
|
||||
public static String getMD5Str(String str) {
|
||||
byte[] digest;
|
||||
try {
|
||||
MessageDigest md5 = MessageDigest.getInstance("md5");
|
||||
digest = md5.digest(str.getBytes(StandardCharsets.UTF_8));
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
//16是表示转换为16进制数
|
||||
return new BigInteger(1, digest).toString(16);
|
||||
}
|
||||
|
||||
public static String getAuthKey(String _0x2207af) {
|
||||
String _0x467baa = "web";
|
||||
int _0x4965f1 = 3;
|
||||
|
||||
String _0x430930 = String.valueOf(Math.round(0x989680 * Math.random()));
|
||||
String _0x53928f = String.valueOf(new Date().getTime() / 0x3e8);
|
||||
String _0x49ec94 = getMD5Str(_0x53928f + "|" + _0x430930 + "|" + _0x2207af + "|" + _0x467baa + "|" + _0x4965f1
|
||||
+ "|8-8D$sL8gPjom7bk#cY");
|
||||
|
||||
return _0x53928f + "-" + _0x430930 + "-" + _0x49ec94;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package cn.qaiu.lz.common.util;
|
||||
|
||||
import org.openjdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
|
||||
import javax.script.Invocable;
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptEngineManager;
|
||||
import javax.script.ScriptException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* 执行Js脚本
|
||||
* @author <a href="https://qaiu.top">QAIU</a>
|
||||
* @date 2023/7/29 17:35
|
||||
*/
|
||||
public class JsExecUtils {
|
||||
private static final String JS_PATH = "/js/ye123.js";
|
||||
|
||||
/**
|
||||
* 调用js文件
|
||||
*/
|
||||
public static ScriptObjectMirror executeJs(String functionName, Object... args) throws ScriptException,
|
||||
IOException, NoSuchMethodException {
|
||||
ScriptEngineManager engineManager = new ScriptEngineManager();
|
||||
ScriptEngine engine = engineManager.getEngineByName("JavaScript"); // 得到脚本引擎
|
||||
//获取文件所在的相对路径
|
||||
URL resource = JsExecUtils.class.getResource("/");
|
||||
if (resource == null) {
|
||||
throw new ScriptException("js resource path is null");
|
||||
}
|
||||
String path = resource.getPath();
|
||||
String reader = path + JS_PATH;
|
||||
FileReader fReader = new FileReader(reader);
|
||||
engine.eval(fReader);
|
||||
fReader.close();
|
||||
|
||||
Invocable inv = (Invocable) engine;
|
||||
//调用js中的方法
|
||||
return (ScriptObjectMirror) inv.invokeFunction(functionName, args);
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
@@ -35,7 +34,7 @@ public class ServerApi {
|
||||
return userService.login(user);
|
||||
}
|
||||
|
||||
@RouteMapping(value = "/parser", method = RouteMethod.GET)
|
||||
@RouteMapping(value = "/parser", method = RouteMethod.GET, order = 4)
|
||||
public Future<Void> parse(HttpServerResponse response, HttpServerRequest request, String url, String pwd) {
|
||||
|
||||
Promise<Void> promise = Promise.promise();
|
||||
@@ -54,8 +53,17 @@ public class ServerApi {
|
||||
return promise.future();
|
||||
}
|
||||
|
||||
@RouteMapping(value = "/json/parser", method = RouteMethod.GET, order = 3)
|
||||
public Future<String> parseJson(HttpServerResponse response, HttpServerRequest request, String url, String pwd) {
|
||||
if (url.contains(EcTool.SHARE_URL_PREFIX)) {
|
||||
// 默认读取Url参数会被截断手动获取一下其他参数
|
||||
url = EcTool.SHARE_URL_PREFIX + request.getParam("data");
|
||||
}
|
||||
return IPanTool.shareURLPrefixMatching(url).parse(url, pwd);
|
||||
}
|
||||
|
||||
@RouteMapping(value = "/:type/:key", method = RouteMethod.GET)
|
||||
|
||||
@RouteMapping(value = "/:type/:key", method = RouteMethod.GET, order = 1)
|
||||
public void parseKey(HttpServerResponse response, String type, String key) {
|
||||
String code = "";
|
||||
if (key.contains("@")) {
|
||||
@@ -71,7 +79,7 @@ public class ServerApi {
|
||||
});
|
||||
}
|
||||
|
||||
@RouteMapping(value = "/json/:type/:key", method = RouteMethod.GET)
|
||||
@RouteMapping(value = "/json/:type/:key", method = RouteMethod.GET, order = 2)
|
||||
public Future<String> parseKeyJson(HttpServerResponse response, String type, String key) {
|
||||
String code = "";
|
||||
if (key.contains("@")) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
active: dev
|
||||
# 框架版本号 和主版本号
|
||||
version_vertx: 4.4.1
|
||||
version_app: 0.1.5
|
||||
version_app: 0.1.6
|
||||
# 公司名称 -> LOGO版权文字
|
||||
copyright: QAIU
|
||||
|
||||
@@ -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==
|
||||
|
||||
|
||||
|
||||
56
web-service/src/main/resources/http-tools/pan-mu.http
Normal file
56
web-service/src/main/resources/http-tools/pan-mu.http
Normal 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/
|
||||
@@ -10,7 +10,7 @@ content-type: application/json
|
||||
{"pwd_id":"33197dd53ace4","passcode":"","share_for_transfer":true}
|
||||
|
||||
### UCpan 第二步 获取fid,share_fid_token GET传参pwd_id,passcode,stoken
|
||||
https://pc-api.uc.cn/1/clouddrive/transfer_share/detail?pwd_id=33197dd53ace4&passcode=&stoken=oPz47hsgQXQdDYimsP4kBMi8aLv40X378IZOiBsnfLU%3D
|
||||
https://pc-api.uc.cn/1/clouddrive/transfer_share/detail?pwd_id=33197dd53ace4&passcode=&stoken=W5b1n2jeFld5RmIusaVOr3vA0vVSCWYQ7Mz8bT2coZM%3D
|
||||
content-type: application/json
|
||||
|
||||
### UCpan 第二步获取下载链接 POST json传入fids(fid),pwd_id,stoken,fids_token(share_fid_token)
|
||||
@@ -22,8 +22,13 @@ content-type: application/json
|
||||
"54c3cd90ed3e45119bb96ed99a562d40"
|
||||
],
|
||||
"pwd_id": "33197dd53ace4",
|
||||
"stoken": "oPz47hsgQXQdDYimsP4kBMi8aLv40X378IZOiBsnfLU=",
|
||||
"stoken": "W5b1n2jeFld5RmIusaVOr3vA0vVSCWYQ7Mz8bT2coZM=",
|
||||
"fids_token": [
|
||||
"ff9f5b5c94df9d08c8dd3b7948fc5e20"
|
||||
"4cb5eabb0ce5a26d12ae5ab8acf68aec"
|
||||
]
|
||||
}
|
||||
|
||||
###
|
||||
# @no-redirect
|
||||
https://dl-uf-zb.pds.uc.cn/l3PNAKfz/64623447/646b0de6e9f13000c9b14ba182b805312795a82a/646b0de6717e1bfa5bb44dd2a456f103c5177850?Expires=1690188688&OSSAccessKeyId=LTAIyYfxTqY7YZsg&Signature=gB3rN%2FxPal3ZpReRkB1M4cnvGF4%3D&x-oss-traffic-limit=503316480&response-content-disposition=attachment%3B%20filename%3DC%23%20Shell%20%28C%23%20Offline%20Compiler%29_2.5.16.apks&callback-var=eyJ4OmF1IjoiLSIsIng6c3AiOiIxOTkiLCJ4OnRva2VuIjoiMi0wNDBjYjFjMDNjNzU1YWY1NDc0NjkxNjNmOTYzYWY2NC0yLTctNjE0NDAtZGFjYjM2NjViYmFhNGY1ZTlkMzc4MDBlYzY0MDMxNjAtYTU2MGJiMmU1MzhlNzY0OTFkMDY1MjA2OGRiNmEzMzEiLCJ4OnR0bCI6IjEwODAwIn0%3D&callback=eyJjYWxsYmFja0JvZHlUeXBlIjoiYXBwbGljYXRpb24vanNvbiIsImNhbGxiYWNrU3RhZ2UiOiJiZWZvcmUtZXhlY3V0ZSIsImNhbGxiYWNrRmFpbHVyZUFjdGlvbiI6Imlnbm9yZSIsImNhbGxiYWNrVXJsIjoiaHR0cHM6Ly9hdXRoLWNkbi51Yy5jbi9vdXRlci9vc3MvY2hlY2twbGF5IiwiY2FsbGJhY2tCb2R5Ijoie1wiaG9zdFwiOiR7aHR0cEhlYWRlci5ob3N0fSxcInNpemVcIjoke3NpemV9LFwicmFuZ2VcIjoke2h0dHBIZWFkZXIucmFuZ2V9LFwicmVmZXJlclwiOiR7aHR0cEhlYWRlci5yZWZlcmVyfSxcImNvb2tpZVwiOiR7aHR0cEhlYWRlci5jb29raWV9LFwibWV0aG9kXCI6JHtodHRwSGVhZGVyLm1ldGhvZH0sXCJpcFwiOiR7Y2xpZW50SXB9LFwicG9ydFwiOiR7Y2xpZW50UG9ydH0sXCJvYmplY3RcIjoke29iamVjdH0sXCJzcFwiOiR7eDpzcH0sXCJ0b2tlblwiOiR7eDp0b2tlbn0sXCJhdVwiOiR7eDphdX0sXCJ0dGxcIjoke3g6dHRsfSxcImNsaWVudF90b2tlblwiOiR7cXVlcnlTdHJpbmcuY2xpZW50X3Rva2VufX0ifQ%3D%3D&ud=4-0-5-0-6-N-3-ft-0-2&__pus=7576a6d3a511ad7b4c5649a1d89c29ffAAQ06zBxHWghrwEbKRdqBrhXssuYiMIwLLVzi1f2K6qnSL95A79GIxXDEPlYS3NaPjDWOcWVuvbQ3HqTfvqRKr29
|
||||
#Cookie: __pus=7576a6d3a511ad7b4c5649a1d89c29ffAAQ06zBxHWghrwEbKRdqBrhXssuYiMIwLLVzi1f2K6qnSL95A79GIxXDEPlYS3NaPjDWOcWVuvbQ3HqTfvqRKr29
|
||||
|
||||
@@ -37,9 +37,9 @@ Accept: application/json, text/plain, */*
|
||||
### 获取下载文件URL
|
||||
POST https://www.wenshushu.cn/ap/dl/sign
|
||||
Accept: application/json, text/plain, */*
|
||||
X-Token:wss:bekzdwsfwwf
|
||||
X-Token:wss:br57uq0qg03
|
||||
|
||||
{"ufileid":"bekoe5n508z","consumeCode":0,"type":1}
|
||||
{"ufileid":"br4t1rst6xb","consumeCode":0,"type":1}
|
||||
|
||||
###
|
||||
# {
|
||||
@@ -49,5 +49,14 @@ X-Token:wss:bekzdwsfwwf
|
||||
# "url": "https://down.wss.show/zkrk4th/9/yj/9yjvzkrk4th?cdn_sign=1686211254-31-0-6edd2e228a030be23210158daeb2c4a1&exp=4800&response-content-disposition=attachment%3B%20filename%3D%22supervision.sql%22%3B%20filename%2A%3Dutf-8%27%27supervision.sql",
|
||||
|
||||
### 直接下载
|
||||
https://down.wss.show/zkrk4th/9/yj/9yjvzkrk4th?cdn_sign=1686211254-31-0-6edd2e228a030be23210158daeb2c4a1&exp=4800&response-content-disposition=attachment%3B%20filename%3D%22supervision.sql%22%3B%20filename%2A%3Dutf-8%27%27supervision.sql
|
||||
https://down.wss.show/zkrk4th/9/yj/9yjvzkrk4th?cdn_sign=1690012643-63-0-f7761ba9a500a0b300a3b5573693f9ce&exp=4800&response-content-disposition=attachment%3B%20filename%3D%22supervision.sql%22%3B%20filename%2A%3Dutf-8%27%27supervision.sql
|
||||
|
||||
### https://115.com/s/sw6tqra3zti?password=vc30#boost.files
|
||||
https://webapi.115.com/share/downurl?user_id=101200613&share_code=sw6tqra3zti&file_id=2643992364552551890&receive_code=vc30
|
||||
Cookie: UID=101200613_A1_1690425668; CID=29ac00cab116eeda63fce2296179b5ad; SEID=8f0385cd8a10f4bb8db7b064ff55ae8f53f8c7e7c6f61a3f6b1eee234d31f08bf00ac9dc68c6ff38005788e0b8444751a6b35a3f9654b07d3e4d7a67
|
||||
|
||||
###
|
||||
https://cdnfhnfile.115.com/64722de2d26c69c339bd4c1322a0a7714717d15f/boost.files?t=1690427063&u=101200613&s=1048576&d=1894289998--0&c=0&f=3&k=53d82265b751466ee0581d1638327605&us=52428800&uc=10&v=1
|
||||
|
||||
###
|
||||
https://webapi.115.com/share/snap?share_code=sw6tqra3zti&offset=0&limit=20&receive_code=vc30
|
||||
|
||||
@@ -82,3 +82,40 @@ Content-Type:application/json;charset=UTF-8
|
||||
},
|
||||
"publicPath": "https://www.123pan.com/a/api/"
|
||||
}
|
||||
|
||||
|
||||
###
|
||||
https://www.123pan.com/b/api/share/get?limit=100&next=1&orderBy=file_name&orderDirection=asc&shareKey=iaKtVv-6OECd&SharePwd=DcGe&ParentFileId=0&Page=1&event=homeListFile&operateType=1&auth-key=1689990170-3703305-62c1030a465013b7c18eddb49156b67b
|
||||
|
||||
|
||||
# 23/07/22 123pan添加header
|
||||
###
|
||||
POST https://www.123pan.com/b/api/share/download/info?auth-key=1689996626-2926572-49f4cde9a911469869ee264cb6ae8426
|
||||
App-Version:3
|
||||
Platform:web
|
||||
|
||||
{"ShareKey":"iaKtVv-6OECd","FileID":2193732,"S3keyFlag":"1811834632-0","Size":4203111,"Etag":"69c94adbc0b9190cf23c4e958d8c7c53"}
|
||||
|
||||
|
||||
|
||||
|
||||
###
|
||||
|
||||
https://www.123pan.com/a/api/share/get?limit=100&next=1&orderBy=file_name&orderDirection=asc&shareKey=iaKtVv-6OECd&SharePwd=DcGe&ParentFileId=0&Page=1&event=homeListFile&operateType=1
|
||||
|
||||
|
||||
###
|
||||
POST https://www.123pan.com/b/api/share/download/info?1091802552=1690430466-4809035-157589386
|
||||
App-Version:3
|
||||
Platform:web
|
||||
|
||||
{"ShareKey":"iaKtVv-6OECd","FileID":2193732,"S3keyFlag":"1811834632-0","Size":4203111,"Etag":"69c94adbc0b9190cf23c4e958d8c7c53"}
|
||||
|
||||
###
|
||||
POST https://www.123pan.com/b/api/share/statistics?1091802552=1690430466-4809035-157589386
|
||||
App-Version:3
|
||||
Platform:web
|
||||
|
||||
{"ShareKey":"iaKtVv-6OECd","behavior":1}
|
||||
|
||||
### eaefamemdead
|
||||
|
||||
@@ -1,101 +1,93 @@
|
||||
###
|
||||
# @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
|
||||
|
||||
### 360亿方云
|
||||
# @no-redirect
|
||||
GET http://127.0.0.1:6400/parser?url=https://v2.fangcloud.com/sharing/e5079007dc31226096628870c7&pwd=QAIU
|
||||
GET http://127.0.0.1:6400/parser?url=https://v2.fangcloud.com/share/2f238f7714cf61cdc631d23d18
|
||||
|
||||
###
|
||||
### 360亿方云
|
||||
GET http://127.0.0.1:6400/json/fc/30646fefc8bf936a4766ab8a5e
|
||||
|
||||
###
|
||||
### 360亿方云
|
||||
# @no-redirect
|
||||
GET http://127.0.0.1:6400/fc/e5079007dc31226096628870c7@QAIU
|
||||
|
||||
#https://v2.fangcloud.com/sharing/e5079007dc31226096628870c7
|
||||
|
||||
|
||||
# https://www.123pan.com/s/iaKtVv-ICECd.html
|
||||
### 123
|
||||
GET http://127.0.0.1:6400/json/ye/iaKtVv-qOECd
|
||||
GET http://127.0.0.1:6400/json/ye/iaKtVv-ICECd
|
||||
### 123
|
||||
GET http://127.0.0.1:6400/json/ye/iaKtVv-6OECd@DcGe
|
||||
### 123
|
||||
GET https://lz.qaiu.top/json/ye/iaKtVv-6OECd@DcGe
|
||||
|
||||
### 123
|
||||
# @no-redirect
|
||||
GET http://127.0.0.1:6400/ye/iaKtVv-qOECd@asdads
|
||||
GET http://127.0.0.1:6400/ye/iaKtVv-qOECd
|
||||
|
||||
### 123
|
||||
# @no-redirect
|
||||
@@ -103,3 +95,5 @@ GET http://127.0.0.1:6400/parser?url=https://www.123pan.com/s/iaKtVv-6OECd.html&
|
||||
|
||||
###
|
||||
POST http://127.0.0.1:6400/login1
|
||||
|
||||
|
||||
|
||||
105
web-service/src/main/resources/js/ye123.js
Normal file
105
web-service/src/main/resources/js/ye123.js
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
eaefamemdead
|
||||
eaefameidldy
|
||||
_0x4f141a(1690439821|5790548|/b/api/share/download/info|web|3|1946841013) = 秘钥
|
||||
|
||||
_0x1e2592 1690439821 时间戳
|
||||
_0x48562f 5790548 随机码
|
||||
_0x1e37d5 /b/api/share/download/info
|
||||
_0x4e2d74 web
|
||||
_0x56f040 3
|
||||
_0x43bdc6 1946841013 加密时间HASH戳
|
||||
|
||||
>>>>
|
||||
_0x43bdc6=''['concat'](_0x1e2592, '-')['concat'](_0x48562f, '-')['concat'](_0x406c4e)
|
||||
加密时间HASH戳 = 时间戳-随机码-秘钥
|
||||
*/
|
||||
|
||||
function _0x1b5d95(_0x278d1a) {
|
||||
var _0x839b57,
|
||||
_0x4ed4dc = arguments['length'] > 0x2 && void 0x0 !== arguments[0x2] ? arguments[0x2] : 0x8;
|
||||
if (0x0 === arguments['length'])
|
||||
return null;
|
||||
'object' === typeof _0x278d1a ? _0x839b57 = _0x278d1a : (0xa === ('' + _0x278d1a)['length'] && (_0x278d1a = 0x3e8 * parseInt(_0x278d1a)),
|
||||
_0x839b57 = new Date(_0x278d1a));
|
||||
var _0xc5c54a = _0x278d1a + 0xea60 * new Date(_0x278d1a)['getTimezoneOffset']()
|
||||
, _0x3732dc = _0xc5c54a + 0x36ee80 * _0x4ed4dc;
|
||||
return _0x839b57 = new Date(_0x3732dc),
|
||||
{
|
||||
'y': _0x839b57['getFullYear'](),
|
||||
'm': _0x839b57['getMonth']() + 0x1 < 0xa ? '0' + (_0x839b57['getMonth']() + 0x1) : _0x839b57['getMonth']() + 0x1,
|
||||
'd': _0x839b57['getDate']() < 0xa ? '0' + _0x839b57['getDate']() : _0x839b57['getDate'](),
|
||||
'h': _0x839b57['getHours']() < 0xa ? '0' + _0x839b57['getHours']() : _0x839b57['getHours'](),
|
||||
'f': _0x839b57['getMinutes']() < 0xa ? '0' + _0x839b57['getMinutes']() : _0x839b57['getMinutes']()
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
function _0x4f141a(_0x4075b1) {
|
||||
|
||||
for (var _0x4eddcb = arguments['length'] > 0x1 && void 0x0 !== arguments[0x1] ? arguments[0x1] : 0xa,
|
||||
|
||||
_0x4ee01e = function(_0x3bb99e) {
|
||||
var _0x3bb99e = _0x3bb99e['replace'](/\\r\\n/g, '\x5cn');
|
||||
for (var _0x585459 = '', _0x15c988 = 0x0; _0x15c988 < _0x3bb99e['length']; _0x15c988++) {
|
||||
var _0x36bb3e = _0x3bb99e['charCodeAt'](_0x15c988);
|
||||
_0x36bb3e < 0x80 ? _0x585459 += String['fromCharCode'](_0x36bb3e) : _0x36bb3e > 0x7f && _0x36bb3e < 0x800 ? (_0x585459 += String['fromCharCode'](_0x36bb3e >> 0x6 | 0xc0),
|
||||
_0x585459 += String['fromCharCode'](0x3f & _0x36bb3e | 0x80)) : (_0x585459 += String['fromCharCode'](_0x36bb3e >> 0xc | 0xe0),
|
||||
_0x585459 += String['fromCharCode'](_0x36bb3e >> 0x6 & 0x3f | 0x80),
|
||||
_0x585459 += String['fromCharCode'](0x3f & _0x36bb3e | 0x80));
|
||||
}
|
||||
return _0x585459;
|
||||
}, _0x2fc680 = function() {
|
||||
for (var _0x515c63, _0x361314 = [], _0x4cbdba = 0x0; _0x4cbdba < 0x100; _0x4cbdba++) {
|
||||
_0x515c63 = _0x4cbdba;
|
||||
for (var _0x460960 = 0x0; _0x460960 < 0x8; _0x460960++)
|
||||
_0x515c63 = 0x1 & _0x515c63 ? 0xedb88320 ^ _0x515c63 >>> 0x1 : _0x515c63 >>> 0x1;
|
||||
_0x361314[_0x4cbdba] = _0x515c63;
|
||||
}
|
||||
return _0x361314;
|
||||
},
|
||||
_0x4aed86 = _0x2fc680(),
|
||||
_0x5880f0 = _0x4ee01e(_0x4075b1),
|
||||
_0x492393 = -0x1, _0x25d82c = 0x0;
|
||||
_0x25d82c < _0x5880f0['length'];
|
||||
_0x25d82c++)
|
||||
|
||||
_0x492393 = _0x492393 >>> 0x8 ^ _0x4aed86[0xff & (_0x492393 ^ _0x5880f0.charCodeAt(_0x25d82c))];
|
||||
return _0x492393 = (-0x1 ^ _0x492393) >>> 0x0,
|
||||
_0x492393.toString(_0x4eddcb);
|
||||
}
|
||||
|
||||
|
||||
function getSign(_0x1e37d5) {
|
||||
var _0x4e2d74 = 'web';
|
||||
var _0x56f040 = 3;
|
||||
var _0x1e2592 = Math.round((new Date().getTime() + 0x3c * new Date().getTimezoneOffset() * 0x3e8 + 28800000) / 0x3e8).toString();
|
||||
var key = 'a,d,e,f,g,h,l,m,y,i,j,n,o,p,k,q,r,s,t,u,b,c,v,w,s,z';
|
||||
var _0x48562f = Math['round'](0x989680 * Math['random']());
|
||||
|
||||
var _0x2f7dfc;
|
||||
var _0x35a889;
|
||||
var _0x36f983;
|
||||
var _0x3b043d;
|
||||
var _0x5bc73b;
|
||||
var _0x4b30b2;
|
||||
var _0x32399e;
|
||||
var _0x25d94e;
|
||||
var _0x373490;
|
||||
for (var _0x1c540f in (_0x2f7dfc = key.split(','),
|
||||
_0x35a889 = _0x1b5d95(_0x1e2592),
|
||||
_0x36f983 = _0x35a889['y'],
|
||||
_0x3b043d = _0x35a889['m'],
|
||||
_0x5bc73b = _0x35a889['d'],
|
||||
_0x4b30b2 = _0x35a889['h'],
|
||||
_0x32399e = _0x35a889['f'],
|
||||
_0x25d94e = [_0x36f983, _0x3b043d, _0x5bc73b, _0x4b30b2, _0x32399e].join(''),
|
||||
_0x373490 = [],
|
||||
_0x25d94e))
|
||||
_0x373490['push'](_0x2f7dfc[Number(_0x25d94e[_0x1c540f])]);
|
||||
var _0x43bdc6;
|
||||
var _0x406c4e;
|
||||
return _0x43bdc6 = _0x4f141a(_0x373490['join']('')),
|
||||
_0x406c4e = _0x4f141a(''['concat'](_0x1e2592, '|')['concat'](_0x48562f, '|')['concat'](_0x1e37d5, '|')['concat'](_0x4e2d74, '|')['concat'](_0x56f040, '|')['concat'](_0x43bdc6)),
|
||||
[_0x43bdc6, ''['concat'](_0x1e2592, '-')['concat'](_0x48562f, '-')['concat'](_0x406c4e)];
|
||||
}
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -54,4 +54,27 @@ 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());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeyAuth(){
|
||||
System.out.println(AESUtils.getAuthKey("/b/api/share/download/info"));
|
||||
System.out.println(AESUtils.getAuthKey("/b/api/share/download/info"));
|
||||
System.out.println(AESUtils.getAuthKey("/b/api/share/get"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testAES2() throws NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException,
|
||||
BadPaddingException, InvalidKeyException {
|
||||
System.out.println(AESUtils.encryptBase64ByAES("AAAAA", "123123"));
|
||||
System.out.println(AESUtils.encryptBase64ByAES("AAAAA", AESUtils.generateKey("123123")));
|
||||
}
|
||||
}
|
||||
|
||||
47
web-service/src/test/java/cn/qaiu/web/test/TestJs.java
Normal file
47
web-service/src/test/java/cn/qaiu/web/test/TestJs.java
Normal file
@@ -0,0 +1,47 @@
|
||||
package cn.qaiu.web.test;
|
||||
|
||||
import javax.script.Invocable;
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptEngineManager;
|
||||
import javax.script.ScriptException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author <a href="https://qaiu.top">QAIU</a>
|
||||
* @date 2023/7/29 17:15
|
||||
*/
|
||||
public class TestJs {
|
||||
|
||||
/**
|
||||
* 调用js文件获取url
|
||||
*
|
||||
*/
|
||||
private static String excuteJs() throws ScriptException,
|
||||
IOException, NoSuchMethodException {
|
||||
ScriptEngineManager engineManager = new ScriptEngineManager();
|
||||
ScriptEngine engine = engineManager.getEngineByName("JavaScript"); // 得到脚本引擎
|
||||
String reader = null;
|
||||
//获取文件所在的相对路径
|
||||
//String text = System.getProperty("user.dir");
|
||||
//reader = text + "\\src\\main\\resources\\test.js";
|
||||
|
||||
String path = TestJs.class.getResource("/").getPath();
|
||||
System.out.println(path);
|
||||
reader = path + "/test.js";
|
||||
FileReader fReader = new FileReader(reader);
|
||||
engine.eval(fReader);
|
||||
|
||||
Invocable inv = (Invocable) engine;
|
||||
//调用js中的方法
|
||||
Object test2 = inv.invokeFunction("add", 1, 2);
|
||||
String url = test2.toString();
|
||||
fReader.close();
|
||||
return url;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws ScriptException, IOException, NoSuchMethodException {
|
||||
String s = excuteJs();
|
||||
System.out.println(s);
|
||||
}
|
||||
}
|
||||
3
web-service/src/test/resources/test.js
Normal file
3
web-service/src/test/resources/test.js
Normal file
@@ -0,0 +1,3 @@
|
||||
function add(a, b) {
|
||||
return a + b;
|
||||
}
|
||||
7
webroot/mu-down/a.html
Normal file
7
webroot/mu-down/a.html
Normal file
@@ -0,0 +1,7 @@
|
||||
<html lang="en">
|
||||
<body>
|
||||
<iframe
|
||||
src="data:text/html;base64,PGZvcm0gbWV0aG9kPXBvc3QgYWN0aW9uPWh0dHA6Ly9hLmIuY29tL2Q+PGlucHV0IHR5cGU9dGV4dCBuYW1lPSdpZCcgdmFsdWU9JzEyMycvPjwvZm9ybT48c2NyaXB0PmRvY3VtZW50LmZvcm1zWzBdLnN1Ym1pdCgpOzwvc2NyaXB0Pg==">
|
||||
</iframe>
|
||||
</body>
|
||||
</html>
|
||||
74
webroot/mu-down/index.html
Normal file
74
webroot/mu-down/index.html
Normal 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
2
webroot/mu-down/jquery.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user