diff --git a/boot/build.gradle b/boot/build.gradle index 9d5fbcec..9831ce58 100644 --- a/boot/build.gradle +++ b/boot/build.gradle @@ -48,6 +48,7 @@ dependencies { implementation('org.springframework.boot:spring-boot-starter-web') { exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat' } + implementation 'org.apache.commons:commons-lang3:3.+' implementation 'org.springframework.boot:spring-boot-starter-undertow' compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' diff --git a/boot/src/main/java/com/reajason/javaweb/boot/dto/GenerateRequest.java b/boot/src/main/java/com/reajason/javaweb/boot/dto/GenerateRequest.java index 5684cbcb..6dea5a30 100644 --- a/boot/src/main/java/com/reajason/javaweb/boot/dto/GenerateRequest.java +++ b/boot/src/main/java/com/reajason/javaweb/boot/dto/GenerateRequest.java @@ -2,7 +2,9 @@ package com.reajason.javaweb.boot.dto; import com.reajason.javaweb.memshell.Packers; import com.reajason.javaweb.memshell.config.*; +import com.reajason.javaweb.memshell.utils.CommonUtil; import lombok.Data; +import org.apache.commons.lang3.StringUtils; /** * @author ReaJason @@ -32,36 +34,36 @@ public class GenerateRequest { return switch (shellConfig.getShellTool()) { case Godzilla -> GodzillaConfig.builder() .shellClassName(shellToolConfig.getShellClassName()) - .pass(shellToolConfig.getGodzillaPass()) - .key(shellToolConfig.getGodzillaKey()) + .pass(StringUtils.defaultIfBlank(shellToolConfig.getGodzillaPass(), CommonUtil.getRandomString(8))) + .key(StringUtils.defaultIfBlank(shellToolConfig.getGodzillaKey(), CommonUtil.getRandomString(8))) .headerName(shellToolConfig.getHeaderName()) - .headerValue(shellToolConfig.getHeaderValue()) + .headerValue(StringUtils.defaultIfBlank(shellToolConfig.getHeaderValue(), CommonUtil.getRandomString(8))) .build(); case Behinder -> BehinderConfig.builder() .shellClassName(shellToolConfig.getShellClassName()) - .pass(shellToolConfig.getBehinderPass()) + .pass(StringUtils.defaultIfBlank(shellToolConfig.getBehinderPass(), CommonUtil.getRandomString(8))) .headerName(shellToolConfig.getHeaderName()) - .headerValue(shellToolConfig.getHeaderValue()) + .headerValue(StringUtils.defaultIfBlank(shellToolConfig.getHeaderValue(), CommonUtil.getRandomString(8))) .build(); case Command -> CommandConfig.builder() .shellClassName(shellToolConfig.getShellClassName()) - .paramName(shellToolConfig.getCommandParamName()) + .paramName(StringUtils.defaultIfBlank(shellToolConfig.getCommandParamName(), CommonUtil.getRandomString(8))) .build(); case Suo5 -> Suo5Config.builder() .shellClassName(shellToolConfig.getShellClassName()) .headerName(shellToolConfig.getHeaderName()) - .headerValue(shellToolConfig.getHeaderValue()) + .headerValue(StringUtils.defaultIfBlank(shellToolConfig.getHeaderValue(), CommonUtil.getRandomString(8))) .build(); case AntSword -> AntSwordConfig.builder() .shellClassName(shellToolConfig.getShellClassName()) - .pass(shellToolConfig.getAntSwordPass()) + .pass(StringUtils.defaultIfBlank(shellToolConfig.getAntSwordPass(), CommonUtil.getRandomString(8))) .headerName(shellToolConfig.getHeaderName()) - .headerValue(shellToolConfig.getHeaderValue()) + .headerValue(StringUtils.defaultIfBlank(shellToolConfig.getHeaderValue(), CommonUtil.getRandomString(8))) .build(); case NeoreGeorg -> NeoreGeorgConfig.builder() .shellClassName(shellToolConfig.getShellClassName()) .headerName(shellToolConfig.getHeaderName()) - .headerValue(shellToolConfig.getHeaderValue()) + .headerValue(StringUtils.defaultIfBlank(shellToolConfig.getHeaderValue(), CommonUtil.getRandomString(8))) .build(); case Custom -> CustomConfig.builder() .shellClassBase64(shellToolConfig.getShellClassBase64()) diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/config/AntSwordConfig.java b/generator/src/main/java/com/reajason/javaweb/memshell/config/AntSwordConfig.java index 569bdc55..c9c325c6 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/config/AntSwordConfig.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/config/AntSwordConfig.java @@ -15,7 +15,7 @@ import lombok.experimental.SuperBuilder; @ToString public class AntSwordConfig extends ShellToolConfig { @Builder.Default - private String pass = "pass"; + private String pass = CommonUtil.getRandomString(8); @Builder.Default private String headerName = "User-Agent"; @Builder.Default diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/config/BehinderConfig.java b/generator/src/main/java/com/reajason/javaweb/memshell/config/BehinderConfig.java index 10cf9d64..29a4bc40 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/config/BehinderConfig.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/config/BehinderConfig.java @@ -15,7 +15,7 @@ import lombok.experimental.SuperBuilder; @ToString public class BehinderConfig extends ShellToolConfig { @Builder.Default - private String pass = "pass"; + private String pass = CommonUtil.getRandomString(8); @Builder.Default private String headerName = "User-Agent"; @Builder.Default diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/config/CommandConfig.java b/generator/src/main/java/com/reajason/javaweb/memshell/config/CommandConfig.java index d9ad38b8..85907532 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/config/CommandConfig.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/config/CommandConfig.java @@ -1,5 +1,6 @@ package com.reajason.javaweb.memshell.config; +import com.reajason.javaweb.memshell.utils.CommonUtil; import lombok.Builder; import lombok.Getter; import lombok.ToString; @@ -14,5 +15,5 @@ import lombok.experimental.SuperBuilder; @ToString public class CommandConfig extends ShellToolConfig { @Builder.Default - private String paramName = "cmd"; + private String paramName = CommonUtil.getRandomString(8); } diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/config/GodzillaConfig.java b/generator/src/main/java/com/reajason/javaweb/memshell/config/GodzillaConfig.java index 67956665..98f40640 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/config/GodzillaConfig.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/config/GodzillaConfig.java @@ -15,9 +15,9 @@ import lombok.experimental.SuperBuilder; @ToString public class GodzillaConfig extends ShellToolConfig { @Builder.Default - private String pass = "pass"; + private String pass = CommonUtil.getRandomString(8); @Builder.Default - private String key = "key"; + private String key = CommonUtil.getRandomString(8); @Builder.Default private String headerName = "User-Agent"; @Builder.Default diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/server/ApusicShell.java b/generator/src/main/java/com/reajason/javaweb/memshell/server/ApusicShell.java index 0488c3de..9755da11 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/server/ApusicShell.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/server/ApusicShell.java @@ -30,8 +30,9 @@ public class ApusicShell extends AbstractShell { @Override public InjectorMapping getShellInjectorMapping() { return InjectorMapping.builder() - .addInjector(SERVLET, ApusicServletInjector.class) + .addInjector(LISTENER, ApusicListenerInjector.class) .addInjector(FILTER, ApusicFilterInjector.class) - .addInjector(LISTENER, ApusicListenerInjector.class).build(); + .addInjector(SERVLET, ApusicServletInjector.class) + .build(); } } diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/server/BesShell.java b/generator/src/main/java/com/reajason/javaweb/memshell/server/BesShell.java index e9d22373..c42537a5 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/server/BesShell.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/server/BesShell.java @@ -18,8 +18,8 @@ public class BesShell extends AbstractShell { @Override public InjectorMapping getShellInjectorMapping() { return InjectorMapping.builder() - .addInjector(FILTER, BesFilterInjector.class) .addInjector(LISTENER, BesListenerInjector.class) + .addInjector(FILTER, BesFilterInjector.class) .addInjector(VALVE, BesValveInjector.class) .addInjector(AGENT_FILTER_CHAIN, BesFilterChainAgentInjector.class) .addInjector(AGENT_FILTER_CHAIN_ASM, BesFilterChainAgentWithAsmInjector.class) diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/server/GlassFishShell.java b/generator/src/main/java/com/reajason/javaweb/memshell/server/GlassFishShell.java index a3d8aa8d..dcbc4c76 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/server/GlassFishShell.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/server/GlassFishShell.java @@ -44,10 +44,10 @@ public class GlassFishShell extends AbstractShell { @Override public InjectorMapping getShellInjectorMapping() { return InjectorMapping.builder() - .addInjector(FILTER, GlassFishFilterInjector.class) - .addInjector(JAKARTA_FILTER, GlassFishFilterInjector.class) .addInjector(LISTENER, GlassFishListenerInjector.class) .addInjector(JAKARTA_LISTENER, GlassFishListenerInjector.class) + .addInjector(FILTER, GlassFishFilterInjector.class) + .addInjector(JAKARTA_FILTER, GlassFishFilterInjector.class) .addInjector(VALVE, GlassFishValveInjector.class) .addInjector(JAKARTA_VALVE, GlassFishValveInjector.class) .addInjector(AGENT_FILTER_CHAIN, TomcatFilterChainAgentInjector.class) diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/server/InforSuiteShell.java b/generator/src/main/java/com/reajason/javaweb/memshell/server/InforSuiteShell.java index 449678a7..e2ff683a 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/server/InforSuiteShell.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/server/InforSuiteShell.java @@ -24,10 +24,10 @@ public class InforSuiteShell extends AbstractShell { @Override public InjectorMapping getShellInjectorMapping() { return InjectorMapping.builder() - .addInjector(FILTER, InforSuiteFilterInjector.class) - .addInjector(JAKARTA_FILTER, InforSuiteFilterInjector.class) .addInjector(LISTENER, GlassFishListenerInjector.class) .addInjector(JAKARTA_LISTENER, GlassFishListenerInjector.class) + .addInjector(FILTER, InforSuiteFilterInjector.class) + .addInjector(JAKARTA_FILTER, InforSuiteFilterInjector.class) .addInjector(VALVE, GlassFishValveInjector.class) .addInjector(JAKARTA_VALVE, GlassFishValveInjector.class) .addInjector(AGENT_FILTER_CHAIN, TomcatFilterChainAgentInjector.class) diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/server/JbossShell.java b/generator/src/main/java/com/reajason/javaweb/memshell/server/JbossShell.java index 7ac7ff04..86498c4a 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/server/JbossShell.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/server/JbossShell.java @@ -24,8 +24,8 @@ public class JbossShell extends AbstractShell { @Override public InjectorMapping getShellInjectorMapping() { return InjectorMapping.builder() - .addInjector(FILTER, JbossFilterInjector.class) .addInjector(LISTENER, JbossListenerInjector.class) + .addInjector(FILTER, JbossFilterInjector.class) .addInjector(VALVE, JbossValveInjector.class) .addInjector(AGENT_FILTER_CHAIN, TomcatFilterChainAgentInjector.class) .addInjector(AGENT_FILTER_CHAIN_ASM, TomcatFilterChainAgentWithAsmInjector.class) diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/server/JettyShell.java b/generator/src/main/java/com/reajason/javaweb/memshell/server/JettyShell.java index b5c1ef57..9ca6e28b 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/server/JettyShell.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/server/JettyShell.java @@ -33,12 +33,12 @@ public class JettyShell extends AbstractShell { @Override public InjectorMapping getShellInjectorMapping() { return InjectorMapping.builder() - .addInjector(SERVLET, JettyServletInjector.class) - .addInjector(JAKARTA_SERVLET, JettyServletInjector.class) - .addInjector(FILTER, JettyFilterInjector.class) - .addInjector(JAKARTA_FILTER, JettyFilterInjector.class) .addInjector(LISTENER, JettyListenerInjector.class) .addInjector(JAKARTA_LISTENER, JettyListenerInjector.class) + .addInjector(FILTER, JettyFilterInjector.class) + .addInjector(JAKARTA_FILTER, JettyFilterInjector.class) + .addInjector(SERVLET, JettyServletInjector.class) + .addInjector(JAKARTA_SERVLET, JettyServletInjector.class) .addInjector(JETTY_AGENT_HANDLER, JettyHandlerAgentInjector.class) .addInjector(JETTY_AGENT_HANDLER_ASM, JettyHandlerAgentWithAsmInjector.class) .build(); diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/server/ResinShell.java b/generator/src/main/java/com/reajason/javaweb/memshell/server/ResinShell.java index c7fb4d3f..67d06b98 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/server/ResinShell.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/server/ResinShell.java @@ -28,9 +28,9 @@ public class ResinShell extends AbstractShell { @Override public InjectorMapping getShellInjectorMapping() { return InjectorMapping.builder() - .addInjector(SERVLET, ResinServletInjector.class) - .addInjector(FILTER, ResinFilterInjector.class) .addInjector(LISTENER, ResinListenerInjector.class) + .addInjector(FILTER, ResinFilterInjector.class) + .addInjector(SERVLET, ResinServletInjector.class) .addInjector(AGENT_FILTER_CHAIN, ResinFilterChainAgentInjector.class) .addInjector(AGENT_FILTER_CHAIN_ASM, ResinFilterChainAgentWithAsmInjector.class) .build(); diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/server/ServerToolRegistry.java b/generator/src/main/java/com/reajason/javaweb/memshell/server/ServerToolRegistry.java index 766fff7d..34dcaffc 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/server/ServerToolRegistry.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/server/ServerToolRegistry.java @@ -23,12 +23,11 @@ public class ServerToolRegistry { Set injectorSupportedShellTypes = shellInjectorMapping.getSupportedShellTypes(); ToolMapping.ToolMappingBuilder toolMappingBuilder = ToolMapping.builder(); - for (Map.Entry> entry : rawToolMapping.entrySet()) { - String shellType = entry.getKey(); - if (!injectorSupportedShellTypes.contains(shellType)) { + for (String shellType : injectorSupportedShellTypes) { + Class shellClass = rawToolMapping.get(shellType); + if (shellClass == null) { continue; } - Class shellClass = entry.getValue(); if (ShellType.LISTENER.equals(shellType) || ShellType.JAKARTA_LISTENER.equals(shellType)) { shellClass = ListenerGenerator.generateListenerShellClass(shell.getListenerInterceptor(), shellClass); diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/server/SpringWebFluxShell.java b/generator/src/main/java/com/reajason/javaweb/memshell/server/SpringWebFluxShell.java index 3aa983c0..bfb87f95 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/server/SpringWebFluxShell.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/server/SpringWebFluxShell.java @@ -17,9 +17,9 @@ public class SpringWebFluxShell extends AbstractShell { public InjectorMapping getShellInjectorMapping() { return InjectorMapping.builder() .addInjector(SPRING_WEBFLUX_WEB_FILTER, SpringWebFluxWebFilterInjector.class) + .addInjector(NETTY_HANDLER, SpringWebFluxNettyHandlerInjector.class) .addInjector(SPRING_WEBFLUX_HANDLER_METHOD, SpringWebFluxHandlerMethodInjector.class) .addInjector(SPRING_WEBFLUX_HANDLER_FUNCTION, SpringWebFluxHandlerFunctionInjector.class) - .addInjector(NETTY_HANDLER, SpringWebFluxNettyHandlerInjector.class) .build(); } } diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/server/TomcatShell.java b/generator/src/main/java/com/reajason/javaweb/memshell/server/TomcatShell.java index 08493e1a..2cd30b6b 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/server/TomcatShell.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/server/TomcatShell.java @@ -33,14 +33,14 @@ public class TomcatShell extends AbstractShell { @Override public InjectorMapping getShellInjectorMapping() { return InjectorMapping.builder() - .addInjector(SERVLET, TomcatServletInjector.class) - .addInjector(JAKARTA_SERVLET, TomcatServletInjector.class) - .addInjector(FILTER, TomcatFilterInjector.class) - .addInjector(JAKARTA_FILTER, TomcatFilterInjector.class) .addInjector(LISTENER, TomcatListenerInjector.class) .addInjector(JAKARTA_LISTENER, TomcatListenerInjector.class) + .addInjector(FILTER, TomcatFilterInjector.class) + .addInjector(JAKARTA_FILTER, TomcatFilterInjector.class) .addInjector(VALVE, TomcatValveInjector.class) .addInjector(JAKARTA_VALVE, TomcatValveInjector.class) + .addInjector(SERVLET, TomcatServletInjector.class) + .addInjector(JAKARTA_SERVLET, TomcatServletInjector.class) .addInjector(AGENT_FILTER_CHAIN, TomcatFilterChainAgentInjector.class) .addInjector(AGENT_FILTER_CHAIN_ASM, TomcatFilterChainAgentWithAsmInjector.class) .addInjector(CATALINA_AGENT_CONTEXT_VALVE, TomcatContextValveAgentInjector.class) diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/server/TongWeb6Shell.java b/generator/src/main/java/com/reajason/javaweb/memshell/server/TongWeb6Shell.java index 0b6dc537..b5eebad2 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/server/TongWeb6Shell.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/server/TongWeb6Shell.java @@ -18,10 +18,10 @@ public class TongWeb6Shell extends AbstractShell { @Override public InjectorMapping getShellInjectorMapping() { return InjectorMapping.builder() - .addInjector(FILTER, TongWebFilterInjector.class) - .addInjector(JAKARTA_FILTER, TongWebFilterInjector.class) .addInjector(LISTENER, TongWebListenerInjector.class) .addInjector(JAKARTA_LISTENER, TongWebListenerInjector.class) + .addInjector(FILTER, TongWebFilterInjector.class) + .addInjector(JAKARTA_FILTER, TongWebFilterInjector.class) .addInjector(VALVE, TongWebValveInjector.class) .addInjector(JAKARTA_VALVE, TongWebValveInjector.class) .addInjector(AGENT_FILTER_CHAIN, TongWebFilterChainAgentInjector.class) diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/server/TongWeb7Shell.java b/generator/src/main/java/com/reajason/javaweb/memshell/server/TongWeb7Shell.java index 3f8b885c..9b4a581f 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/server/TongWeb7Shell.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/server/TongWeb7Shell.java @@ -18,10 +18,10 @@ public class TongWeb7Shell extends AbstractShell { @Override public InjectorMapping getShellInjectorMapping() { return InjectorMapping.builder() - .addInjector(FILTER, TongWebFilterInjector.class) - .addInjector(JAKARTA_FILTER, TongWebFilterInjector.class) .addInjector(LISTENER, TongWebListenerInjector.class) .addInjector(JAKARTA_LISTENER, TongWebListenerInjector.class) + .addInjector(FILTER, TongWebFilterInjector.class) + .addInjector(JAKARTA_FILTER, TongWebFilterInjector.class) .addInjector(VALVE, TongWebValveInjector.class) .addInjector(JAKARTA_VALVE, TongWebValveInjector.class) .addInjector(AGENT_FILTER_CHAIN, TongWebFilterChainAgentInjector.class) diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/server/UndertowShell.java b/generator/src/main/java/com/reajason/javaweb/memshell/server/UndertowShell.java index c032b68c..1e16a590 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/server/UndertowShell.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/server/UndertowShell.java @@ -38,12 +38,12 @@ public class UndertowShell extends AbstractShell { @Override public InjectorMapping getShellInjectorMapping() { return InjectorMapping.builder() - .addInjector(SERVLET, UndertowServletInjector.class) - .addInjector(JAKARTA_SERVLET, UndertowServletInjector.class) - .addInjector(FILTER, UndertowFilterInjector.class) - .addInjector(JAKARTA_FILTER, UndertowFilterInjector.class) .addInjector(LISTENER, UndertowListenerInjector.class) .addInjector(JAKARTA_LISTENER, UndertowListenerInjector.class) + .addInjector(FILTER, UndertowFilterInjector.class) + .addInjector(JAKARTA_FILTER, UndertowFilterInjector.class) + .addInjector(SERVLET, UndertowServletInjector.class) + .addInjector(JAKARTA_SERVLET, UndertowServletInjector.class) .addInjector(UNDERTOW_AGENT_SERVLET_HANDLER, UndertowServletInitialHandlerAgentInjector.class) .addInjector(UNDERTOW_AGENT_SERVLET_HANDLER_ASM, UndertowServletInitialHandlerAgentWithAsmInjector.class) .build(); diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/server/WebLogicShell.java b/generator/src/main/java/com/reajason/javaweb/memshell/server/WebLogicShell.java index e15cd11b..acd24ff2 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/server/WebLogicShell.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/server/WebLogicShell.java @@ -18,9 +18,9 @@ public class WebLogicShell extends AbstractShell { @Override public InjectorMapping getShellInjectorMapping() { return InjectorMapping.builder() - .addInjector(SERVLET, WebLogicServletInjector.class) - .addInjector(FILTER, WebLogicFilterInjector.class) .addInjector(LISTENER, WebLogicListenerInjector.class) + .addInjector(FILTER, WebLogicFilterInjector.class) + .addInjector(SERVLET, WebLogicServletInjector.class) .addInjector(WEBLOGIC_AGENT_SERVLET_CONTEXT, WebLogicServletContextAgentInjector.class) .addInjector(WEBLOGIC_AGENT_SERVLET_CONTEXT_ASM, WebLogicServletContextAgentWithAsmInjector.class) .build(); diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/server/WebSphereShell.java b/generator/src/main/java/com/reajason/javaweb/memshell/server/WebSphereShell.java index c7b5a1f0..17852694 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/server/WebSphereShell.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/server/WebSphereShell.java @@ -29,9 +29,9 @@ public class WebSphereShell extends AbstractShell { @Override public InjectorMapping getShellInjectorMapping() { return InjectorMapping.builder() - .addInjector(SERVLET, WebSphereServletInjector.class) - .addInjector(FILTER, WebSphereFilterInjector.class) .addInjector(LISTENER, WebSphereListenerInjector.class) + .addInjector(FILTER, WebSphereFilterInjector.class) + .addInjector(SERVLET, WebSphereServletInjector.class) .addInjector(WAS_AGENT_FILTER_MANAGER, WebSphereFilterChainAgentInjector.class) .addInjector(WAS_AGENT_FILTER_MANAGER_ASM, WebSphereFilterChainAgentWithAsmInjector.class) .build(); diff --git a/web/src/components/layouts/root-layout.tsx b/web/src/components/layouts/root-layout.tsx index 0e9c32b4..f6e6cf16 100644 --- a/web/src/components/layouts/root-layout.tsx +++ b/web/src/components/layouts/root-layout.tsx @@ -1,13 +1,12 @@ import { LanguageSwitcher } from "@/components/language-switcher"; import { ModeToggle } from "@/components/mode-toggle.tsx"; import { ThemeProvider } from "@/components/theme-provider.tsx"; +import { Button } from "@/components/ui/button"; import { Toaster } from "@/components/ui/sonner"; import VersionBadge from "@/components/version-badge"; import { GitHubIcon } from "@/icon"; -import { Button } from "@/components/ui/button"; import { Outlet } from "react-router-dom"; - export default function RootLayout() { return ( @@ -39,4 +38,4 @@ export default function RootLayout() { ); -} \ No newline at end of file +} diff --git a/web/src/components/main-config-card.tsx b/web/src/components/main-config-card.tsx index f658b2a1..166a2129 100644 --- a/web/src/components/main-config-card.tsx +++ b/web/src/components/main-config-card.tsx @@ -19,7 +19,7 @@ import { WaypointsIcon, ZapIcon, } from "lucide-react"; -import { JSX, useState } from "react"; +import { JSX, useEffect, useState } from "react"; import { FormProvider, UseFormReturn } from "react-hook-form"; import { useTranslation } from "react-i18next"; import { AntSwordTabContent } from "./tools/antsword-tab"; @@ -65,20 +65,45 @@ export function MainConfigCard({ const shellTool = form.watch("shellTool"); const { t } = useTranslation(); + // 处理一下默认值 server 不刷新 shellType 的问题 + useEffect(() => { + if (mainConfig) { + const initialServer = form.getValues("server"); + if (initialServer && mainConfig[initialServer]) { + handleServerChange(initialServer); + } + } + }, [mainConfig, form]); + + // 处理一下 shellTypes 由于 server 或 shellTool 变更时无法正常为 form.shellType 赋值的问题 + useEffect(() => { + if (shellTypes.length > 0) { + form.setValue("shellType", shellTypes[0]); + } + }, [shellTypes, form]); + const handleServerChange = (value: string) => { if (mainConfig) { const newShellToolMap = mainConfig[value]; setShellToolMap(newShellToolMap); + const newShellTools = Object.keys(newShellToolMap); setShellTools([...newShellTools.map((tool) => tool as ShellToolType), ShellToolType.Custom]); - if (newShellTools.length > 0) { - const firstTool = newShellTools[0]; - setShellTypes(newShellToolMap[firstTool]); - form.setValue("shellTool", firstTool); - } else { - setShellTypes([]); - } + const currentShellTool = form.getValues("shellTool"); + + const firstTool = newShellTools[0]; + let currentShellTypes = null; + + if (!newShellToolMap[currentShellTool]) { + form.setValue("shellTool", firstTool); + currentShellTypes = newShellToolMap[firstTool]; + } else { + currentShellTypes = newShellToolMap[currentShellTool]; + } + setShellTypes(currentShellTypes); + + // 特殊环境的 JDK 版本 if ( (value === "SpringWebFlux" || value === "XXLJOB") && Number.parseInt(form.getValues("targetJdkVersion") as string) < 52 @@ -88,8 +113,6 @@ export function MainConfigCard({ form.resetField("targetJdkVersion"); } form.resetField("bypassJavaModule"); - form.resetField("shellTool"); - form.resetField("shellType"); form.resetField("urlPattern"); } }; @@ -133,14 +156,15 @@ export function MainConfigCard({ }; if (shellToolMap) { + let currentShellTypes = null; if (value === ShellToolType.Custom) { - setShellTypes(servers?.[form.getValues("server")] as string[]); + currentShellTypes = servers?.[form.getValues("server")] as string[]; } else { - setShellTypes(shellToolMap[value]); + currentShellTypes = shellToolMap[value]; } + setShellTypes(currentShellTypes); form.resetField("urlPattern"); - form.resetField("shellType"); form.resetField("shellClassName"); form.resetField("injectorClassName"); if (value === ShellToolType.Godzilla) { diff --git a/web/src/components/package-config-card.tsx b/web/src/components/package-config-card.tsx index 7c4c9c81..d6916fd2 100644 --- a/web/src/components/package-config-card.tsx +++ b/web/src/components/package-config-card.tsx @@ -16,10 +16,10 @@ type Option = { export function PackageConfigCard({ packerConfig, form, -}: { +}: Readonly<{ packerConfig: PackerConfig | undefined; form: UseFormReturn; -}) { +}>) { const [options, setOptions] = useState>([]); const shellType = form.watch("shellType"); @@ -39,15 +39,17 @@ export function PackageConfigCard({ } return !name.startsWith("Agent") && !name.toLowerCase().startsWith("xxl"); }); - setOptions( - filteredOptions.map((name) => { - return { - name: t(`packageConfig.packer.${name}`), - value: name, - }; - }), - ); - if (filteredOptions.length > 0) { + + const mappedOptions = filteredOptions.map((name) => { + return { + name: t(`packageConfig.packer.${name}`), + value: name, + }; + }); + + setOptions(mappedOptions); + const currentValue = form.getValues("packingMethod"); + if (filteredOptions.length > 0 && (!currentValue || !filteredOptions.includes(currentValue))) { form.setValue("packingMethod", filteredOptions[0]); } }, [form, packerConfig, server, shellType, t]); diff --git a/web/src/components/tools/antsword-tab.tsx b/web/src/components/tools/antsword-tab.tsx index 29aed920..04ea3f37 100644 --- a/web/src/components/tools/antsword-tab.tsx +++ b/web/src/components/tools/antsword-tab.tsx @@ -28,7 +28,9 @@ export function AntSwordTabContent({ name="antSwordPass" render={({ field }) => ( - {t("shellToolConfig.antSwordPass")} + + {t("shellToolConfig.antSwordPass")} {t("optional")} + )} @@ -49,7 +51,9 @@ export function AntSwordTabContent({ name="headerValue" render={({ field }) => ( - {t("shellToolConfig.headerValue")} + + {t("shellToolConfig.headerValue")} {t("optional")} + )} diff --git a/web/src/components/tools/behinder-tab.tsx b/web/src/components/tools/behinder-tab.tsx index cbc0083d..88fc8fde 100644 --- a/web/src/components/tools/behinder-tab.tsx +++ b/web/src/components/tools/behinder-tab.tsx @@ -28,7 +28,9 @@ export function BehinderTabContent({ name="behinderPass" render={({ field }) => ( - {t("shellToolConfig.behinderPass")} + + {t("shellToolConfig.behinderPass")} {t("optional")} + )} @@ -49,7 +51,9 @@ export function BehinderTabContent({ name="headerValue" render={({ field }) => ( - {t("shellToolConfig.headerValue")} + + {t("shellToolConfig.headerValue")} {t("optional")} + )} diff --git a/web/src/components/tools/command-tab.tsx b/web/src/components/tools/command-tab.tsx index 6fafcb6c..608f5554 100644 --- a/web/src/components/tools/command-tab.tsx +++ b/web/src/components/tools/command-tab.tsx @@ -28,7 +28,9 @@ export function CommandTabContent({ name="commandParamName" render={({ field }) => ( - {t("shellToolConfig.paramName")} + + {t("shellToolConfig.paramName")} {t("optional")} + diff --git a/web/src/components/tools/godzilla-tab.tsx b/web/src/components/tools/godzilla-tab.tsx index f2f30183..b27cb844 100644 --- a/web/src/components/tools/godzilla-tab.tsx +++ b/web/src/components/tools/godzilla-tab.tsx @@ -29,7 +29,9 @@ export function GodzillaTabContent({ name="godzillaPass" render={({ field }) => ( - {t("shellToolConfig.pass")} + + {t("shellToolConfig.pass")} {t("optional")} + )} @@ -39,7 +41,9 @@ export function GodzillaTabContent({ name="godzillaKey" render={({ field }) => ( - {t("shellToolConfig.key")} + + {t("shellToolConfig.key")} {t("optional")} + )} @@ -59,7 +63,9 @@ export function GodzillaTabContent({ name="headerValue" render={({ field }) => ( - {t("shellToolConfig.headerValue")} + + {t("shellToolConfig.headerValue")} {t("optional")} + )} diff --git a/web/src/components/tools/neoreg-tab.tsx b/web/src/components/tools/neoreg-tab.tsx index b27307b6..351f68f3 100644 --- a/web/src/components/tools/neoreg-tab.tsx +++ b/web/src/components/tools/neoreg-tab.tsx @@ -39,7 +39,9 @@ export function NeoRegTabContent({ name="headerValue" render={({ field }) => ( - {t("shellToolConfig.headerValue")} + + {t("shellToolConfig.headerValue")} {t("optional")} + )} diff --git a/web/src/components/tools/suo5-tab.tsx b/web/src/components/tools/suo5-tab.tsx index de260eb3..4a881068 100644 --- a/web/src/components/tools/suo5-tab.tsx +++ b/web/src/components/tools/suo5-tab.tsx @@ -39,7 +39,9 @@ export function Suo5TabContent({ name="headerValue" render={({ field }) => ( - {t("shellToolConfig.headerValue")} + + {t("shellToolConfig.headerValue")} {t("optional")} + )} diff --git a/web/src/main.tsx b/web/src/main.tsx index 1cfa2676..6370b0af 100644 --- a/web/src/main.tsx +++ b/web/src/main.tsx @@ -3,10 +3,10 @@ import "./index.css"; import { TailwindIndicator } from "@/components/tailwind-indicator.tsx"; import { env } from "@/config.ts"; import { I18nextProvider } from "react-i18next"; -import i18n from "./i18n/i18n"; import { RouterProvider } from "react-router-dom"; -import { router } from "./router"; +import i18n from "./i18n/i18n"; import { QueryProvider } from "./providers/query-client-provider"; +import { router } from "./router"; const rootElement = document.getElementById("app") as HTMLElement; @@ -18,6 +18,6 @@ if (!rootElement.innerHTML) { {env.MODE !== "production" && } - + , ); } diff --git a/web/src/pages/index.tsx b/web/src/pages/index.tsx index 658e0614..c08009b0 100644 --- a/web/src/pages/index.tsx +++ b/web/src/pages/index.tsx @@ -7,7 +7,6 @@ import { env } from "@/config.ts"; import { FormSchema, formSchema } from "@/types/schema.ts"; import { APIErrorResponse, - ConfigResponseType, GenerateResponse, GenerateResult, MainConfig, @@ -17,14 +16,17 @@ import { } from "@/types/shell.ts"; import { customValidation, transformToPostData } from "@/utils/transformer.ts"; import { zodResolver } from "@hookform/resolvers/zod"; +import { useQuery } from "@tanstack/react-query"; import { LoaderCircle, WandSparklesIcon } from "lucide-react"; import { useState, useTransition } from "react"; import { useForm } from "react-hook-form"; import { useTranslation } from "react-i18next"; +import { useLoaderData } from "react-router-dom"; import { toast } from "sonner"; -import { useQuery } from "@tanstack/react-query"; export default function IndexPage() { + const urlParams = useLoaderData() as Partial; + const { data: serverConfig } = useQuery({ queryKey: ["serverConfig"], queryFn: async () => { @@ -53,23 +55,25 @@ export default function IndexPage() { const form = useForm({ resolver: zodResolver(formSchema), defaultValues: { - server: "Tomcat", - targetJdkVersion: "50", - debug: false, - bypassJavaModule: false, - shellClassName: "", - shellTool: "Godzilla", - shellType: "Listener", - urlPattern: "/*", - godzillaPass: "pass", - godzillaKey: "key", - commandParamName: "cmd", - behinderPass: "pass", - antSwordPass: "ant", - headerName: "User-Agent", - headerValue: "test", - injectorClassName: "", - packingMethod: "Base64", + server: urlParams.server ?? "Tomcat", + targetJdkVersion: urlParams.targetJdkVersion ?? "50", + debug: urlParams.debug ?? false, + bypassJavaModule: urlParams.bypassJavaModule ?? false, + shellClassName: urlParams.shellClassName ?? "", + shellTool: urlParams.shellTool ?? ShellToolType.Godzilla, + shellType: urlParams.shellType ?? "Listener", + urlPattern: urlParams.urlPattern ?? "/*", + godzillaPass: urlParams.godzillaPass ?? "", + godzillaKey: urlParams.godzillaKey ?? "", + commandParamName: urlParams.commandParamName ?? "", + behinderPass: urlParams.behinderPass ?? "", + antSwordPass: urlParams.antSwordPass ?? "", + headerName: urlParams.headerName ?? "User-Agent", + headerValue: urlParams.headerValue ?? "", + injectorClassName: urlParams.injectorClassName ?? "", + packingMethod: urlParams.packingMethod ?? "", + shrink: urlParams.shrink ?? false, + shellClassBase64: urlParams.shellClassBase64 ?? "", }, }); @@ -95,6 +99,7 @@ export default function IndexPage() { if (!response.ok) { const json: APIErrorResponse = await response.json(); toast.error(t("errors.generationFailed", { error: json.error })); + return; } const result = (await response.json()) as GenerateResponse; @@ -131,4 +136,4 @@ export default function IndexPage() { ); -} \ No newline at end of file +} diff --git a/web/src/providers/query-client-provider.tsx b/web/src/providers/query-client-provider.tsx index 390322e7..3441fdb5 100644 --- a/web/src/providers/query-client-provider.tsx +++ b/web/src/providers/query-client-provider.tsx @@ -10,6 +10,6 @@ const queryClient = new QueryClient({ }, }); -export function QueryProvider({ children }: { children: ReactNode }) { +export function QueryProvider({ children }: Readonly<{ children: ReactNode }>) { return {children}; -} \ No newline at end of file +} diff --git a/web/src/router.tsx b/web/src/router.tsx index a68f709f..8e7b9f1e 100644 --- a/web/src/router.tsx +++ b/web/src/router.tsx @@ -1,7 +1,44 @@ -import { createBrowserRouter } from "react-router-dom"; -import { env } from "@/config"; import RootLayout from "@/components/layouts/root-layout"; +import { env } from "@/config"; import IndexPage from "@/pages"; +import { FormSchema } from "@/types/schema"; +import { createBrowserRouter } from "react-router-dom"; + +// Function to parse URL parameters into form default values +const parseUrlParams = (searchParams: URLSearchParams): Partial => { + const result: Partial = {}; + + // Helper function to parse boolean values + const parseBoolean = (value: string | null): boolean | undefined => { + if (value === null) return undefined; + return value.toLowerCase() === "true"; + }; + + // Map URL parameters to form fields + if (searchParams.has("server")) result.server = searchParams.get("server") ?? undefined; + if (searchParams.has("targetJdkVersion")) result.targetJdkVersion = searchParams.get("targetJdkVersion") ?? undefined; + if (searchParams.has("debug")) result.debug = parseBoolean(searchParams.get("debug")); + if (searchParams.has("bypassJavaModule")) + result.bypassJavaModule = parseBoolean(searchParams.get("bypassJavaModule")); + if (searchParams.has("shellClassName")) result.shellClassName = searchParams.get("shellClassName") ?? undefined; + if (searchParams.has("shellTool")) result.shellTool = searchParams.get("shellTool") ?? undefined; + if (searchParams.has("shellType")) result.shellType = searchParams.get("shellType") ?? undefined; + if (searchParams.has("urlPattern")) result.urlPattern = searchParams.get("urlPattern") ?? undefined; + if (searchParams.has("godzillaPass")) result.godzillaPass = searchParams.get("godzillaPass") ?? undefined; + if (searchParams.has("godzillaKey")) result.godzillaKey = searchParams.get("godzillaKey") ?? undefined; + if (searchParams.has("behinderPass")) result.behinderPass = searchParams.get("behinderPass") ?? undefined; + if (searchParams.has("antSwordPass")) result.antSwordPass = searchParams.get("antSwordPass") ?? undefined; + if (searchParams.has("commandParamName")) result.commandParamName = searchParams.get("commandParamName") ?? undefined; + if (searchParams.has("headerName")) result.headerName = searchParams.get("headerName") ?? undefined; + if (searchParams.has("headerValue")) result.headerValue = searchParams.get("headerValue") ?? undefined; + if (searchParams.has("injectorClassName")) + result.injectorClassName = searchParams.get("injectorClassName") ?? undefined; + if (searchParams.has("packingMethod")) result.packingMethod = searchParams.get("packingMethod") ?? undefined; + if (searchParams.has("shrink")) result.shrink = parseBoolean(searchParams.get("shrink")); + if (searchParams.has("shellClassBase64")) result.shellClassBase64 = searchParams.get("shellClassBase64") ?? undefined; + + return result; +}; export const router = createBrowserRouter( [ @@ -12,11 +49,15 @@ export const router = createBrowserRouter( { index: true, element: , + loader: ({ request }) => { + const url = new URL(request.url); + return parseUrlParams(url.searchParams); + }, }, ], }, ], { basename: env.BASE_PATH, - } -); \ No newline at end of file + }, +); diff --git a/web/src/utils/transformer.ts b/web/src/utils/transformer.ts index cd57fc1c..1ae52dc5 100644 --- a/web/src/utils/transformer.ts +++ b/web/src/utils/transformer.ts @@ -56,3 +56,43 @@ export function transformToPostData(formValue: FormSchema) { packer: formValue.packingMethod, }; } + +/** + * Generates a URL with the current form values as query parameters + * @param values The form values + * @returns A URL string with query parameters + */ +export function generateShareableUrl(values: FormSchema): string { + const params = new URLSearchParams(); + + // Helper function to add parameters only if they have non-default values + const addParam = (key: string, value: any, defaultValue: any) => { + if (value !== defaultValue) { + params.append(key, String(value)); + } + }; + + // Add all form values to the URL parameters + addParam("server", values.server, "Tomcat"); + addParam("targetJdkVersion", values.targetJdkVersion, "50"); + addParam("debug", values.debug, false); + addParam("bypassJavaModule", values.bypassJavaModule, false); + addParam("shellClassName", values.shellClassName, ""); + addParam("shellTool", values.shellTool, "Godzilla"); + addParam("shellType", values.shellType, "Listener"); + addParam("urlPattern", values.urlPattern, "/*"); + addParam("godzillaPass", values.godzillaPass, "pass"); + addParam("godzillaKey", values.godzillaKey, "key"); + addParam("commandParamName", values.commandParamName, "cmd"); + addParam("behinderPass", values.behinderPass, "pass"); + addParam("antSwordPass", values.antSwordPass, "ant"); + addParam("headerName", values.headerName, "User-Agent"); + addParam("headerValue", values.headerValue, "test"); + addParam("injectorClassName", values.injectorClassName, ""); + addParam("packingMethod", values.packingMethod, "Base64"); + addParam("shrink", values.shrink, false); + addParam("shellClassBase64", values.shellClassBase64, ""); + + // Return the current URL with the query parameters + return `${window.location.origin}${window.location.pathname}?${params.toString()}`; +}