Skip to content

Commit 417db44

Browse files
committed
Merge remote-tracking branch 'origin/master' into bdu/pr-gate
2 parents 460c5e4 + cb3d992 commit 417db44

File tree

50 files changed

+856
-206
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+856
-206
lines changed

dd-java-agent/instrumentation/jax-ws-annotations-1/src/main/java/datadog/trace/instrumentation/jaxws1/WebServiceInstrumentation.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,6 @@ public WebServiceInstrumentation() {
3636
super("jax-ws");
3737
}
3838

39-
@Override
40-
protected boolean defaultEnabled() {
41-
return false;
42-
}
43-
4439
@Override
4540
public String hierarchyMarkerType() {
4641
return null; // bootstrap type

dd-java-agent/instrumentation/jax-ws-annotations-2/src/main/java/datadog/trace/instrumentation/jaxws2/WebServiceProviderInstrumentation.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,6 @@ public WebServiceProviderInstrumentation() {
3434
super("jax-ws");
3535
}
3636

37-
@Override
38-
protected boolean defaultEnabled() {
39-
return false;
40-
}
41-
4237
@Override
4338
public String hierarchyMarkerType() {
4439
return null; // bootstrap type
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package datadog.trace.instrumentation.play25.appsec;
2+
3+
import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named;
4+
5+
import com.google.auto.service.AutoService;
6+
import datadog.trace.agent.tooling.Instrumenter;
7+
import datadog.trace.agent.tooling.InstrumenterModule;
8+
import datadog.trace.agent.tooling.muzzle.Reference;
9+
10+
@AutoService(InstrumenterModule.class)
11+
public class ResultsStatusInstrumentation extends InstrumenterModule.AppSec
12+
implements Instrumenter.ForSingleType, Instrumenter.HasMethodAdvice {
13+
14+
public ResultsStatusInstrumentation() {
15+
super("play");
16+
}
17+
18+
@Override
19+
public String muzzleDirective() {
20+
return "play25only";
21+
}
22+
23+
@Override
24+
public Reference[] additionalMuzzleReferences() {
25+
return MuzzleReferences.PLAY_25_ONLY;
26+
}
27+
28+
@Override
29+
public String instrumentedType() {
30+
return "play.api.mvc.Results$Status";
31+
}
32+
33+
@Override
34+
public String[] helperClassNames() {
35+
return new String[] {
36+
packageName + ".BodyParserHelpers",
37+
};
38+
}
39+
40+
@Override
41+
public void methodAdvice(MethodTransformer transformer) {
42+
transformer.applyAdvice(named("apply"), packageName + ".ResultsStatusApplyAdvice");
43+
}
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package datadog.trace.instrumentation.play25.appsec;
2+
3+
import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named;
4+
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
5+
6+
import com.google.auto.service.AutoService;
7+
import datadog.trace.agent.tooling.Instrumenter;
8+
import datadog.trace.agent.tooling.InstrumenterModule;
9+
import datadog.trace.agent.tooling.muzzle.Reference;
10+
11+
@AutoService(InstrumenterModule.class)
12+
public class StatusHeaderInstrumentation extends InstrumenterModule.AppSec
13+
implements Instrumenter.ForSingleType, Instrumenter.HasMethodAdvice {
14+
15+
public StatusHeaderInstrumentation() {
16+
super("play");
17+
}
18+
19+
@Override
20+
public String muzzleDirective() {
21+
return "play25only";
22+
}
23+
24+
@Override
25+
public Reference[] additionalMuzzleReferences() {
26+
return MuzzleReferences.PLAY_25_ONLY;
27+
}
28+
29+
@Override
30+
public String instrumentedType() {
31+
return "play.mvc.StatusHeader";
32+
}
33+
34+
@Override
35+
public void methodAdvice(MethodTransformer transformer) {
36+
transformer.applyAdvice(
37+
named("sendJson").and(takesArgument(0, named("com.fasterxml.jackson.databind.JsonNode"))),
38+
packageName + ".StatusHeaderSendJsonAdvice");
39+
}
40+
}

dd-java-agent/instrumentation/play-2.4/src/main/java_play25/datadog/trace/instrumentation/play25/appsec/BodyParserHelpers.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import scala.collection.Iterator;
4040
import scala.collection.Seq;
4141
import scala.compat.java8.JFunction1;
42+
import scala.math.BigDecimal;
4243

4344
public class BodyParserHelpers {
4445

@@ -231,15 +232,20 @@ private static void handleException(Exception e, String logMessage) {
231232
log.warn(logMessage, e);
232233
}
233234

234-
private static Object jsValueToJavaObject(JsValue value, int maxRecursion) {
235+
public static Object jsValueToJavaObject(JsValue value) {
236+
return jsValueToJavaObject(value, MAX_RECURSION);
237+
}
238+
239+
public static Object jsValueToJavaObject(JsValue value, int maxRecursion) {
235240
if (value == null || maxRecursion <= 0) {
236241
return null;
237242
}
238243

239244
if (value instanceof JsString) {
240245
return ((JsString) value).value();
241246
} else if (value instanceof JsNumber) {
242-
return ((JsNumber) value).value();
247+
final BigDecimal number = ((JsNumber) value).value();
248+
return number == null ? null : number.bigDecimal();
243249
} else if (value instanceof JsBoolean) {
244250
return ((JsBoolean) value).value();
245251
} else if (value instanceof JsObject) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package datadog.trace.instrumentation.play25.appsec;
2+
3+
import static datadog.trace.api.gateway.Events.EVENTS;
4+
import static datadog.trace.instrumentation.play25.appsec.BodyParserHelpers.jsValueToJavaObject;
5+
6+
import datadog.appsec.api.blocking.BlockingException;
7+
import datadog.trace.advice.ActiveRequestContext;
8+
import datadog.trace.advice.RequiresRequestContext;
9+
import datadog.trace.api.gateway.BlockResponseFunction;
10+
import datadog.trace.api.gateway.CallbackProvider;
11+
import datadog.trace.api.gateway.Flow;
12+
import datadog.trace.api.gateway.RequestContext;
13+
import datadog.trace.api.gateway.RequestContextSlot;
14+
import datadog.trace.bootstrap.instrumentation.api.AgentTracer;
15+
import java.util.function.BiFunction;
16+
import net.bytebuddy.asm.Advice;
17+
import play.api.libs.json.JsValue;
18+
19+
@RequiresRequestContext(RequestContextSlot.APPSEC)
20+
public class ResultsStatusApplyAdvice {
21+
22+
@Advice.OnMethodEnter(suppress = Throwable.class)
23+
static void after(
24+
@Advice.Argument(0) final Object content, @ActiveRequestContext RequestContext reqCtx) {
25+
26+
if (!(content instanceof JsValue)) {
27+
return;
28+
}
29+
30+
CallbackProvider cbp = AgentTracer.get().getCallbackProvider(RequestContextSlot.APPSEC);
31+
if (cbp == null) {
32+
return;
33+
}
34+
BiFunction<RequestContext, Object, Flow<Void>> callback =
35+
cbp.getCallback(EVENTS.responseBody());
36+
if (callback == null) {
37+
return;
38+
}
39+
40+
Flow<Void> flow = callback.apply(reqCtx, jsValueToJavaObject((JsValue) content));
41+
Flow.Action action = flow.getAction();
42+
if (action instanceof Flow.Action.RequestBlockingAction) {
43+
BlockResponseFunction blockResponseFunction = reqCtx.getBlockResponseFunction();
44+
if (blockResponseFunction == null) {
45+
return;
46+
}
47+
Flow.Action.RequestBlockingAction rba = (Flow.Action.RequestBlockingAction) action;
48+
blockResponseFunction.tryCommitBlockingResponse(
49+
reqCtx.getTraceSegment(),
50+
rba.getStatusCode(),
51+
rba.getBlockingContentType(),
52+
rba.getExtraHeaders());
53+
54+
throw new BlockingException("Blocked request (for Results$Status/apply)");
55+
}
56+
}
57+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package datadog.trace.instrumentation.play25.appsec;
2+
3+
import static datadog.trace.api.gateway.Events.EVENTS;
4+
5+
import com.fasterxml.jackson.databind.JsonNode;
6+
import datadog.appsec.api.blocking.BlockingException;
7+
import datadog.trace.advice.ActiveRequestContext;
8+
import datadog.trace.advice.RequiresRequestContext;
9+
import datadog.trace.api.gateway.BlockResponseFunction;
10+
import datadog.trace.api.gateway.CallbackProvider;
11+
import datadog.trace.api.gateway.Flow;
12+
import datadog.trace.api.gateway.RequestContext;
13+
import datadog.trace.api.gateway.RequestContextSlot;
14+
import datadog.trace.bootstrap.CallDepthThreadLocalMap;
15+
import datadog.trace.bootstrap.instrumentation.api.AgentTracer;
16+
import java.util.function.BiFunction;
17+
import net.bytebuddy.asm.Advice;
18+
import play.mvc.StatusHeader;
19+
20+
@RequiresRequestContext(RequestContextSlot.APPSEC)
21+
public class StatusHeaderSendJsonAdvice {
22+
23+
@Advice.OnMethodEnter(suppress = Throwable.class)
24+
static void before() {
25+
CallDepthThreadLocalMap.incrementCallDepth(StatusHeader.class);
26+
}
27+
28+
@Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class)
29+
static void after(
30+
@Advice.Argument(0) final JsonNode json, @ActiveRequestContext RequestContext reqCtx) {
31+
final int depth = CallDepthThreadLocalMap.decrementCallDepth(StatusHeader.class);
32+
if (depth > 0) {
33+
return;
34+
}
35+
36+
if (json == null) {
37+
return;
38+
}
39+
40+
CallbackProvider cbp = AgentTracer.get().getCallbackProvider(RequestContextSlot.APPSEC);
41+
if (cbp == null) {
42+
return;
43+
}
44+
BiFunction<RequestContext, Object, Flow<Void>> callback =
45+
cbp.getCallback(EVENTS.responseBody());
46+
if (callback == null) {
47+
return;
48+
}
49+
50+
Flow<Void> flow = callback.apply(reqCtx, json);
51+
Flow.Action action = flow.getAction();
52+
if (action instanceof Flow.Action.RequestBlockingAction) {
53+
BlockResponseFunction blockResponseFunction = reqCtx.getBlockResponseFunction();
54+
if (blockResponseFunction == null) {
55+
return;
56+
}
57+
Flow.Action.RequestBlockingAction rba = (Flow.Action.RequestBlockingAction) action;
58+
blockResponseFunction.tryCommitBlockingResponse(
59+
reqCtx.getTraceSegment(),
60+
rba.getStatusCode(),
61+
rba.getBlockingContentType(),
62+
rba.getExtraHeaders());
63+
64+
throw new BlockingException("Blocked request (for StatusHeader/sendJson)");
65+
}
66+
}
67+
}

dd-java-agent/instrumentation/play-2.4/src/test/groovy/datadog/trace/instrumentation/play25/server/PlayRouters.groovy

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package datadog.trace.instrumentation.play25.server
22

33
import com.fasterxml.jackson.databind.JsonNode
4-
import com.fasterxml.jackson.databind.ObjectMapper
54
import datadog.appsec.api.blocking.Blocking
65
import datadog.trace.agent.test.base.HttpServerTest
76
import groovy.transform.CompileStatic
@@ -130,7 +129,7 @@ class PlayRouters {
130129
->
131130
JsonNode json = body().asJson()
132131
controller(BODY_JSON) {
133-
Results.status(BODY_JSON.status, new ObjectMapper().writeValueAsString(json))
132+
Results.status(BODY_JSON.status, json)
134133
}
135134
} as Supplier)
136135
.build()
@@ -253,7 +252,7 @@ class PlayRouters {
253252
CompletableFuture.supplyAsync({
254253
->
255254
controller(BODY_JSON) {
256-
Results.status(BODY_JSON.status, new ObjectMapper().writeValueAsString(json))
255+
Results.status(BODY_JSON.status, json)
257256
}
258257
}, execContext)
259258
} as Supplier)

dd-java-agent/instrumentation/play-2.4/src/test/groovy/datadog/trace/instrumentation/play25/server/PlayServerTest.groovy

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,11 @@ class PlayServerTest extends HttpServerTest<Server> {
9393
true
9494
}
9595

96+
@Override
97+
boolean testResponseBodyJson() {
98+
true
99+
}
100+
96101
@Override
97102
String testPathParam() {
98103
'/path/?/param'

dd-java-agent/instrumentation/play-2.4/src/test/scala/datadog/trace/instrumentation/play25/PlayController.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class PlayController(implicit ec: ExecutionContext) extends Controller {
7777

7878
def bodyJson = controller(ServerEndpoint.BODY_JSON) { request =>
7979
val body: JsValue = request.body.asJson.getOrElse(JsNull)
80-
Results.Ok(Json.stringify(body))
80+
Results.Ok(body)
8181
}
8282

8383
private def controller(endpoint: ServerEndpoint)(block: Request[AnyContent] => Result) : Action[AnyContent] = {

dd-java-agent/instrumentation/play-2.4/src/test/scala/datadog/trace/instrumentation/play25/PlayRoutersScala.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ object PlayRoutersScala {
143143
case POST(p"/body-json") => Action.async(parser) { request =>
144144
controller(BODY_JSON) {
145145
val body: JsValue = request.body.asJson.getOrElse(JsNull)
146-
Results.Ok(Json.stringify(body))
146+
Results.Ok(body)
147147
}
148148
}
149149
}

dd-java-agent/instrumentation/play-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayRouters.groovy

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package datadog.trace.instrumentation.play26.server
22

3+
import com.fasterxml.jackson.databind.ObjectMapper
34
import datadog.appsec.api.blocking.Blocking
45
import datadog.trace.agent.test.base.HttpServerTest
56
import groovy.transform.CompileStatic
67
import play.BuiltInComponents
78
import play.api.libs.json.JsValue
8-
import play.api.libs.json.Json$
99
import play.api.mvc.AnyContent
1010
import play.libs.concurrent.HttpExecution
1111
import play.mvc.Http
@@ -150,7 +150,7 @@ class PlayRouters {
150150
->
151151
controller(BODY_JSON) {
152152
JsValue json = body().asJson().get()
153-
Results.status(BODY_JSON.status, Json$.MODULE$.stringify(json))
153+
Results.status(BODY_JSON.status, new ObjectMapper().readTree(json.toString()))
154154
}
155155
} as Supplier)
156156
.POST(BODY_XML.path).routeTo({
@@ -286,7 +286,7 @@ class PlayRouters {
286286
CompletableFuture.supplyAsync({
287287
->
288288
controller(BODY_JSON) {
289-
Results.status(BODY_JSON.status, Json$.MODULE$.stringify(json))
289+
Results.status(BODY_JSON.status, new ObjectMapper().readTree(json.toString()))
290290
}
291291
}, execContext)
292292
} as Supplier)

dd-java-agent/instrumentation/play-2.6/src/baseTest/groovy/datadog/trace/instrumentation/play26/server/PlayServerTest.groovy

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,11 @@ class PlayServerTest extends HttpServerTest<Server> {
9696
true
9797
}
9898

99+
@Override
100+
boolean testResponseBodyJson() {
101+
true
102+
}
103+
99104
@Override
100105
String testPathParam() {
101106
'/path/?/param'

dd-java-agent/instrumentation/play-2.6/src/latestDepTest/groovy/datadog/trace/instrumentation/play26/server/latestdep/PlayRouters.groovy

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package datadog.trace.instrumentation.play26.server.latestdep
22

33
import com.fasterxml.jackson.databind.JsonNode
4-
import com.fasterxml.jackson.databind.ObjectMapper
54
import datadog.appsec.api.blocking.Blocking
65
import datadog.trace.agent.test.base.HttpServerTest
76
import datadog.trace.instrumentation.play26.server.TestHttpErrorHandler
@@ -121,7 +120,7 @@ class PlayRouters {
121120
.POST(BODY_JSON.path).routingTo({ Http.Request req ->
122121
controller(BODY_JSON) {
123122
JsonNode json = req.body().asJson()
124-
Results.status(BODY_JSON.status, new ObjectMapper().writeValueAsString(json))
123+
Results.status(BODY_JSON.status, json)
125124
}
126125
} as RequestFunctions.Params0<Result>)
127126
.POST(BODY_XML.path).routingTo({ Http.Request req ->
@@ -254,7 +253,7 @@ class PlayRouters {
254253
CompletableFuture.supplyAsync({
255254
->
256255
controller(BODY_JSON) {
257-
Results.status(BODY_JSON.status, new ObjectMapper().writeValueAsString(json))
256+
Results.status(BODY_JSON.status, json)
258257
}
259258
}, execContext)
260259
} as RequestFunctions.Params0<? extends CompletionStage<Result>>)

0 commit comments

Comments
 (0)