diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerConfig.java b/LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerConfig.java index cd5d3072..54b01ce6 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerConfig.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerConfig.java @@ -296,6 +296,7 @@ public static class NettyConfig { public boolean fileServerEnabled; public boolean sendExceptionEnabled; public boolean ipForwarding; + public boolean disableWebApiInterface; public boolean showHiddenFiles; public String launcherURL; public String downloadURL; diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/LauncherNettyServer.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/LauncherNettyServer.java index 7355a93c..f0f5a1dd 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/LauncherNettyServer.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/LauncherNettyServer.java @@ -17,6 +17,7 @@ import pro.gravit.launchserver.LaunchServer; import pro.gravit.launchserver.config.LaunchServerConfig; import pro.gravit.launchserver.socket.handlers.NettyIpForwardHandler; +import pro.gravit.launchserver.socket.handlers.NettyWebAPIHandler; import pro.gravit.launchserver.socket.handlers.WebSocketFrameHandler; import pro.gravit.launchserver.socket.handlers.fileserver.FileServerHandler; import pro.gravit.utils.BiHookSet; @@ -60,6 +61,8 @@ public void initChannel(SocketChannel ch) { pipeline.addLast("forward-http", new NettyIpForwardHandler(context)); pipeline.addLast("websock-comp", new WebSocketServerCompressionHandler()); pipeline.addLast("websock-codec", new WebSocketServerProtocolHandler(WEBSOCKET_PATH, null, true)); + if(!server.config.netty.disableWebApiInterface) + pipeline.addLast("webapi", new NettyWebAPIHandler(context)); if (server.config.netty.fileServerEnabled) pipeline.addLast("fileserver", new FileServerHandler(server.updatesDir, true, config.showHiddenFiles)); pipeline.addLast("launchserver", new WebSocketFrameHandler(context, server, service)); diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/handlers/NettyWebAPIHandler.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/handlers/NettyWebAPIHandler.java new file mode 100644 index 00000000..f145bd02 --- /dev/null +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/handlers/NettyWebAPIHandler.java @@ -0,0 +1,78 @@ +package pro.gravit.launchserver.socket.handlers; + +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; +import io.netty.handler.codec.MessageToMessageDecoder; +import io.netty.handler.codec.http.*; +import io.netty.util.ReferenceCounted; +import pro.gravit.launchserver.socket.NettyConnectContext; +import pro.gravit.utils.BiHookSet; +import pro.gravit.utils.HookSet; +import pro.gravit.utils.helper.LogHelper; + +import java.net.URI; +import java.util.*; + +import static io.netty.handler.codec.http.HttpResponseStatus.NOT_MODIFIED; +import static io.netty.handler.codec.http.HttpResponseStatus.OK; +import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; + +public class NettyWebAPIHandler extends SimpleChannelInboundHandler { + private final NettyConnectContext context; + + public NettyWebAPIHandler(NettyConnectContext context) { + super(); + this.context = context; + } + @FunctionalInterface + public interface SimpleSeverletHandler { + void handle(ChannelHandlerContext ctx, FullHttpRequest msg, NettyConnectContext context) throws Exception; + } + public static class SeverletPathPair { + public final String key; + public final SimpleSeverletHandler callback; + + public SeverletPathPair(String key, SimpleSeverletHandler callback) { + this.key = key; + this.callback = callback; + } + } + private static ArrayList severletList = new ArrayList<>(); + public static SeverletPathPair addNewSeverlet(String path, SimpleSeverletHandler callback) + { + SeverletPathPair pair = new SeverletPathPair("/webapi/".concat(path), callback); + severletList.add(pair); + severletList.sort(Comparator.comparingInt((a) -> -a.key.length())); + return pair; + } + public static SeverletPathPair addUnsafeSeverlet(String path, SimpleSeverletHandler callback) + { + SeverletPathPair pair = new SeverletPathPair(path, callback); + severletList.add(pair); + severletList.sort(Comparator.comparingInt((a) -> -a.key.length())); + return pair; + } + public static void removeSeverlet(SeverletPathPair pair) + { + severletList.remove(pair); + } + @Override + protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) throws Exception { + boolean isNext = true; + for(SeverletPathPair pair : severletList) + { + if(msg.uri().startsWith(pair.key)) + { + pair.callback.handle(ctx, msg, context); + isNext = false; + break; + } + } + if(isNext) + { + msg.retain(); + ctx.fireChannelRead(msg); + } + } +}