Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ abstract class AkkaHttpServerInstrumentationTest extends HttpServerTest<AkkaHttp
true
}

@Override
boolean testBodyFilenames() {
true
}

@Override
boolean testBodyJson() {
true
Expand Down Expand Up @@ -223,6 +228,11 @@ abstract class AkkaHttpServerInstrumentationSyncTest extends AkkaHttpServerInstr
false
}

@Override
boolean testBodyFilenames() {
false
}

@Override
boolean testBodyJson() {
false
Expand Down Expand Up @@ -283,6 +293,11 @@ class AkkaHttpServerInstrumentationBindAndHandleTest extends AkkaHttpServerInstr
akkaHttpVersion != '10.0.10'
}

@Override
boolean testBodyFilenames() {
akkaHttpVersion != '10.0.10'
}

@Override
boolean testBodyUrlencoded() {
akkaHttpVersion != '10.0.10'
Expand All @@ -309,6 +324,11 @@ class AkkaHttpServerInstrumentationBindAndHandleAsyncWithRouteAsyncHandlerTest e
akkaHttpVersion != '10.0.10'
}

@Override
boolean testBodyFilenames() {
akkaHttpVersion != '10.0.10'
}

@Override
boolean testBodyUrlencoded() {
akkaHttpVersion != '10.0.10'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ class AkkaHttp102ServerInstrumentationBindSyncTest extends AkkaHttpServerInstrum
false
}

@Override
boolean testBodyFilenames() {
false
}

@Override
boolean testBodyJson() {
false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.WeakHashMap;
import java.util.function.BiFunction;
import org.slf4j.Logger;
Expand Down Expand Up @@ -199,17 +200,24 @@ private static void handleMultipartStrictFormData(
}

CallbackProvider cbp = AgentTracer.get().getCallbackProvider(RequestContextSlot.APPSEC);
BiFunction<RequestContext, Object, Flow<Void>> callback =
BiFunction<RequestContext, Object, Flow<Void>> bodyCallback =
cbp.getCallback(EVENTS.requestBodyProcessed());
if (callback == null) {
BiFunction<RequestContext, List<String>, Flow<Void>> filenamesCallback =
cbp.getCallback(EVENTS.requestFilesFilenames());
if (bodyCallback == null && filenamesCallback == null) {
return;
}

// conversion to map string -> list of string
java.lang.Iterable<akka.http.javadsl.model.Multipart.FormData.BodyPart.Strict> strictParts =
st.getStrictParts();
Map<String, List<String>> conv = new HashMap<>();
List<String> filenames = new ArrayList<>();
for (akka.http.javadsl.model.Multipart.FormData.BodyPart.Strict part : strictParts) {
Optional<String> filenameOpt = part.getFilename();
if (filenameOpt.isPresent() && !filenameOpt.get().isEmpty()) {
filenames.add(filenameOpt.get());
}

akka.http.javadsl.model.HttpEntity.Strict entity = part.getEntity();
if (!(entity instanceof HttpEntity.Strict)) {
continue;
Expand All @@ -232,8 +240,27 @@ private static void handleMultipartStrictFormData(
curStrings.add(s);
}

// callback execution
executeCallback(reqCtx, callback, conv, "multipartFormDataUnmarshaller");
if (bodyCallback != null) {
executeCallback(reqCtx, bodyCallback, conv, "multipartFormDataUnmarshaller");
}

if (filenamesCallback != null && !filenames.isEmpty()) {
Flow<Void> filenamesFlow = filenamesCallback.apply(reqCtx, filenames);
Flow.Action filenamesAction = filenamesFlow.getAction();
if (filenamesAction instanceof Flow.Action.RequestBlockingAction) {
Flow.Action.RequestBlockingAction rba = (Flow.Action.RequestBlockingAction) filenamesAction;
BlockResponseFunction brf = reqCtx.getBlockResponseFunction();
if (brf != null) {
boolean success = brf.tryCommitBlockingResponse(reqCtx.getTraceSegment(), rba);
if (success) {
if (brf instanceof AkkaBlockResponseFunction) {
((AkkaBlockResponseFunction) brf).setUnmarshallBlock(true);
}
throw new BlockingException("Blocked request (multipart file upload)");
}
}
}
}
}

public static Unmarshaller<HttpEntity, String> transformStringUnmarshaller(
Expand Down Expand Up @@ -389,6 +416,7 @@ public static Unmarshaller<HttpEntity, StrictForm> transformStrictFormUnmarshall
private static void handleStrictFormData(StrictForm sf) {
Iterator<Tuple2<String, StrictForm.Field>> iterator = sf.fields().iterator();
Map<String, List<String>> conv = new HashMap<>();
List<String> filenames = new ArrayList<>();
while (iterator.hasNext()) {
Tuple2<String, StrictForm.Field> next = iterator.next();
String fieldName = next._1();
Expand All @@ -413,9 +441,13 @@ private static void handleStrictFormData(StrictForm sf) {
strings.add((String) strictFieldValue);
} else if (strictFieldValue
instanceof akka.http.scaladsl.model.Multipart$FormData$BodyPart$Strict) {
HttpEntity.Strict sentity =
((akka.http.scaladsl.model.Multipart$FormData$BodyPart$Strict) strictFieldValue)
.entity();
akka.http.scaladsl.model.Multipart$FormData$BodyPart$Strict bodyPart =
(akka.http.scaladsl.model.Multipart$FormData$BodyPart$Strict) strictFieldValue;
Optional<String> filenameOpt = bodyPart.getFilename();
if (filenameOpt.isPresent() && !filenameOpt.get().isEmpty()) {
filenames.add(filenameOpt.get());
}
HttpEntity.Strict sentity = bodyPart.entity();
String s =
sentity
.getData()
Expand All @@ -426,6 +458,36 @@ private static void handleStrictFormData(StrictForm sf) {
}

handleArbitraryPostData(conv, "HttpEntity -> StrictForm unmarshaller");

if (!filenames.isEmpty()) {
AgentSpan span = activeSpan();
RequestContext reqCtx;
if (span != null
&& (reqCtx = span.getRequestContext()) != null
&& reqCtx.getData(RequestContextSlot.APPSEC) != null) {
CallbackProvider cbp = AgentTracer.get().getCallbackProvider(RequestContextSlot.APPSEC);
BiFunction<RequestContext, List<String>, Flow<Void>> filenamesCb =
cbp.getCallback(EVENTS.requestFilesFilenames());
if (filenamesCb != null) {
Flow<Void> filenamesFlow = filenamesCb.apply(reqCtx, filenames);
Flow.Action filenamesAction = filenamesFlow.getAction();
if (filenamesAction instanceof Flow.Action.RequestBlockingAction) {
Flow.Action.RequestBlockingAction rba =
(Flow.Action.RequestBlockingAction) filenamesAction;
BlockResponseFunction brf = reqCtx.getBlockResponseFunction();
if (brf != null) {
boolean success = brf.tryCommitBlockingResponse(reqCtx.getTraceSegment(), rba);
if (success) {
if (brf instanceof AkkaBlockResponseFunction) {
((AkkaBlockResponseFunction) brf).setUnmarshallBlock(true);
}
throw new BlockingException("Blocked request (multipart file upload)");
}
}
}
}
}
}
}

private static Object tryConvertingScalaContainers(Object obj, int depth) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ class AkkaHttp102ServerInstrumentationBindSyncTest extends AkkaHttpServerInstrum
false
}

@Override
boolean testBodyFilenames() {
false
}

@Override
boolean testBodyJson() {
false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ abstract class AkkaHttpServerInstrumentationTest extends HttpServerTest<AkkaHttp
true
}

@Override
boolean testBodyFilenames() {
true
}

@Override
boolean testBodyJson() {
true
Expand Down Expand Up @@ -223,6 +228,11 @@ abstract class AkkaHttpServerInstrumentationSyncTest extends AkkaHttpServerInstr
false
}

@Override
boolean testBodyFilenames() {
false
}

@Override
boolean testBodyJson() {
false
Expand Down Expand Up @@ -279,6 +289,11 @@ class AkkaHttpServerInstrumentationBindAndHandleTest extends AkkaHttpServerInstr
true
}

@Override
boolean testBodyFilenames() {
true
}

@Override
boolean testBodyUrlencoded() {
true
Expand All @@ -305,6 +320,11 @@ class AkkaHttpServerInstrumentationBindAndHandleAsyncWithRouteAsyncHandlerTest e
true
}

@Override
boolean testBodyFilenames() {
true
}

@Override
boolean testBodyUrlencoded() {
true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ class GrizzlyTest extends HttpServerTest<HttpServer> {
true
}

@Override
boolean testBodyFilenames() {
true
}

@Override
boolean testBodyJson() {
true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ class Jersey3JettyTest extends HttpServerTest<JettyServer> {
true
}

@Override
boolean testBodyFilenames() {
true
}

@Override
boolean testBodyJson() {
true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import javax.ws.rs.core.MediaType;
import net.bytebuddy.asm.Advice;
import org.glassfish.jersey.media.multipart.BodyPart;
import org.glassfish.jersey.media.multipart.ContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataBodyPart;
import org.glassfish.jersey.media.multipart.MultiPart;
import org.glassfish.jersey.message.internal.MediaTypes;
Expand Down Expand Up @@ -70,18 +71,26 @@ static void after(
}

CallbackProvider cbp = AgentTracer.get().getCallbackProvider(RequestContextSlot.APPSEC);
BiFunction<RequestContext, Object, Flow<Void>> callback =
BiFunction<RequestContext, Object, Flow<Void>> bodyCallback =
cbp.getCallback(EVENTS.requestBodyProcessed());
if (callback == null) {
BiFunction<RequestContext, List<String>, Flow<Void>> filenamesCb =
cbp.getCallback(EVENTS.requestFilesFilenames());
if (bodyCallback == null && filenamesCb == null) {
return;
}

Map<String, List<String>> map = new HashMap<>();
List<String> filenames = new ArrayList<>();
for (BodyPart bodyPart : ret.getBodyParts()) {
if (!(bodyPart instanceof FormDataBodyPart)) {
continue;
}
FormDataBodyPart dataBodyPart = (FormDataBodyPart) bodyPart;
ContentDisposition cd = dataBodyPart.getContentDisposition();
String filename = cd != null ? cd.getFileName() : null;
if (filename != null && !filename.isEmpty()) {
filenames.add(filename);
}
if (!MediaTypes.typeEqual(MediaType.TEXT_PLAIN_TYPE, dataBodyPart.getMediaType())) {
continue;
}
Expand All @@ -99,14 +108,31 @@ static void after(
values.add(v);
}

Flow<Void> flow = callback.apply(reqCtx, map);
Flow.Action action = flow.getAction();
if (action instanceof Flow.Action.RequestBlockingAction) {
Flow.Action.RequestBlockingAction rba = (Flow.Action.RequestBlockingAction) action;
BlockResponseFunction blockResponseFunction = reqCtx.getBlockResponseFunction();
if (blockResponseFunction != null) {
blockResponseFunction.tryCommitBlockingResponse(reqCtx.getTraceSegment(), rba);
t = new BlockingException("Blocked request (for MultiPartReaderClientSide/readFrom)");
if (bodyCallback != null) {
Flow<Void> flow = bodyCallback.apply(reqCtx, map);
Flow.Action action = flow.getAction();
if (action instanceof Flow.Action.RequestBlockingAction) {
Flow.Action.RequestBlockingAction rba = (Flow.Action.RequestBlockingAction) action;
BlockResponseFunction blockResponseFunction = reqCtx.getBlockResponseFunction();
if (blockResponseFunction != null) {
blockResponseFunction.tryCommitBlockingResponse(reqCtx.getTraceSegment(), rba);
t = new BlockingException("Blocked request (for MultiPartReaderClientSide/readFrom)");
reqCtx.getTraceSegment().effectivelyBlocked();
}
}
}

if (filenamesCb != null && !filenames.isEmpty()) {
Flow<Void> filenamesFlow = filenamesCb.apply(reqCtx, filenames);
Flow.Action filenamesAction = filenamesFlow.getAction();
if (t == null && filenamesAction instanceof Flow.Action.RequestBlockingAction) {
Flow.Action.RequestBlockingAction rba =
(Flow.Action.RequestBlockingAction) filenamesAction;
BlockResponseFunction brf = reqCtx.getBlockResponseFunction();
if (brf != null) {
brf.tryCommitBlockingResponse(reqCtx.getTraceSegment(), rba);
}
t = new BlockingException("Blocked request (multipart file upload)");
reqCtx.getTraceSegment().effectivelyBlocked();
}
}
Expand Down
Loading
Loading