Skip to content

Commit a4f6a9a

Browse files
authored
Merge branch 'master' into mhlidd/httpserverdecorator_cleanup
2 parents cc9beea + a90ccbc commit a4f6a9a

File tree

63 files changed

+1371
-276
lines changed

Some content is hidden

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

63 files changed

+1371
-276
lines changed

.gitlab-ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ variables:
2525
BUILD_JOB_NAME: "build"
2626
DEPENDENCY_CACHE_POLICY: pull
2727
BUILD_CACHE_POLICY: pull
28-
GRADLE_VERSION: "8.5" # must match gradle-wrapper.properties
28+
GRADLE_VERSION: "8.14.3" # must match gradle-wrapper.properties
2929
MAVEN_REPOSITORY_PROXY: "http://artifactual.artifactual.all-clusters.local-dc.fabric.dog:8081/repository/maven-central/"
3030
GRADLE_PLUGIN_PROXY: "http://artifactual.artifactual.all-clusters.local-dc.fabric.dog:8081/repository/gradle-plugin-portal-proxy/"
3131
BUILDER_IMAGE_VERSION_PREFIX: "v25.06-" # use either an empty string (e.g. "") for latest images or a version followed by a hyphen (e.g. "v25.05-")

.gitlab/upload_ciapp.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,20 @@ junit_upload() {
3535
./results
3636
}
3737

38+
# Upload code coverage results to Datadog
39+
coverage_upload() {
40+
DD_API_KEY=$1 \
41+
[email protected]:DataDog/dd-trace-java.git \
42+
datadog-ci coverage upload --ignored-paths=./test-published-dependencies .
43+
}
44+
3845
# Upload test results to production environment like all other CI jobs
3946
junit_upload "$DATADOG_API_KEY_PROD"
47+
junit_upload_status=$?
48+
49+
coverage_upload "$DATADOG_API_KEY_PROD"
50+
coverage_upload_status=$?
51+
52+
if [[ $junit_upload_status -ne 0 || $coverage_upload_status -ne 0 ]]; then
53+
exit 1
54+
fi

buildSrc/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ dependencies {
4646
implementation("org.ow2.asm", "asm", "9.8")
4747
implementation("org.ow2.asm", "asm-tree", "9.8")
4848

49-
testImplementation("org.spockframework", "spock-core", "2.2-groovy-3.0")
49+
testImplementation("org.spockframework", "spock-core", "2.3-groovy-3.0")
5050
testImplementation("org.codehaus.groovy", "groovy-all", "3.0.17")
5151
}
5252

buildSrc/call-site-instrumentation-plugin/build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ dependencies {
3737
implementation("com.github.javaparser", "javaparser-symbol-solver-core", "3.24.4")
3838

3939
testImplementation("net.bytebuddy", "byte-buddy", "1.17.5")
40-
testImplementation("org.spockframework", "spock-core", "2.0-groovy-3.0")
40+
testImplementation("org.spockframework", "spock-core", "2.3-groovy-3.0")
4141
testImplementation("org.objenesis", "objenesis", "3.0.1")
4242
testImplementation("org.codehaus.groovy", "groovy-all", "3.0.17")
4343
testImplementation("javax.servlet", "javax.servlet-api", "3.0.1")
@@ -68,7 +68,7 @@ val copyCallSiteSources = tasks.register<Copy>("copyCallSiteSources") {
6868
}
6969

7070
tasks {
71-
withType<AbstractCompile>() {
71+
withType<AbstractCompile> {
7272
dependsOn(copyCallSiteSources)
7373
}
7474
}

communication/src/main/java/datadog/communication/ddagent/SharedCommunicationObjects.java

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public class SharedCommunicationObjects {
3030
public OkHttpClient okHttpClient;
3131
public HttpUrl agentUrl;
3232
public Monitoring monitoring;
33-
private DDAgentFeaturesDiscovery featuresDiscovery;
33+
private volatile DDAgentFeaturesDiscovery featuresDiscovery;
3434
private ConfigurationPoller configurationPoller;
3535

3636
public SharedCommunicationObjects() {
@@ -139,28 +139,34 @@ public void setFeaturesDiscovery(DDAgentFeaturesDiscovery featuresDiscovery) {
139139
}
140140

141141
public DDAgentFeaturesDiscovery featuresDiscovery(Config config) {
142-
if (featuresDiscovery == null) {
143-
createRemaining(config);
144-
featuresDiscovery =
145-
new DDAgentFeaturesDiscovery(
146-
okHttpClient,
147-
monitoring,
148-
agentUrl,
149-
config.isTraceAgentV05Enabled(),
150-
config.isTracerMetricsEnabled());
151-
152-
if (paused) {
153-
// defer remote discovery until remote I/O is allowed
154-
} else {
155-
if (AGENT_THREAD_GROUP.equals(Thread.currentThread().getThreadGroup())) {
156-
featuresDiscovery.discover(); // safe to run on same thread
157-
} else {
158-
// avoid performing blocking I/O operation on application thread
159-
AgentTaskScheduler.INSTANCE.execute(featuresDiscovery::discover);
142+
DDAgentFeaturesDiscovery ret = featuresDiscovery;
143+
if (ret == null) {
144+
synchronized (this) {
145+
if (featuresDiscovery == null) {
146+
createRemaining(config);
147+
ret =
148+
new DDAgentFeaturesDiscovery(
149+
okHttpClient,
150+
monitoring,
151+
agentUrl,
152+
config.isTraceAgentV05Enabled(),
153+
config.isTracerMetricsEnabled());
154+
155+
if (paused) {
156+
// defer remote discovery until remote I/O is allowed
157+
} else {
158+
if (AGENT_THREAD_GROUP.equals(Thread.currentThread().getThreadGroup())) {
159+
ret.discover(); // safe to run on same thread
160+
} else {
161+
// avoid performing blocking I/O operation on application thread
162+
AgentTaskScheduler.INSTANCE.execute(ret::discover);
163+
}
164+
}
165+
featuresDiscovery = ret;
160166
}
161167
}
162168
}
163-
return featuresDiscovery;
169+
return ret;
164170
}
165171

166172
private static final class FixedConfigUrlSupplier implements Supplier<String> {
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.datadog.iast;
2+
3+
import datadog.trace.api.gateway.RequestContext;
4+
import datadog.trace.api.gateway.RequestContextSlot;
5+
import java.util.function.BiConsumer;
6+
7+
public class HttpRouteHandler implements BiConsumer<RequestContext, String> {
8+
9+
@Override
10+
public void accept(final RequestContext ctx, final String route) {
11+
final IastRequestContext iastCtx = ctx.getData(RequestContextSlot.IAST);
12+
if (iastCtx != null) {
13+
iastCtx.setRoute(route);
14+
}
15+
}
16+
}

dd-java-agent/agent-iast/src/main/java/com/datadog/iast/IastRequestContext.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public class IastRequestContext implements IastContext, HasMetricCollector {
3636
@Nullable private volatile String xForwardedProto;
3737
@Nullable private volatile String contentType;
3838
@Nullable private volatile String authorization;
39+
@Nullable private volatile String route;
3940

4041
/**
4142
* Use {@link IastRequestContext#IastRequestContext(TaintedObjects)} instead as we require more
@@ -121,6 +122,15 @@ public void setAuthorization(final String authorization) {
121122
this.authorization = authorization;
122123
}
123124

125+
@Nullable
126+
public String getRoute() {
127+
return route;
128+
}
129+
130+
public void setRoute(final String route) {
131+
this.route = route;
132+
}
133+
124134
public OverheadContext getOverheadContext() {
125135
return overheadContext;
126136
}

dd-java-agent/agent-iast/src/main/java/com/datadog/iast/IastSystem.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ public static void start(
122122
registerRequestStartedCallback(ss, addTelemetry, dependencies);
123123
registerRequestEndedCallback(ss, addTelemetry, dependencies);
124124
registerHeadersCallback(ss);
125+
registerHttpRouteCallback(ss);
125126
registerGrpcServerRequestMessageCallback(ss);
126127
maybeApplySecurityControls(instrumentation);
127128
LOGGER.debug("IAST started");
@@ -246,6 +247,10 @@ private static void registerHeadersCallback(final SubscriptionService ss) {
246247
ss.registerCallback(event, handler);
247248
}
248249

250+
private static void registerHttpRouteCallback(final SubscriptionService ss) {
251+
ss.registerCallback(Events.get().httpRoute(), new HttpRouteHandler());
252+
}
253+
249254
private static void registerGrpcServerRequestMessageCallback(final SubscriptionService ss) {
250255
ss.registerCallback(Events.get().grpcServerRequestMessage(), new GrpcRequestMessageHandler());
251256
}

dd-java-agent/agent-iast/src/main/java/com/datadog/iast/overhead/OverheadController.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ public boolean consumeQuota(
233233
Object methodTag = rootSpan.getTag(Tags.HTTP_METHOD);
234234
method = (methodTag == null) ? "" : methodTag.toString();
235235
Object routeTag = rootSpan.getTag(Tags.HTTP_ROUTE);
236-
path = (routeTag == null) ? "" : routeTag.toString();
236+
path = (routeTag == null) ? getHttpRouteFromRequestContext(span) : routeTag.toString();
237237
}
238238
if (!maybeSkipVulnerability(ctx, type, method, path)) {
239239
return operation.consumeQuota(ctx);
@@ -316,6 +316,19 @@ public OverheadContext getContext(@Nullable final AgentSpan span) {
316316
return globalContext;
317317
}
318318

319+
@Nullable
320+
public String getHttpRouteFromRequestContext(@Nullable final AgentSpan span) {
321+
String httpRoute = null;
322+
final RequestContext requestContext = span != null ? span.getRequestContext() : null;
323+
if (requestContext != null) {
324+
IastRequestContext iastRequestContext = requestContext.getData(RequestContextSlot.IAST);
325+
if (iastRequestContext != null) {
326+
httpRoute = iastRequestContext.getRoute();
327+
}
328+
}
329+
return httpRoute == null ? "" : httpRoute;
330+
}
331+
319332
static int computeSamplingParameter(final float pct) {
320333
if (pct >= 100) {
321334
return 100;
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.datadog.iast
2+
3+
import datadog.trace.api.gateway.RequestContext
4+
import datadog.trace.api.gateway.RequestContextSlot
5+
import datadog.trace.test.util.DDSpecification
6+
import groovy.transform.CompileDynamic
7+
8+
@CompileDynamic
9+
class HttpRouteHandlerTest extends DDSpecification {
10+
void 'route is set'() {
11+
given:
12+
final handler = new HttpRouteHandler()
13+
final iastCtx = Mock(IastRequestContext)
14+
final ctx = Mock(RequestContext)
15+
ctx.getData(RequestContextSlot.IAST) >> iastCtx
16+
17+
when:
18+
handler.accept(ctx, '/foo')
19+
20+
then:
21+
1 * ctx.getData(RequestContextSlot.IAST) >> iastCtx
22+
1 * iastCtx.setRoute('/foo')
23+
0 * _
24+
}
25+
26+
void 'does nothing when context missing'() {
27+
given:
28+
final handler = new HttpRouteHandler()
29+
final ctx = Mock(RequestContext)
30+
ctx.getData(RequestContextSlot.IAST) >> null
31+
32+
when:
33+
handler.accept(ctx, '/foo')
34+
35+
then:
36+
1 * ctx.getData(RequestContextSlot.IAST) >> null
37+
0 * _
38+
}
39+
}

0 commit comments

Comments
 (0)