针对http请求前置处理优化

This commit is contained in:
aoshiguchen
2022-07-22 21:56:40 +08:00
parent 6c95264ead
commit d486b9f4bb
4 changed files with 193 additions and 6 deletions
@@ -28,6 +28,8 @@ import fun.asgc.neutrino.core.annotation.NonIntercept;
import fun.asgc.neutrino.core.constant.MetaDataConstant;
import fun.asgc.neutrino.core.context.ApplicationConfig;
import fun.asgc.neutrino.core.util.*;
import fun.asgc.neutrino.core.web.param.HttpContextHolder;
import fun.asgc.neutrino.core.web.param.HttpRequestParser;
import fun.asgc.neutrino.core.web.router.DefaultHttpRouter;
import fun.asgc.neutrino.core.web.router.HttpRouteParam;
import fun.asgc.neutrino.core.web.router.HttpRouteResult;
@@ -37,6 +39,7 @@ import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.*;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.C;
import java.util.Date;
@@ -55,12 +58,16 @@ public class HttpRequestHandler {
private DefaultHttpRouter defaultHttpRouter;
private static volatile String httpContextPath;
public void handle(ChannelHandlerContext context, FullHttpRequest request) {
String routePath = getRoutePath(request.uri());
HttpMethod httpMethod = HttpMethod.of(request.method().name());
public void handle() {
ChannelHandlerContext context = HttpContextHolder.getChannelHandlerContext();
HttpRequestParser requestParser = HttpContextHolder.getHttpRequestParser();
log.info("HttpRequest method:{} url:{} query:{}", requestParser.getMethod().name(), requestParser.getUrl(), requestParser.getQueryParamMap());
String routePath = getRoutePath(requestParser.getUrl());
HttpMethod httpMethod = HttpMethod.of(requestParser.getMethod().name());
HttpRouteResult httpRouteResult = defaultHttpRouter.route(new HttpRouteParam().setMethod(httpMethod).setUrl(routePath));
if (null == httpRouteResult) {
HttpServerUtil.send404Response(context, request.uri());
HttpServerUtil.send404Response(context, requestParser.getUrl());
return;
}
if (HttpRouterType.METHOD == httpRouteResult.getType()) {
@@ -92,7 +99,7 @@ public class HttpRequestHandler {
return;
} else {
// TODO
HttpServerUtil.send404Response(context, request.uri());
HttpServerUtil.send404Response(context, requestParser.getUrl());
return;
}
}
@@ -28,6 +28,7 @@ import fun.asgc.neutrino.core.annotation.Init;
import fun.asgc.neutrino.core.context.ApplicationConfig;
import fun.asgc.neutrino.core.context.ApplicationRunner;
import fun.asgc.neutrino.core.util.*;
import fun.asgc.neutrino.core.web.param.HttpContextHolder;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
@@ -89,10 +90,12 @@ public class WebApplicationServer implements ApplicationRunner {
pipeline.addLast(new SimpleChannelInboundHandler<FullHttpRequest>() {
@Override
protected void channelRead0(ChannelHandlerContext context, FullHttpRequest request) throws Exception {
HttpContextHolder.init(context, request);
String uri = request.uri();
log.debug("http request: {}", uri);
if (uri.startsWith(http.getContextPath() + "/") || uri.equals(http.getContextPath())) {
httpRequestHandler.handle(context, request);
httpRequestHandler.handle();
} else if (uri.equals("/favicon.ico") && null != faviconBytes) {
FullHttpResponse fullHttpResponse = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.wrappedBuffer(faviconBytes));
fullHttpResponse.headers().add(HttpHeaderNames.CONTENT_TYPE, "image/x-icon");
@@ -0,0 +1,68 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* 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.
*/
package fun.asgc.neutrino.core.web.param;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.FullHttpRequest;
/**
*
* @author: aoshiguchen
* @date: 2022/7/22
*/
public abstract class HttpContextHolder {
private static final ThreadLocal<HttpRequestParser> httpRequestParserHolder = new ThreadLocal<>();
private static ThreadLocal<FullHttpRequest> fullHttpRequestHolder = new ThreadLocal<>();
private static ThreadLocal<ChannelHandlerContext> channelHandlerContextHolder = new ThreadLocal<>();
public static void remove() {
httpRequestParserHolder.remove();
fullHttpRequestHolder.remove();
channelHandlerContextHolder.remove();
}
public static void setFullHttpRequest(FullHttpRequest request) {
fullHttpRequestHolder.set(request);
httpRequestParserHolder.set(HttpRequestParser.create(request));
}
public static void setChannelHandlerContext(ChannelHandlerContext context) {
channelHandlerContextHolder.set(context);
}
public static HttpRequestParser getHttpRequestParser() {
return httpRequestParserHolder.get();
}
public static FullHttpRequest getFullHttpRequest() {
return fullHttpRequestHolder.get();
}
public static ChannelHandlerContext getChannelHandlerContext() {
return channelHandlerContextHolder.get();
}
public static void init(ChannelHandlerContext context, FullHttpRequest request) {
setChannelHandlerContext(context);
setFullHttpRequest(request);
}
}
@@ -0,0 +1,109 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* 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.
*/
package fun.asgc.neutrino.core.web.param;
import fun.asgc.neutrino.core.util.LockUtil;
import fun.asgc.neutrino.core.util.StringUtil;
import io.netty.buffer.ByteBuf;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.util.CharsetUtil;
import java.util.HashMap;
import java.util.Map;
/**
* Http请求解析器
* @author: aoshiguchen
* @date: 2022/7/22
*/
public class HttpRequestParser {
private FullHttpRequest request;
private String url;
private String queryString;
private Map<String, String> queryParamMap = null;
private HttpRequestParser(FullHttpRequest request) {
this.request = request;
this.url = request.uri();
this.queryString = "";
int index = url.indexOf("?");
if (index >= 0) {
if (index < url.length() - 1) {
this.queryString = url.substring(index + 1);
}
url = getUrl().substring(0, index);
}
}
public static HttpRequestParser create(FullHttpRequest request) {
return new HttpRequestParser(request);
}
public String getUrl() {
return url;
}
public String getQueryString() {
return queryString;
}
public Map<String, String> getQueryParamMap() {
return LockUtil.doubleCheckProcessForNoException(
() -> null == queryParamMap,
this,
() -> {
queryParamMap = new HashMap<>();
if (StringUtil.isEmpty(queryString)) {
return;
}
String[] params = queryString.split("&");
for (String param : params) {
int index2 = param.indexOf("=");
String key = "";
String val = "";
if (index2 > 0) {
key = param.substring(0, index2);
if (index2 < param.length() - 1) {
val = param.substring(index2 + 1);
}
queryParamMap.put(key, val);
}
}
},
() -> queryParamMap
);
}
public HttpMethod getMethod() {
return request.method();
}
public ByteBuf getContent() {
return request.content();
}
public String getContentAsString() {
return getContent().toString(CharsetUtil.UTF_8);
}
}