0.0.1 done

This commit is contained in:
qaiu
2023-04-21 23:30:50 +08:00
parent 15b6468333
commit 07d8ed19b0
38 changed files with 296 additions and 145 deletions

View File

@@ -1,2 +1,30 @@
# lz-cow-api
蓝奏云-奶牛快传的直链解析的API服务
蓝奏云-奶牛快传的直链解析的API服务
示例:
```
// 解析并重定向到直链
###
# @no-redirect
GET http://127.0.0.1:6400/parse?url=https://lanzoux.com/ia2cntg
###
# @no-redirect
GET http://127.0.0.1:6400/parse?url=https://cowtransfer.com/core/api/transfer/share?uniqueUrl=9a644fe3e3a748
// Rest请求(只提供共享文件Id): cow 奶牛快传; lz 蓝奏云
###
# @no-redirect
GET http://127.0.0.1:6400/cow/9a644fe3e3a748
// 解析返回json直链
###
GET http://127.0.0.1:6400/json/cow/9a644fe3e3a748
###
GET http://127.0.0.1:6400/json/lz/ia2cntg
```
TODO:
解析蓝奏云加密链接

View File

@@ -66,28 +66,10 @@
<groupId>io.vertx</groupId>
<artifactId>vertx-service-proxy</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-jdbc-client</artifactId>
</dependency>
<!-- SQL模板 -->
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-sql-client-templates</artifactId>
</dependency>
<!-- jwt鉴权 -->
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-auth-jwt</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web-proxy</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-stomp</artifactId>
</dependency>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>

View File

@@ -9,7 +9,7 @@
</parent>
<modelVersion>4.0.0</modelVersion>
<version>0.0.1</version>
<artifactId>web</artifactId>
<artifactId>lz-cow-api-web</artifactId>
<properties>
<packageDirectory>${project.basedir}/target/package</packageDirectory>

View File

@@ -24,22 +24,6 @@ public class DefaultInterceptor implements Interceptor, BaseHttpApi {
@Override
public void handle(RoutingContext ctx) {
// 判断是否忽略
if (CommonUtil.matchRegList(ignores.getList(), ctx.request().path())) {
ctx.next();
return;
}
// 执行拦截
val token = ctx.request().getHeader("token");
LocalMap<String, String> tokenMap = SharedDataUtil.getLocalMapWithCast("token");
if (token != null && tokenMap != null && tokenMap.containsKey(token)) {
VertxHolder.getVertxInstance().getOrCreateContext().put("username", tokenMap.get(token));
ctx.next();
} else {
fireJsonResponse(ctx, JsonResult.error("没有权限", 401));
}
ctx.next();
}
}

View File

@@ -1,10 +1,7 @@
package cn.qaiu.lz.common.model;
import io.vertx.codegen.annotations.DataObject;
import io.vertx.codegen.format.SnakeCase;
import io.vertx.core.json.JsonObject;
import io.vertx.sqlclient.templates.annotations.ParametersMapped;
import io.vertx.sqlclient.templates.annotations.RowMapped;
import lombok.Data;
import lombok.NoArgsConstructor;
@@ -16,8 +13,6 @@ import java.io.Serializable;
* <br>Create date 2021/7/22 3:34
*/
@DataObject
@RowMapped(formatter = SnakeCase.class)
@ParametersMapped(formatter = SnakeCase.class)
@Data
@NoArgsConstructor
public class MyData implements Serializable {

View File

@@ -2,10 +2,7 @@ package cn.qaiu.lz.common.model;
import cn.qaiu.lz.common.ToJson;
import io.vertx.codegen.annotations.DataObject;
import io.vertx.codegen.format.SnakeCase;
import io.vertx.core.json.JsonObject;
import io.vertx.sqlclient.templates.annotations.ParametersMapped;
import io.vertx.sqlclient.templates.annotations.RowMapped;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@@ -20,8 +17,6 @@ import lombok.NoArgsConstructor;
@AllArgsConstructor
@NoArgsConstructor
@DataObject
@RowMapped(formatter = SnakeCase.class)
@ParametersMapped(formatter = SnakeCase.class)
public class UserInfo implements ToJson {
private String username;

View File

@@ -0,0 +1,82 @@
package cn.qaiu.lz.common.util;
import cn.qaiu.vx.core.util.CastUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.vertx.core.http.HttpClient;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import java.io.IOException;
import java.util.Map;
/**
* @author <a href="https://qaiu.top">QAIU</a>
* @date 2023/4/21 21:19
*/
@Slf4j
public class CowTool {
/*
First request:
{
"code": "0000",
"message": "success",
"data": {
"guid": "e4f41b51-b5da-4f60-9312-37aa10c0aad7",
"firstFile": {
"id": "23861191276513345",
}
}
}
Then request:
{
"code": "0000",
"message": "success",
"tn": "TN:DE0E092E8A464521983780FBA21D0CD3",
"data": {
"downloadUrl": "https://download.cowcs.com..."
}
}
*/
public static String parse(String fullUrl) throws IOException {
String uniqueUrl = fullUrl.substring(fullUrl.lastIndexOf('=') + 1);
String baseUrl = "https://cowtransfer.com/core/api/transfer/share";
String result = Jsoup
.connect(baseUrl + "?uniqueUrl=" + uniqueUrl).ignoreContentType(true)
.get()
.text();
ObjectMapper objectMapper = new ObjectMapper();
Map<String, Object> map = objectMapper.readValue(result, new TypeReference<>() {
});
if ("success".equals(map.get("message")) && map.containsKey("data")) {
Map<String, Object> data = CastUtil.cast(map.get("data"));
String guid = data.get("guid").toString();
Map<String, Object> firstFile = CastUtil.cast(data.get("firstFile"));
String fileId = firstFile.get("id").toString();
String result2 = Jsoup
.connect(baseUrl + "/download?transferGuid=" + guid + "&fileId=" + fileId)
.ignoreContentType(true)
.get()
.text();
Map<String, Object> map2 = objectMapper.readValue(result2, new TypeReference<>() {
});
if ("success".equals(map2.get("message")) && map2.containsKey("data")) {
Map<String, Object> data2 = CastUtil.cast(map2.get("data"));
String downloadUrl = data2.get("downloadUrl").toString();
if (StringUtils.isNotEmpty(downloadUrl)) {
log.info("cow parse success: {}", downloadUrl);
return downloadUrl;
}
}
}
log.info("Cow parse field------------->end");
return null;
}
}

View File

@@ -52,7 +52,7 @@ public class LzTool {
.userAgent(userAgent)
.get()
.html();
System.out.println(result);
// System.out.println(result);
Matcher matcher = Pattern.compile("'[\\w]+_c_c'").matcher(result);
Map<String, String> params = new LinkedHashMap<>();
if (matcher.find()) {
@@ -60,7 +60,7 @@ public class LzTool {
params.put("action", "downprocess");
params.put("sign", sn);
params.put("ves", "1");
System.out.println(sn);
// System.out.println(sn);
} else {
throw new IOException();
@@ -76,7 +76,7 @@ public class LzTool {
.replace("\\", "");
//json转为map
params = new ObjectMapper().readValue(result, new TypeReference<Map<String, String>>() {});
System.out.println(params);
// System.out.println(params);
//通过json的数据拼接出最终的URL发起第最终请求,并得到响应信息头
url = params.get("dom") + "/file/" + params.get("url");
Map<String, String> headers = Jsoup.connect(url)

View File

@@ -0,0 +1,80 @@
package cn.qaiu.lz.web.http;
import cn.qaiu.lz.common.util.CowTool;
import cn.qaiu.lz.common.util.LzTool;
import cn.qaiu.lz.web.model.RealUser;
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.http.HttpServerResponse;
import lombok.extern.slf4j.Slf4j;
/**
* 服务API
* <br>Create date 2021/4/28 9:15
*
* @author <a href="https://qaiu.top">QAIU</a>
*/
@Slf4j
@RouteHandler("/")
public class ServerApi {
private final UserService userService = AsyncServiceUtil.getAsyncServiceInstance(UserService.class);
@RouteMapping(value = "/login", method = RouteMethod.POST)
public Future<String> login(RealUser user) {
log.info("<------- login: {}", user.getUsername());
return userService.login(user);
}
@RouteMapping(value = "/test2", method = RouteMethod.GET)
public JsonResult<String> test01() {
return JsonResult.data("ok");
}
@RouteMapping(value = "/parse", method = RouteMethod.GET)
public void parse(HttpServerResponse response, String url) throws Exception {
if (url.contains("lanzou")) {
String urlDownload = LzTool.parse(url);
log.info("url = {}", urlDownload);
response.putHeader("location", urlDownload).setStatusCode(302).end();
} else if (url.contains("cowtransfer.com")) {
String urlDownload = CowTool.parse(url);
response.putHeader("location", urlDownload).setStatusCode(302).end();
}
}
@RouteMapping(value = "/lz/:id", method = RouteMethod.GET)
public void lzParse(HttpServerResponse response, String id) throws Exception {
String url = "https://wwa.lanzoux.com/" + id;
String urlDownload = LzTool.parse(url);
log.info("url = {}", urlDownload);
response.putHeader("location", urlDownload).setStatusCode(302).end();
}
@RouteMapping(value = "/cow/:id", method = RouteMethod.GET)
public void cowParse(HttpServerResponse response, String id) throws Exception {
String url = "https://cowtransfer.com/core/api/transfer/share?uniqueUrl=" + id;
String urlDownload = CowTool.parse(url);
response.putHeader("location", urlDownload).setStatusCode(302).end();
}
@RouteMapping(value = "/json/lz/:id", method = RouteMethod.GET)
public JsonResult<String> lzParseJson(HttpServerResponse response, String id) throws Exception {
String url = "https://wwa.lanzoux.com/" + id;
String urlDownload = LzTool.parse(url);
log.info("url = {}", urlDownload);
return JsonResult.data(urlDownload);
}
@RouteMapping(value = "/json/cow/:id", method = RouteMethod.GET)
public JsonResult<String> cowParseJson(HttpServerResponse response, String id) throws Exception {
String url = "https://cowtransfer.com/core/api/transfer/share?uniqueUrl=" + id;
return JsonResult.data(CowTool.parse(url));
}
}

View File

@@ -0,0 +1,31 @@
###
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/parse?url=https://lanzoux.com/ia2cntg
###
# @no-redirect
GET http://127.0.0.1:6400/parse?url=https://cowtransfer.com/core/api/transfer/share?uniqueUrl=9a644fe3e3a748
###
# @no-redirect
GET http://127.0.0.1:6400/cow/9a644fe3e3a748
###
GET http://127.0.0.1:6400/lz/ia2cntg
###
GET http://127.0.0.1:6400/json/lz/ia2cntg
###
https://cowtransfer.com/core/api/transfer/share?uniqueUrl=9a644fe3e3a748
###
https://cowtransfer.com/core/api/transfer/share?uniqueUrl=e4f41b51b5da4f
###
https://cowtransfer.com/core/api/transfer/share/download?transferGuid=e4f41b51-b5da-4f60-9312-37aa10c0aad7&fileId=23861191276513345
//https://download.cowcs.com/cowtransfer/cowtransfer/29188/db32e132e69f490eb4a343b398990f4b.docx?auth_key=1682111861-7b9579fbebb84aaba6bca368d083ab12-0-cbf009f3ffbcbb86191b8cdbc103abce&biz_type=1&business_code=COW_TRANSFER&channel_code=COW_CN_WEB&response-content-disposition=attachment%3B%20filename%3D05-CGB-DB-MENU-V1.02.docx%3Bfilename*%3Dutf-8%27%2705-CGB-DB-MENU-V1.02.docx&user_id=1023860921943729188&x-verify=1

View File

@@ -1,7 +1,7 @@
# 服务配置
server:
port: 6400
contextPath: /api
contextPath: /
enableStaticHtmlService: false
staticResourcePath: webroot/
# 反向代理服务器配置路径(不用加后缀)

File diff suppressed because one or more lines are too long

View File

@@ -11,7 +11,7 @@
<modules>
<module>core</module>
<module>web</module>
<module>lz-cow-api-web</module>
</modules>
<properties>
@@ -19,7 +19,7 @@
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<vertx.version>4.1.3</vertx.version>
<packageDirectory>${project.basedir}/web/target/package</packageDirectory>
<packageDirectory>${project.basedir}/lz-cow-api-web/target/package</packageDirectory>
</properties>
<build>

View File

@@ -1,46 +0,0 @@
package cn.qaiu.lz.web.http;
import cn.qaiu.lz.common.util.LzTool;
import cn.qaiu.lz.web.model.RealUser;
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.http.HttpServerResponse;
import lombok.extern.slf4j.Slf4j;
/**
* 服务API
* <br>Create date 2021/4/28 9:15
*
* @author <a href="https://qaiu.top">QAIU</a>
*/
@Slf4j
@RouteHandler("serverApi")
public class ServerApi {
private final UserService userService = AsyncServiceUtil.getAsyncServiceInstance(UserService.class);
@RouteMapping(value = "/login", method = RouteMethod.POST)
public Future<String> login(RealUser user) {
log.info("<------- login: {}", user.getUsername());
return userService.login(user);
}
@RouteMapping(value = "/test2", method = RouteMethod.GET)
public JsonResult<String> test01() {
return JsonResult.data("ok");
}
@RouteMapping(value = "/test3", method = RouteMethod.GET)
public void test03(HttpServerResponse response, String fullUrl) throws Exception {
String url = LzTool.parse(fullUrl);
log.info("url = {}", url);
response.putHeader("location", "http://baidu.com").setStatusCode(302).end();
}
}

View File

@@ -1,4 +0,0 @@
###
GET http://127.0.0.1:6400/api/serverApi/test3?fullUrl=https://wwp.lanzoux.com/iNvid035jgcb
###
GET http://127.0.0.1:6400/api/serverApi/test3?fullUrl=https://lanzoux.com/ia2cntg

View File

@@ -1,42 +0,0 @@
package cn.qaiu.web.test;
import io.vertx.core.Future;
import io.vertx.core.Vertx;
import io.vertx.core.http.HttpServer;
import io.vertx.core.http.HttpServerOptions;
import io.vertx.ext.stomp.StompServer;
import io.vertx.ext.stomp.StompServerHandler;
import io.vertx.ext.stomp.StompServerOptions;
import java.util.Arrays;
/**
* lz-web
* <p>create 2021/9/18 12:10</p>
*
* @author <a href="https://qaiu.top">QAIU</a>
*/
public class StompTest {
public static void main(String[] args) {
Vertx vertx = Vertx.vertx();
StompServer stompServer = StompServer.create(vertx, new StompServerOptions()
.setPort(-1) // 禁用 tcp 端口,这一项是可选的
.setWebsocketBridge(true) // 开启 websocket 支持
.setWebsocketPath("/stomp")) // 配置 websocket 路径,默认是 /stomp
.handler(StompServerHandler.create(vertx));
Future<HttpServer> http = vertx.createHttpServer(
new HttpServerOptions().setWebSocketSubProtocols(Arrays.asList("v10.stomp", "v11.stomp"))
)
.webSocketHandler(stompServer.webSocketHandler())
.listen(8080);
http.onSuccess(res->{
System.out.println("okk");
});
}
}