diff --git a/dd-java-agent/instrumentation/netty/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/NettyMultipartHelper.java b/dd-java-agent/instrumentation/netty/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/NettyMultipartHelper.java index b268216f2aa..3e1d7cca046 100644 --- a/dd-java-agent/instrumentation/netty/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/NettyMultipartHelper.java +++ b/dd-java-agent/instrumentation/netty/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/NettyMultipartHelper.java @@ -33,8 +33,15 @@ public static RuntimeException collectBodyData( List filesContent) { RuntimeException exc = null; for (InterfaceHttpData data : parts) { - if (attributes != null - && data.getHttpDataType() == InterfaceHttpData.HttpDataType.Attribute) { + InterfaceHttpData.HttpDataType dataType; + try { + dataType = data.getHttpDataType(); + } catch (UnsupportedOperationException ignored) { + // Some framework-specific implementations (e.g. Vert.x NettyFileUpload) do not support + // getHttpDataType() — skip them; their framework's own instrumentation handles them. + continue; + } + if (attributes != null && dataType == InterfaceHttpData.HttpDataType.Attribute) { String name = data.getName(); List values = attributes.get(name); if (values == null) { @@ -45,7 +52,7 @@ public static RuntimeException collectBodyData( } catch (IOException e) { exc = new UndeclaredThrowableException(e); } - } else if (data.getHttpDataType() == InterfaceHttpData.HttpDataType.FileUpload) { + } else if (dataType == InterfaceHttpData.HttpDataType.FileUpload) { FileUpload fileUpload = (FileUpload) data; String filename = fileUpload.getFilename(); if (filenames != null && filename != null && !filename.isEmpty()) { diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RoutingContextFilenamesAdvice.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RoutingContextFilenamesAdvice.java new file mode 100644 index 00000000000..4ab0bbec651 --- /dev/null +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RoutingContextFilenamesAdvice.java @@ -0,0 +1,72 @@ +package datadog.trace.instrumentation.vertx_3_4.server; + +import static datadog.trace.api.gateway.Events.EVENTS; + +import datadog.appsec.api.blocking.BlockingException; +import datadog.trace.advice.ActiveRequestContext; +import datadog.trace.advice.RequiresRequestContext; +import datadog.trace.api.gateway.BlockResponseFunction; +import datadog.trace.api.gateway.CallbackProvider; +import datadog.trace.api.gateway.Flow; +import datadog.trace.api.gateway.RequestContext; +import datadog.trace.api.gateway.RequestContextSlot; +import datadog.trace.bootstrap.CallDepthThreadLocalMap; +import datadog.trace.bootstrap.instrumentation.api.AgentTracer; +import io.vertx.ext.web.FileUpload; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.function.BiFunction; +import net.bytebuddy.asm.Advice; + +@RequiresRequestContext(RequestContextSlot.APPSEC) +class RoutingContextFilenamesAdvice { + + @Advice.OnMethodEnter(suppress = Throwable.class) + static int before() { + return CallDepthThreadLocalMap.incrementCallDepth(FileUpload.class); + } + + @Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class) + static void after( + @Advice.Enter int depth, + @Advice.Return Set uploads, + @ActiveRequestContext RequestContext reqCtx, + @Advice.Thrown(readOnly = false) Throwable throwable) { + CallDepthThreadLocalMap.decrementCallDepth(FileUpload.class); + if (depth != 0 || throwable != null || uploads == null || uploads.isEmpty()) { + return; + } + + List filenames = new ArrayList<>(uploads.size()); + for (FileUpload upload : uploads) { + String name = upload.fileName(); + if (name != null && !name.isEmpty()) { + filenames.add(name); + } + } + if (filenames.isEmpty()) { + return; + } + + CallbackProvider cbp = AgentTracer.get().getCallbackProvider(RequestContextSlot.APPSEC); + BiFunction, Flow> cb = + cbp.getCallback(EVENTS.requestFilesFilenames()); + if (cb == null) { + return; + } + + Flow flow = cb.apply(reqCtx, filenames); + Flow.Action action = flow.getAction(); + if (action instanceof Flow.Action.RequestBlockingAction) { + BlockResponseFunction brf = reqCtx.getBlockResponseFunction(); + if (brf != null) { + brf.tryCommitBlockingResponse( + reqCtx.getTraceSegment(), (Flow.Action.RequestBlockingAction) action); + if (throwable == null) { + throwable = new BlockingException("Blocked request (multipart file upload)"); + } + } + } + } +} diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RoutingContextImplInstrumentation.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RoutingContextImplInstrumentation.java index bc52bbfdbed..e13eef7f18e 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RoutingContextImplInstrumentation.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/main/java/datadog/trace/instrumentation/vertx_3_4/server/RoutingContextImplInstrumentation.java @@ -15,6 +15,11 @@ public class RoutingContextImplInstrumentation extends InstrumenterModule.AppSec implements Instrumenter.ForSingleType, Instrumenter.HasMethodAdvice { + private static final Reference FILE_UPLOAD_REF = + new Reference.Builder("io.vertx.ext.web.FileUpload") + .withMethod(new String[0], 0, "fileName", "Ljava/lang/String;") + .build(); + public RoutingContextImplInstrumentation() { super("vertx", "vertx-3.4"); } @@ -26,7 +31,7 @@ public String instrumentedType() { @Override public Reference[] additionalMuzzleReferences() { - return new Reference[] {PARSABLE_HEADER_VALUE, VIRTUAL_HOST_HANDLER}; + return new Reference[] {PARSABLE_HEADER_VALUE, VIRTUAL_HOST_HANDLER, FILE_UPLOAD_REF}; } @Override @@ -37,5 +42,8 @@ public void methodAdvice(MethodTransformer transformer) { transformer.applyAdvice( named("setSession").and(takesArgument(0, named("io.vertx.ext.web.Session"))), packageName + ".RoutingContextSessionAdvice"); + transformer.applyAdvice( + named("fileUploads").and(takesArguments(0)), + packageName + ".RoutingContextFilenamesAdvice"); } } diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/test/groovy/server/VertxHttpServerForkedTest.groovy b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/test/groovy/server/VertxHttpServerForkedTest.groovy index 4b585252db3..c64753affe7 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/test/groovy/server/VertxHttpServerForkedTest.groovy +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/test/groovy/server/VertxHttpServerForkedTest.groovy @@ -82,6 +82,11 @@ class VertxHttpServerForkedTest extends HttpServerTest { true } + @Override + boolean testBodyFilenames() { + true + } + @Override boolean testBodyJson() { true diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/test/java/server/VertxTestServer.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/test/java/server/VertxTestServer.java index 2d20d98a0ef..0110d1268da 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/test/java/server/VertxTestServer.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-3.4/src/test/java/server/VertxTestServer.java @@ -92,6 +92,7 @@ public void start(final Future startFuture) { String res = convertFormAttributes(ctx); ctx.response().setStatusCode(BODY_URLENCODED.getStatus()).end(res); })); + router.route(BODY_MULTIPART.getPath()).handler(BodyHandler.create()); router .route(BODY_MULTIPART.getPath()) .handler( @@ -100,13 +101,9 @@ public void start(final Future startFuture) { ctx, BODY_MULTIPART, () -> { - ctx.request().setExpectMultipart(true); - ctx.request() - .endHandler( - (_void) -> { - String res = convertFormAttributes(ctx); - ctx.response().setStatusCode(BODY_MULTIPART.getStatus()).end(res); - }); + ctx.fileUploads(); + String res = convertFormAttributes(ctx); + ctx.response().setStatusCode(BODY_MULTIPART.getStatus()).end(res); })); router.route(BODY_JSON.getPath()).handler(BodyHandler.create()); router diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/latestDepTest/groovy/server/VertxHttpServerForkedTest.groovy b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/latestDepTest/groovy/server/VertxHttpServerForkedTest.groovy index 2c09d35d353..8f276d08f23 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/latestDepTest/groovy/server/VertxHttpServerForkedTest.groovy +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/latestDepTest/groovy/server/VertxHttpServerForkedTest.groovy @@ -77,6 +77,11 @@ class VertxHttpServerForkedTest extends HttpServerTest { true } + @Override + boolean testBodyFilenames() { + true + } + @Override boolean testBodyJson() { true diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/latestDepTest/java/server/VertxTestServer.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/latestDepTest/java/server/VertxTestServer.java index f711678b3bd..8b20617cc7c 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/latestDepTest/java/server/VertxTestServer.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/latestDepTest/java/server/VertxTestServer.java @@ -92,6 +92,7 @@ public void start(final Promise startPromise) { String res = convertFormAttributes(ctx); ctx.response().setStatusCode(BODY_URLENCODED.getStatus()).end(res); })); + router.route(BODY_MULTIPART.getPath()).handler(BodyHandler.create()); router .route(BODY_MULTIPART.getPath()) .handler( @@ -100,13 +101,9 @@ public void start(final Promise startPromise) { ctx, BODY_MULTIPART, () -> { - ctx.request().setExpectMultipart(true); - ctx.request() - .endHandler( - (_void) -> { - String res = convertFormAttributes(ctx); - ctx.response().setStatusCode(BODY_MULTIPART.getStatus()).end(res); - }); + ctx.fileUploads(); + String res = convertFormAttributes(ctx); + ctx.response().setStatusCode(BODY_MULTIPART.getStatus()).end(res); })); router.route(BODY_JSON.getPath()).handler(BodyHandler.create()); router diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RoutingContextFilenamesAdvice.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RoutingContextFilenamesAdvice.java new file mode 100644 index 00000000000..e9ac149e7bb --- /dev/null +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RoutingContextFilenamesAdvice.java @@ -0,0 +1,72 @@ +package datadog.trace.instrumentation.vertx_4_0.server; + +import static datadog.trace.api.gateway.Events.EVENTS; + +import datadog.appsec.api.blocking.BlockingException; +import datadog.trace.advice.ActiveRequestContext; +import datadog.trace.advice.RequiresRequestContext; +import datadog.trace.api.gateway.BlockResponseFunction; +import datadog.trace.api.gateway.CallbackProvider; +import datadog.trace.api.gateway.Flow; +import datadog.trace.api.gateway.RequestContext; +import datadog.trace.api.gateway.RequestContextSlot; +import datadog.trace.bootstrap.CallDepthThreadLocalMap; +import datadog.trace.bootstrap.instrumentation.api.AgentTracer; +import io.vertx.ext.web.FileUpload; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.function.BiFunction; +import net.bytebuddy.asm.Advice; + +@RequiresRequestContext(RequestContextSlot.APPSEC) +class RoutingContextFilenamesAdvice { + + @Advice.OnMethodEnter(suppress = Throwable.class) + static int before() { + return CallDepthThreadLocalMap.incrementCallDepth(FileUpload.class); + } + + @Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class) + static void after( + @Advice.Enter int depth, + @Advice.Return Collection uploads, + @ActiveRequestContext RequestContext reqCtx, + @Advice.Thrown(readOnly = false) Throwable throwable) { + CallDepthThreadLocalMap.decrementCallDepth(FileUpload.class); + if (depth != 0 || throwable != null || uploads == null || uploads.isEmpty()) { + return; + } + + List filenames = new ArrayList<>(uploads.size()); + for (FileUpload upload : uploads) { + String name = upload.fileName(); + if (name != null && !name.isEmpty()) { + filenames.add(name); + } + } + if (filenames.isEmpty()) { + return; + } + + CallbackProvider cbp = AgentTracer.get().getCallbackProvider(RequestContextSlot.APPSEC); + BiFunction, Flow> cb = + cbp.getCallback(EVENTS.requestFilesFilenames()); + if (cb == null) { + return; + } + + Flow flow = cb.apply(reqCtx, filenames); + Flow.Action action = flow.getAction(); + if (action instanceof Flow.Action.RequestBlockingAction) { + BlockResponseFunction brf = reqCtx.getBlockResponseFunction(); + if (brf != null) { + brf.tryCommitBlockingResponse( + reqCtx.getTraceSegment(), (Flow.Action.RequestBlockingAction) action); + if (throwable == null) { + throwable = new BlockingException("Blocked request (multipart file upload)"); + } + } + } + } +} diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RoutingContextImplInstrumentation.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RoutingContextImplInstrumentation.java index 7a1e157e174..ae863b6ec09 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RoutingContextImplInstrumentation.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/main/java/datadog/trace/instrumentation/vertx_4_0/server/RoutingContextImplInstrumentation.java @@ -18,13 +18,18 @@ public class RoutingContextImplInstrumentation extends InstrumenterModule.AppSec implements Instrumenter.ForSingleType, Instrumenter.HasMethodAdvice { + private static final Reference FILE_UPLOAD_REF = + new Reference.Builder("io.vertx.ext.web.FileUpload") + .withMethod(new String[0], 0, "fileName", "Ljava/lang/String;") + .build(); + public RoutingContextImplInstrumentation() { super("vertx", "vertx-4.0"); } @Override public Reference[] additionalMuzzleReferences() { - return new Reference[] {VertxVersionMatcher.HTTP_1X_SERVER_RESPONSE}; + return new Reference[] {VertxVersionMatcher.HTTP_1X_SERVER_RESPONSE, FILE_UPLOAD_REF}; } @Override @@ -43,5 +48,8 @@ public void methodAdvice(MethodTransformer transformer) { transformer.applyAdvice( named("setSession").and(takesArgument(0, named("io.vertx.ext.web.Session"))), packageName + ".RoutingContextSessionAdvice"); + transformer.applyAdvice( + named("fileUploads").and(takesArguments(0)), + packageName + ".RoutingContextFilenamesAdvice"); } } diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/test/groovy/server/VertxHttpServerForkedTest.groovy b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/test/groovy/server/VertxHttpServerForkedTest.groovy index e18172999ff..1d2f4ec9971 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/test/groovy/server/VertxHttpServerForkedTest.groovy +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/test/groovy/server/VertxHttpServerForkedTest.groovy @@ -78,6 +78,11 @@ class VertxHttpServerForkedTest extends HttpServerTest { true } + @Override + boolean testBodyFilenames() { + true + } + @Override boolean testBodyJson() { true diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/test/java/server/VertxTestServer.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/test/java/server/VertxTestServer.java index d4dc482cb2a..5bb66696a9d 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/test/java/server/VertxTestServer.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-4.0/src/test/java/server/VertxTestServer.java @@ -101,6 +101,7 @@ public void start(final Promise startPromise) { String res = convertFormAttributes(ctx); ctx.response().setStatusCode(BODY_URLENCODED.getStatus()).end(res); })); + router.route(BODY_MULTIPART.getPath()).handler(BodyHandler.create()); router .route(BODY_MULTIPART.getPath()) .handler( @@ -109,13 +110,9 @@ public void start(final Promise startPromise) { ctx, BODY_MULTIPART, () -> { - ctx.request().setExpectMultipart(true); - ctx.request() - .endHandler( - (_void) -> { - String res = convertFormAttributes(ctx); - ctx.response().setStatusCode(BODY_MULTIPART.getStatus()).end(res); - }); + ctx.fileUploads(); + String res = convertFormAttributes(ctx); + ctx.response().setStatusCode(BODY_MULTIPART.getStatus()).end(res); })); router.route(BODY_JSON.getPath()).handler(BodyHandler.create()); router diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-5.0/src/main/java/datadog/trace/instrumentation/vertx_5_0/server/RoutingContextFilenamesAdvice.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-5.0/src/main/java/datadog/trace/instrumentation/vertx_5_0/server/RoutingContextFilenamesAdvice.java new file mode 100644 index 00000000000..cf4aa6482f6 --- /dev/null +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-5.0/src/main/java/datadog/trace/instrumentation/vertx_5_0/server/RoutingContextFilenamesAdvice.java @@ -0,0 +1,71 @@ +package datadog.trace.instrumentation.vertx_5_0.server; + +import static datadog.trace.api.gateway.Events.EVENTS; + +import datadog.appsec.api.blocking.BlockingException; +import datadog.trace.advice.ActiveRequestContext; +import datadog.trace.advice.RequiresRequestContext; +import datadog.trace.api.gateway.BlockResponseFunction; +import datadog.trace.api.gateway.CallbackProvider; +import datadog.trace.api.gateway.Flow; +import datadog.trace.api.gateway.RequestContext; +import datadog.trace.api.gateway.RequestContextSlot; +import datadog.trace.bootstrap.CallDepthThreadLocalMap; +import datadog.trace.bootstrap.instrumentation.api.AgentTracer; +import io.vertx.ext.web.FileUpload; +import java.util.ArrayList; +import java.util.List; +import java.util.function.BiFunction; +import net.bytebuddy.asm.Advice; + +@RequiresRequestContext(RequestContextSlot.APPSEC) +class RoutingContextFilenamesAdvice { + + @Advice.OnMethodEnter(suppress = Throwable.class) + static int before() { + return CallDepthThreadLocalMap.incrementCallDepth(FileUpload.class); + } + + @Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class) + static void after( + @Advice.Enter int depth, + @Advice.Return List uploads, + @ActiveRequestContext RequestContext reqCtx, + @Advice.Thrown(readOnly = false) Throwable throwable) { + CallDepthThreadLocalMap.decrementCallDepth(FileUpload.class); + if (depth != 0 || throwable != null || uploads == null || uploads.isEmpty()) { + return; + } + + List filenames = new ArrayList<>(uploads.size()); + for (FileUpload upload : uploads) { + String name = upload.fileName(); + if (name != null && !name.isEmpty()) { + filenames.add(name); + } + } + if (filenames.isEmpty()) { + return; + } + + CallbackProvider cbp = AgentTracer.get().getCallbackProvider(RequestContextSlot.APPSEC); + BiFunction, Flow> cb = + cbp.getCallback(EVENTS.requestFilesFilenames()); + if (cb == null) { + return; + } + + Flow flow = cb.apply(reqCtx, filenames); + Flow.Action action = flow.getAction(); + if (action instanceof Flow.Action.RequestBlockingAction) { + BlockResponseFunction brf = reqCtx.getBlockResponseFunction(); + if (brf != null) { + brf.tryCommitBlockingResponse( + reqCtx.getTraceSegment(), (Flow.Action.RequestBlockingAction) action); + if (throwable == null) { + throwable = new BlockingException("Blocked request (multipart file upload)"); + } + } + } + } +} diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-5.0/src/main/java/datadog/trace/instrumentation/vertx_5_0/server/RoutingContextImplInstrumentation.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-5.0/src/main/java/datadog/trace/instrumentation/vertx_5_0/server/RoutingContextImplInstrumentation.java new file mode 100644 index 00000000000..93ff71d4d82 --- /dev/null +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-5.0/src/main/java/datadog/trace/instrumentation/vertx_5_0/server/RoutingContextImplInstrumentation.java @@ -0,0 +1,40 @@ +package datadog.trace.instrumentation.vertx_5_0.server; + +import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.takesArguments; + +import com.google.auto.service.AutoService; +import datadog.trace.agent.tooling.Instrumenter; +import datadog.trace.agent.tooling.InstrumenterModule; +import datadog.trace.agent.tooling.muzzle.Reference; + +@AutoService(InstrumenterModule.class) +public class RoutingContextImplInstrumentation extends InstrumenterModule.AppSec + implements Instrumenter.ForSingleType, Instrumenter.HasMethodAdvice { + + private static final Reference FILE_UPLOAD_REF = + new Reference.Builder("io.vertx.ext.web.FileUpload") + .withMethod(new String[0], 0, "fileName", "Ljava/lang/String;") + .build(); + + public RoutingContextImplInstrumentation() { + super("vertx", "vertx-5.0"); + } + + @Override + public String instrumentedType() { + return "io.vertx.ext.web.impl.RoutingContextImpl"; + } + + @Override + public Reference[] additionalMuzzleReferences() { + return new Reference[] {VertxVersionMatcher.HTTP_HEADERS_INTERNAL, FILE_UPLOAD_REF}; + } + + @Override + public void methodAdvice(MethodTransformer transformer) { + transformer.applyAdvice( + named("fileUploads").and(takesArguments(0)), + packageName + ".RoutingContextFilenamesAdvice"); + } +} diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-5.0/src/test/groovy/server/VertxHttpServerForkedTest.groovy b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-5.0/src/test/groovy/server/VertxHttpServerForkedTest.groovy index 261430c0023..8a9372dd9e7 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-5.0/src/test/groovy/server/VertxHttpServerForkedTest.groovy +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-5.0/src/test/groovy/server/VertxHttpServerForkedTest.groovy @@ -82,6 +82,11 @@ class VertxHttpServerForkedTest extends HttpServerTest { true } + @Override + boolean testBodyFilenames() { + true + } + @Override boolean testBodyJson() { true diff --git a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-5.0/src/test/java/server/VertxTestServer.java b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-5.0/src/test/java/server/VertxTestServer.java index 17feffcc79f..24902867163 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-5.0/src/test/java/server/VertxTestServer.java +++ b/dd-java-agent/instrumentation/vertx/vertx-web/vertx-web-5.0/src/test/java/server/VertxTestServer.java @@ -92,6 +92,7 @@ public void start(final Promise startPromise) { String res = convertFormAttributes(ctx); ctx.response().setStatusCode(BODY_URLENCODED.getStatus()).end(res); })); + router.route(BODY_MULTIPART.getPath()).handler(BodyHandler.create()); router .route(BODY_MULTIPART.getPath()) .handler( @@ -100,13 +101,9 @@ public void start(final Promise startPromise) { ctx, BODY_MULTIPART, () -> { - ctx.request().setExpectMultipart(true); - ctx.request() - .endHandler( - (_void) -> { - String res = convertFormAttributes(ctx); - ctx.response().setStatusCode(BODY_MULTIPART.getStatus()).end(res); - }); + ctx.fileUploads(); + String res = convertFormAttributes(ctx); + ctx.response().setStatusCode(BODY_MULTIPART.getStatus()).end(res); })); router.route(BODY_JSON.getPath()).handler(BodyHandler.create()); router