蓝奏云规则微调, 框架优化(70%)

This commit is contained in:
QAIU
2023-08-23 14:55:08 +08:00
parent b0d150319d
commit 6706380558
16 changed files with 212 additions and 56 deletions

View File

@@ -82,7 +82,7 @@ public final class Deploy {
var calendar = Calendar.getInstance();
calendar.setTime(new Date());
var year = calendar.get(Calendar.YEAR);
var logoTemplete = """
var logoTemplate = """
Web Server powered by:\s
____ ____ _ _ _ \s
@@ -95,7 +95,7 @@ public final class Deploy {
""";
System.out.printf(logoTemplete,
System.out.printf(logoTemplate,
conf.getString("version_app"),
VersionCommand.getVersion(),
conf.getString("copyright"),

View File

@@ -0,0 +1,15 @@
package cn.qaiu.vx.core.annotaions;
import java.lang.annotation.*;
@Documented
@Inherited
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface HandleSortFilter {
/**
* 注册顺序,数字越大越先注册<br>
* 值<0时会过滤掉该处理器
*/
int value() default 0;
}

View File

@@ -1,8 +1,11 @@
package cn.qaiu.vx.core.base;
import cn.qaiu.vx.core.interceptor.AfterInterceptor;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.RoutingContext;
import java.util.Set;
import static io.vertx.core.http.HttpHeaders.CONTENT_TYPE;
/**
@@ -13,6 +16,10 @@ import static io.vertx.core.http.HttpHeaders.CONTENT_TYPE;
*/
public interface BaseHttpApi {
default Set<AfterInterceptor> getAfterInterceptor() {
return null;
}
default void fireJsonResponse(RoutingContext ctx, JsonObject jsonResult) {
ctx.response().putHeader(CONTENT_TYPE, "application/json; charset=utf-8")
.setStatusCode(200)
@@ -21,11 +28,28 @@ public interface BaseHttpApi {
default <T> void fireJsonResponse(RoutingContext ctx, T jsonResult) {
JsonObject jsonObject = JsonObject.mapFrom(jsonResult);
fireJsonResponse(ctx, jsonObject);
if (!ctx.response().ended()) {
fireJsonResponse(ctx, jsonObject);
}
handleAfterInterceptor(ctx, jsonObject);
}
default void handleAfterInterceptor(RoutingContext ctx, JsonObject jsonObject){
Set<AfterInterceptor> afterInterceptor = getAfterInterceptor();
if (afterInterceptor != null) {
afterInterceptor.forEach(ai -> ai.handle(ctx.request(), jsonObject));
}
if (!ctx.response().ended()) {
fireJsonResponse(ctx, "handleAfterInterceptor end.");
}
}
default void fireTextResponse(RoutingContext ctx, String text) {
ctx.response().putHeader("content-type", "text/html; charset=utf-8").end(text);
ctx.response().putHeader(CONTENT_TYPE, "text/html; charset=utf-8").end(text);
Set<AfterInterceptor> afterInterceptor = getAfterInterceptor();
if (afterInterceptor != null) {
afterInterceptor.forEach(ai -> ai.handle(ctx.request(), new JsonObject().put("text", text)));
}
}
default void sendError(int statusCode, RoutingContext ctx) {

View File

@@ -1,12 +1,9 @@
package cn.qaiu.vx.core.handlerfactory;
import cn.qaiu.vx.core.annotaions.DateFormat;
import cn.qaiu.vx.core.annotaions.RouteHandler;
import cn.qaiu.vx.core.annotaions.RouteMapping;
import cn.qaiu.vx.core.annotaions.SockRouteMapper;
import cn.qaiu.vx.core.annotaions.*;
import cn.qaiu.vx.core.base.BaseHttpApi;
import cn.qaiu.vx.core.enums.MIMEType;
import cn.qaiu.vx.core.interceptor.Interceptor;
import cn.qaiu.vx.core.interceptor.AfterInterceptor;
import cn.qaiu.vx.core.interceptor.BeforeInterceptor;
import cn.qaiu.vx.core.model.JsonResult;
import cn.qaiu.vx.core.util.*;
import io.vertx.core.Future;
@@ -75,21 +72,22 @@ public class RouterHandlerFactory implements BaseHttpApi {
* 开始扫描并注册handler
*/
public Router createRouter() {
Router router = Router.router(VertxHolder.getVertxInstance());
// 主路由
Router mainRouter = Router.router(VertxHolder.getVertxInstance());
// 静态资源
String path = SharedDataUtil.getJsonConfig("server")
.getString("staticResourcePath");
if (!StringUtils.isEmpty(path)) {
// 静态资源
router.route("/*").handler(StaticHandler
mainRouter.route("/*").handler(StaticHandler
.create(path)
.setCachingEnabled(true)
.setDefaultContentEncoding("UTF-8"));
}
router.route().handler(ctx -> {
mainRouter.route().handler(ctx -> {
LOGGER.debug("The HTTP service request address information ===>path:{}, uri:{}, method:{}",
ctx.request().path(), ctx.request().absoluteURI(), ctx.request().method());
ctx.response().headers().add(ACCESS_CONTROL_ALLOW_ORIGIN, "*");
@@ -100,11 +98,15 @@ public class RouterHandlerFactory implements BaseHttpApi {
ctx.next();
});
// 添加跨域的方法
router.route().handler(CorsHandler.create().addRelativeOrigin(".*").allowCredentials(true).allowedMethods(httpMethods));
mainRouter.route().handler(CorsHandler.create().addRelativeOrigin(".*").allowCredentials(true).allowedMethods(httpMethods));
// 配置文件上传路径
router.route().handler(BodyHandler.create().setUploadsDirectory("uploads"));
mainRouter.route().handler(BodyHandler.create().setUploadsDirectory("uploads"));
// 拦截器
Set<Handler<RoutingContext>> interceptorSet = getInterceptorSet();
Route route0 = mainRouter.route("/*");
interceptorSet.forEach(route0::handler);
try {
Set<Class<?>> handlers = reflections.getTypesAnnotatedWith(RouteHandler.class);
@@ -118,7 +120,7 @@ public class RouterHandlerFactory implements BaseHttpApi {
for (Class<?> handler : sortedHandlers) {
try {
// 注册请求处理方法
registerNewHandler(router, handler);
registerNewHandler(mainRouter, handler);
} catch (Throwable e) {
LOGGER.error("Error register {}, Error details", handler, e.getCause());
@@ -128,12 +130,12 @@ public class RouterHandlerFactory implements BaseHttpApi {
LOGGER.error("Manually Register Handler Fail, Error details" + e.getMessage());
}
// 错误请求处理
router.errorHandler(405, ctx -> fireJsonResponse(ctx, JsonResult
mainRouter.errorHandler(405, ctx -> fireJsonResponse(ctx, JsonResult
.error("Method Not Allowed", 405)));
router.errorHandler(404, ctx -> ctx.response().setStatusCode(404).setChunked(true)
mainRouter.errorHandler(404, ctx -> ctx.response().setStatusCode(404).setChunked(true)
.end("Internal server error: 404 not found"));
return router;
return mainRouter;
}
/**
@@ -157,8 +159,6 @@ public class RouterHandlerFactory implements BaseHttpApi {
method -> method.isAnnotationPresent(SockRouteMapper.class)
).toList());
// 拦截器
Handler<RoutingContext> interceptor = getInterceptor();
// 依次注册处理方法
for (Method method : methodList) {
if (method.isAnnotationPresent(RouteMapping.class)) {
@@ -177,8 +177,6 @@ public class RouterHandlerFactory implements BaseHttpApi {
// 设置默认超时
route.handler(TimeoutHandler.create(SharedDataUtil.getCustomConfig().getInteger(ROUTE_TIME_OUT)));
// 先执行拦截方法, 再进入业务请求
route.handler(interceptor);
route.handler(ctx -> handlerMethod(instance, method, ctx)).failureHandler(ctx -> {
if (ctx.response().ended()) return;
ctx.failure().printStackTrace();
@@ -235,11 +233,9 @@ public class RouterHandlerFactory implements BaseHttpApi {
* @return Handler
* @throws Throwable Throwable
*/
private Handler<RoutingContext> getInterceptor() throws Throwable {
private Set<Handler<RoutingContext>> getInterceptorSet() {
// 配置拦截
Class<?> interceptorClass = Class.forName(SharedDataUtil.getValueForCustomConfig("interceptorClassPath"));
Interceptor handleInstance = (Interceptor)ReflectionUtil.newWithNoParam(interceptorClass);
return handleInstance.doHandle();
return getBeforeInterceptor().stream().map(BeforeInterceptor::doHandle).collect(Collectors.toSet());
}
/**
@@ -369,11 +365,13 @@ public class RouterHandlerFactory implements BaseHttpApi {
fireJsonResponse(ctx, res);
} else if (res != null) {
fireJsonResponse(ctx, JsonResult.data(res));
} else {
handleAfterInterceptor(ctx, null);
}
}).onFailure(e -> fireJsonResponse(ctx, JsonResult.error(e.getMessage())));
} else {
ctx.response().headers().set(CONTENT_TYPE, MIMEType.TEXT_HTML.getValue());
ctx.end(data.toString());
fireTextResponse(ctx, data.toString());
}
}
} catch (Throwable e) {
@@ -404,4 +402,23 @@ public class RouterHandlerFactory implements BaseHttpApi {
}
return fmt;
}
@Override
public Set<AfterInterceptor> getAfterInterceptor() {
Set<Class<? extends AfterInterceptor>> afterInterceptorClassSet =
reflections.getSubTypesOf(AfterInterceptor.class);
if (afterInterceptorClassSet == null) {
return null;
}
return CommonUtil.sortClassSet(afterInterceptorClassSet);
}
private Set<BeforeInterceptor> getBeforeInterceptor() {
Set<Class<? extends BeforeInterceptor>> interceptorClassSet =
reflections.getSubTypesOf(BeforeInterceptor.class);
if (interceptorClassSet == null) {
return new HashSet<>();
}
return CommonUtil.sortClassSet(interceptorClassSet);
}
}

View File

@@ -0,0 +1,15 @@
package cn.qaiu.vx.core.interceptor;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.json.JsonObject;
/**
* 后置拦截器接口
*
* @author <a href="https://qaiu.top">QAIU</a>
*/
public interface AfterInterceptor {
void handle(HttpServerRequest request, JsonObject responseData);
}

View File

@@ -4,18 +4,16 @@ import io.vertx.core.Handler;
import io.vertx.ext.web.RoutingContext;
/**
* 拦截器接口
* <br>Create date 2021-05-06 09:20:37
* 前置拦截器接口
*
* @author <a href="https://qaiu.top">QAIU</a>
*/
public interface Interceptor {
public interface BeforeInterceptor {
default Handler<RoutingContext> doHandle() {
return this::beforeHandle;
return this::handle;
}
void beforeHandle(RoutingContext context);
void handle(RoutingContext context);
void afterHandle(RoutingContext context);
}

View File

@@ -1,5 +1,6 @@
package cn.qaiu.vx.core.util;
import cn.qaiu.vx.core.annotaions.HandleSortFilter;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.json.JsonObject;
import org.apache.commons.beanutils.ConvertUtils;
@@ -15,6 +16,8 @@ import java.net.URL;
import java.net.UnknownHostException;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/**
* CommonUtil
@@ -70,10 +73,11 @@ public class CommonUtil {
} catch (UnknownHostException e) {
return false;
}
try(Socket ignored = new Socket(Address, port)) {
//建立一个Socket连接
try (Socket ignored = new Socket(Address, port)) {
//建立一个Socket连接
flag = true;
} catch (IOException ignoredException) {}
} catch (IOException ignoredException) {
}
return flag;
}
@@ -126,4 +130,32 @@ public class CommonUtil {
LocalConstant.put(configName, map);
LOGGER.info("读取配置{}成功", configName);
}
public static <T> Set<T> sortClassSet(Set<Class<? extends T>> set) {
return set.stream().filter(c1 -> {
HandleSortFilter s1 = c1.getAnnotation(HandleSortFilter.class);
if (s1 != null) {
return s1.value() > 0;
} else {
return true;
}
}).sorted((c1, c2) -> {
HandleSortFilter s1 = c1.getAnnotation(HandleSortFilter.class);
HandleSortFilter s2 = c2.getAnnotation(HandleSortFilter.class);
int n1 = 0, n2 = 0;
if (s1 != null) {
n1 = s1.value();
}
if (s2 != null) {
n2 = s2.value();
}
return n1 - n2;
}).map(c -> {
try {
return ReflectionUtil.newWithNoParam(c);
} catch (Exception e) {
throw new RuntimeException(e);
}
}).collect(Collectors.toSet());
}
}

View File

@@ -0,0 +1,17 @@
package cn.qaiu.vx.core.util;
import io.vertx.core.Promise;
import io.vertx.core.http.HttpHeaders;
import io.vertx.core.http.HttpServerResponse;
public class ResponseUtil {
public static void redirect(HttpServerResponse response, String url) {
response.putHeader(HttpHeaders.LOCATION, url).setStatusCode(302).end();
}
public static void redirect(HttpServerResponse response, String url, Promise<?> promise) {
redirect(response, url);
promise.complete();
}
}

View File

@@ -19,6 +19,7 @@
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<packageDirectory>${project.basedir}/web-service/target/package</packageDirectory>
</properties>

View File

@@ -1,7 +1,7 @@
package cn.qaiu.lz.common.interceptorImpl;
import cn.qaiu.vx.core.base.BaseHttpApi;
import cn.qaiu.vx.core.interceptor.Interceptor;
import cn.qaiu.vx.core.annotaions.HandleSortFilter;
import cn.qaiu.vx.core.interceptor.BeforeInterceptor;
import cn.qaiu.vx.core.util.SharedDataUtil;
import io.vertx.core.json.JsonArray;
import io.vertx.ext.web.RoutingContext;
@@ -10,23 +10,20 @@ import lombok.extern.slf4j.Slf4j;
import static cn.qaiu.vx.core.util.ConfigConstant.IGNORES_REG;
/**
* 默认拦截器实现
* 校验用户是否合法 <br>
* TODO 暂时只做简单实现
* 前置拦截器实现
*/
@Slf4j
public class DefaultInterceptor implements Interceptor, BaseHttpApi {
@HandleSortFilter(1)
public class DefaultInterceptor implements BeforeInterceptor {
protected final JsonArray ignores = SharedDataUtil.getJsonArrayForCustomConfig(IGNORES_REG);
@Override
public void beforeHandle(RoutingContext ctx) {
public void handle(RoutingContext ctx) {
System.out.println("进入前置拦截器->" + ctx.request().path());
ctx.next();
}
@Override
public void afterHandle(RoutingContext ctx) {
}
}

View File

@@ -0,0 +1,26 @@
package cn.qaiu.lz.common.interceptorImpl;
import cn.qaiu.vx.core.annotaions.HandleSortFilter;
import cn.qaiu.vx.core.interceptor.AfterInterceptor;
import cn.qaiu.vx.core.util.SharedDataUtil;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import lombok.extern.slf4j.Slf4j;
import static cn.qaiu.vx.core.util.ConfigConstant.IGNORES_REG;
/**
*
*/
@Slf4j
@HandleSortFilter(99)
public class LogStatistics implements AfterInterceptor {
protected final JsonArray ignores = SharedDataUtil.getJsonArrayForCustomConfig(IGNORES_REG);
@Override
public void handle(HttpServerRequest request, JsonObject responseData) {
System.out.println("后置拦截-->" + responseData + " path:" + request.path());
}
}

View File

@@ -15,6 +15,7 @@ public interface IPanTool {
case "uc" -> new UcTool(key, pwd);
case "ye" -> new YeTool(key, pwd);
case "fj" -> new FjTool(key, pwd);
case "qk" -> new QkTool(key, pwd);
default -> {
throw new UnsupportedOperationException("未知分享类型");
}

View File

@@ -90,7 +90,7 @@ public class LzTool extends PanBase implements IPanTool {
private String getJsText(String html) {
String jsTagStart = "<script type=\"text/javascript\">";
String jsTagEnd = "</script>";
int index = html.indexOf(jsTagStart);
int index = html.lastIndexOf(jsTagStart);
if (index == -1) {
return null;
}

View File

@@ -1,12 +1,20 @@
package cn.qaiu.lz.common.parser.impl;
import cn.qaiu.lz.common.parser.IPanTool;
import cn.qaiu.lz.common.parser.PanBase;
import io.vertx.core.Future;
import io.vertx.core.Promise;
public class QkTool {
public static Future<String> parse() {
public class QkTool extends PanBase implements IPanTool {
public QkTool(String key, String pwd) {
super(key, pwd);
}
public Future<String> parse() {
Promise<String> promise = Promise.promise();
promise.complete("https://lz.qaiu.top");
return promise.future();
}
}

View File

@@ -8,6 +8,7 @@ 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.util.AsyncServiceUtil;
import cn.qaiu.vx.core.util.ResponseUtil;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.core.http.HttpServerRequest;
@@ -44,8 +45,7 @@ public class ServerApi {
}
try {
IPanTool.shareURLPrefixMatching(url, pwd).parse().onSuccess(resUrl -> {
response.putHeader("location", resUrl).setStatusCode(302).end();
promise.complete();
ResponseUtil.redirect(response, resUrl, promise);
}).onFailure(t -> promise.fail(t.fillInStackTrace()));
} catch (Exception e) {
promise.fail(e);
@@ -72,8 +72,7 @@ public class ServerApi {
code = keys[1];
}
IPanTool.typeMatching(type, key, code).parse().onSuccess(resUrl -> response.putHeader("location", resUrl)
.setStatusCode(302).end()).onFailure(t -> {
IPanTool.typeMatching(type, key, code).parse().onSuccess(resUrl -> ResponseUtil.redirect(response, resUrl)).onFailure(t -> {
response.putHeader(CONTENT_TYPE, "text/html;charset=utf-8");
response.end(t.getMessage());
});

View File

@@ -50,6 +50,12 @@ public class TestAESUtil {
Assert.assertEquals(146731, AESUtils.idEncrypt("7jy0zlv"));
}
@Test
public void test00() throws IllegalBlockSizeException, NoSuchPaddingException, BadPaddingException,
NoSuchAlgorithmException, InvalidKeyException {
System.out.println(AESUtils.decryptByBase64AES(AESUtils.CIPHER_AES2, AESUtils.CIPHER_AES));
}
@Test
public void testTs() {
System.out.println(System.currentTimeMillis());