Skip to content

Commit c5268dd

Browse files
committed
Fix GetFilenamesAdvice double-fire for Jetty 9.4+ where _multiParts replaces _contentParameters as the getParts() cache
In Jetty 9.3, getParts(MultiMap) sets _contentParameters, so the map==null guard prevents re-firing on repeated getParts() calls. In Jetty 9.4+, getParts() delegates to getParts(null) and caches the result in _multiParts instead, leaving _contentParameters null on every call. Add _multiParts==null as an additional guard (optional=true handles Jetty 9.3 where the field does not exist).
1 parent 0040e75 commit c5268dd

1 file changed

Lines changed: 11 additions & 2 deletions

File tree

dd-java-agent/instrumentation/jetty/jetty-appsec/jetty-appsec-9.3/src/main/java/datadog/trace/instrumentation/jetty93/RequestExtractContentParametersInstrumentation.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.util.List;
2525
import java.util.function.BiFunction;
2626
import net.bytebuddy.asm.Advice;
27+
import net.bytebuddy.implementation.bytecode.assign.Assigner;
2728
import org.eclipse.jetty.server.Request;
2829
import org.eclipse.jetty.util.MultiMap;
2930

@@ -117,9 +118,17 @@ static void after(
117118
@RequiresRequestContext(RequestContextSlot.APPSEC)
118119
public static class GetFilenamesAdvice {
119120
@Advice.OnMethodEnter(suppress = Throwable.class)
120-
static boolean before(@Advice.FieldValue("_contentParameters") final MultiMap<String> map) {
121+
static boolean before(
122+
@Advice.FieldValue("_contentParameters") final MultiMap<String> contentParameters,
123+
@Advice.FieldValue(value = "_multiParts", optional = true, typing = Assigner.Typing.DYNAMIC)
124+
final Object multiParts) {
121125
final int callDepth = CallDepthThreadLocalMap.incrementCallDepth(Collection.class);
122-
return callDepth == 0 && map == null;
126+
// contentParameters is set by extractContentParameters() (called from getParameterMap()),
127+
// so it being non-null means the request was already processed via that path.
128+
// multiParts is set by getParts(MultiMap) (Jetty 9.4+) after the first getParts() call,
129+
// so it being non-null means getParts() was already invoked and filenames were reported.
130+
// In Jetty 9.3, _multiParts does not exist (optional=true → null).
131+
return callDepth == 0 && contentParameters == null && multiParts == null;
123132
}
124133

125134
@Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class)

0 commit comments

Comments
 (0)