Skip to content

Commit 9b7597b

Browse files
vandonrsarahchen6AlexeyKuznetsov-DD
authored
Fix for undertow versions > 2.2.40, 2.3.25 and 2.4.0 (#11844)
bump undertow lockfile instrument new parser class for undertow adapt test setup to parser used Merge branch 'master' into vandonr/fix2 Merge branch 'master' into vandonr/fix2 Co-authored-by: sarahchen6 <sarah.chen@datadoghq.com> Co-authored-by: alexey.kuznetsov <alexey.kuznetsov@datadoghq.com>
1 parent 8db2dc8 commit 9b7597b

5 files changed

Lines changed: 98 additions & 35 deletions

File tree

dd-java-agent/instrumentation/undertow/undertow-2.0/gradle.lockfile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,11 @@ de.thetaphi:forbiddenapis:3.10=compileClasspath,latestDepForkedTestCompileClassp
5353
io.leangen.geantyref:geantyref:1.3.16=latestDepForkedTestRuntimeClasspath,latestDepTestRuntimeClasspath,testRuntimeClasspath
5454
io.sqreen:libsqreen:17.4.0=latestDepForkedTestRuntimeClasspath,latestDepTestRuntimeClasspath,testRuntimeClasspath
5555
io.undertow:undertow-core:2.0.0.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath
56-
io.undertow:undertow-core:2.2.39.Final=latestDepForkedTestCompileClasspath,latestDepForkedTestRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
56+
io.undertow:undertow-core:2.2.40.Final=latestDepForkedTestCompileClasspath,latestDepForkedTestRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
5757
io.undertow:undertow-servlet:2.0.0.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath
58-
io.undertow:undertow-servlet:2.2.39.Final=latestDepForkedTestCompileClasspath,latestDepForkedTestRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
58+
io.undertow:undertow-servlet:2.2.40.Final=latestDepForkedTestCompileClasspath,latestDepForkedTestRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
5959
io.undertow:undertow-websockets-jsr:2.0.0.Final=testCompileClasspath,testRuntimeClasspath
60-
io.undertow:undertow-websockets-jsr:2.2.39.Final=latestDepForkedTestCompileClasspath,latestDepForkedTestRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
60+
io.undertow:undertow-websockets-jsr:2.2.40.Final=latestDepForkedTestCompileClasspath,latestDepForkedTestRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
6161
javax.servlet:javax.servlet-api:3.1.0=latestDepForkedTestCompileClasspath,latestDepForkedTestRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
6262
jaxen:jaxen:2.0.0=spotbugs
6363
junit:junit:4.13.2=latestDepForkedTestRuntimeClasspath,latestDepTestRuntimeClasspath,testRuntimeClasspath

dd-java-agent/instrumentation/undertow/undertow-2.0/src/main/java/datadog/trace/instrumentation/undertow/HttpRequestParserInstrumentation.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ public HttpRequestParserInstrumentation() {
2828

2929
@Override
3030
public String hierarchyMarkerType() {
31+
// removed in https://github.com/undertow-io/undertow/pull/1949/changes
32+
// see RequestParserInstrumentation for the new type
3133
return "io.undertow.server.protocol.http.HttpRequestParser";
3234
}
3335

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package datadog.trace.instrumentation.undertow;
2+
3+
import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named;
4+
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
5+
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
6+
7+
import com.google.auto.service.AutoService;
8+
import datadog.trace.agent.tooling.Instrumenter;
9+
import datadog.trace.agent.tooling.InstrumenterModule;
10+
11+
@AutoService(InstrumenterModule.class)
12+
public class RequestParserInstrumentation extends InstrumenterModule.Tracing
13+
implements Instrumenter.ForSingleType, Instrumenter.HasMethodAdvice {
14+
public RequestParserInstrumentation() {
15+
super("undertow", "undertow-2.2", "undertow-request-parse");
16+
}
17+
18+
@Override
19+
public String instrumentedType() {
20+
// new class added in new minor versions in
21+
// https://github.com/undertow-io/undertow/pull/1949/changes
22+
// from 2.2.40, 2.3.25 and 2.4.0
23+
// not instrumenting the hierarchy like in its predecessor HttpRequestParserInstrumentation
24+
// because RequestParser is marked final.
25+
return "io.undertow.server.protocol.http.RequestParser";
26+
}
27+
28+
@Override
29+
public void methodAdvice(MethodTransformer transformer) {
30+
transformer.applyAdvice(
31+
isMethod()
32+
.and(named("handle"))
33+
.and(takesArgument(2, named("io.undertow.server.HttpServerExchange"))),
34+
HttpRequestParserInstrumentation.class.getName() + "$RequestParseFailureAdvice");
35+
}
36+
37+
@Override
38+
public String[] helperClassNames() {
39+
return new String[] {
40+
packageName + ".HttpServerExchangeURIDataAdapter",
41+
packageName + ".UndertowDecorator",
42+
packageName + ".UndertowBlockingHandler",
43+
packageName + ".IgnoreSendAttribute",
44+
packageName + ".UndertowBlockResponseFunction",
45+
packageName + ".UndertowExtractAdapter",
46+
packageName + ".UndertowExtractAdapter$Request",
47+
packageName + ".UndertowExtractAdapter$Response"
48+
};
49+
}
50+
}

dd-java-agent/instrumentation/undertow/undertow-2.0/src/test/groovy/UndertowServletAsyncTest.groovy

Lines changed: 40 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,24 @@
1+
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.BODY_MULTIPART
2+
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.BODY_URLENCODED
3+
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.CREATED
4+
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.CREATED_IS
5+
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.ERROR
6+
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.EXCEPTION
7+
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.FORWARDED
8+
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.LOGIN
9+
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.NOT_FOUND
10+
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.NOT_HERE
11+
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.PATH_PARAM
12+
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.QUERY_ENCODED_BOTH
13+
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.QUERY_ENCODED_QUERY
14+
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.QUERY_PARAM
15+
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.REDIRECT
16+
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.SUCCESS
17+
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.TIMEOUT
18+
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.TIMEOUT_ERROR
19+
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.USER_BLOCK
20+
import static datadog.trace.agent.test.base.HttpServerTest.controller
21+
122
import datadog.trace.agent.test.asserts.TraceAssert
223
import datadog.trace.agent.test.base.HttpServer
324
import datadog.trace.agent.test.base.HttpServerTest
@@ -14,8 +35,8 @@ import io.undertow.servlet.api.InstanceHandle
1435
import io.undertow.servlet.api.ServletContainer
1536
import io.undertow.servlet.api.ServletInfo
1637
import io.undertow.servlet.util.ImmediateInstanceHandle
17-
import org.slf4j.LoggerFactory
18-
38+
import java.nio.charset.StandardCharsets
39+
import java.util.concurrent.atomic.AtomicReference
1940
import javax.servlet.AsyncContext
2041
import javax.servlet.AsyncEvent
2142
import javax.servlet.AsyncListener
@@ -26,29 +47,7 @@ import javax.servlet.WriteListener
2647
import javax.servlet.http.HttpServlet
2748
import javax.servlet.http.HttpServletRequest
2849
import javax.servlet.http.HttpServletResponse
29-
import java.nio.charset.StandardCharsets
30-
import java.util.concurrent.atomic.AtomicReference
31-
32-
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.BODY_MULTIPART
33-
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.BODY_URLENCODED
34-
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.CREATED
35-
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.CREATED_IS
36-
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.ERROR
37-
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.EXCEPTION
38-
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.FORWARDED
39-
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.LOGIN
40-
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.NOT_FOUND
41-
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.NOT_HERE
42-
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.PATH_PARAM
43-
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.QUERY_ENCODED_BOTH
44-
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.QUERY_ENCODED_QUERY
45-
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.QUERY_PARAM
46-
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.REDIRECT
47-
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.SUCCESS
48-
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.TIMEOUT
49-
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.TIMEOUT_ERROR
50-
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.USER_BLOCK
51-
import static datadog.trace.agent.test.base.HttpServerTest.controller
50+
import org.slf4j.LoggerFactory
5251

5352
class UndertowServletAsyncTest extends HttpServerTest<Undertow> {
5453
private static final CONTEXT = "ctx"
@@ -119,9 +118,10 @@ class UndertowServletAsyncTest extends HttpServerTest<Undertow> {
119118
dispatch = false
120119
req.setAttribute('ddog.dispatched', 1)
121120
if (req.servletPath.contains(' ')) {
122-
// bug in undertow when dispatching from /foo%20bar
123-
// (matches mapping "/foo bar" 1st and "/foo%20bar" after dispatch)
124-
asyncContext.dispatch(req.servletPath)
121+
// Older versions match the decoded servlet path on redispatch,
122+
// while the newer RequestParser expects the raw encoded path;
123+
// using the other form either misses the servlet mapping or hangs.
124+
asyncContext.dispatch(hasNewRequestParser() ? ep.rawPath : req.servletPath)
125125
} else {
126126
asyncContext.dispatch()
127127
}
@@ -260,6 +260,16 @@ class UndertowServletAsyncTest extends HttpServerTest<Undertow> {
260260
operation()
261261
}
262262

263+
private static boolean hasNewRequestParser() {
264+
// returns true for versions that include the bugfix pushed in https://github.com/undertow-io/undertow/pull/1949
265+
try {
266+
Class.forName('io.undertow.server.protocol.http.RequestParser')
267+
return true
268+
} catch (ClassNotFoundException ignored) {
269+
return false
270+
}
271+
}
272+
263273
@Override
264274
boolean testTimeout() {
265275
true
@@ -408,7 +418,8 @@ class UndertowServletAsyncTest extends HttpServerTest<Undertow> {
408418
trace.span {
409419
serviceName expectedServiceName()
410420
operationName 'servlet.dispatch'
411-
String resName = endpoint.path == endpoint.rawPath ? 'servlet.dispatch' : endpoint.path
421+
String resName =
422+
endpoint.path == endpoint.rawPath ? 'servlet.dispatch' : hasNewRequestParser() ? endpoint.rawPath : endpoint.path
412423
resourceName resName
413424
errored(endpoint.throwsException || endpoint == TIMEOUT_ERROR)
414425
childOfPrevious()

dd-java-agent/instrumentation/undertow/undertow-2.2/gradle.lockfile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,13 @@ io.smallrye.common:smallrye-common-ref:2.4.0=latestDepForkedTestRuntimeClasspath
6262
io.sqreen:libsqreen:17.4.0=latest22ForkedTestRuntimeClasspath,latest22TestRuntimeClasspath,latestDepForkedTestRuntimeClasspath,latestDepTestRuntimeClasspath,testRuntimeClasspath
6363
io.undertow:undertow-core:2.2.14.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath
6464
io.undertow:undertow-core:2.2.20.Final=latest22ForkedTestCompileClasspath,latest22ForkedTestRuntimeClasspath,latest22TestCompileClasspath,latest22TestRuntimeClasspath
65-
io.undertow:undertow-core:2.3.24.Final=latestDepForkedTestCompileClasspath,latestDepForkedTestRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
65+
io.undertow:undertow-core:2.3.25.Final=latestDepForkedTestCompileClasspath,latestDepForkedTestRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
6666
io.undertow:undertow-servlet-jakarta:2.2.14.Final=compileClasspath,latestDepForkedTestCompileClasspath,latestDepForkedTestRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
6767
io.undertow:undertow-servlet-jakarta:2.2.20.Final=latest22ForkedTestCompileClasspath,latest22ForkedTestRuntimeClasspath,latest22TestCompileClasspath,latest22TestRuntimeClasspath
68-
io.undertow:undertow-servlet:2.3.24.Final=latestDepForkedTestCompileClasspath,latestDepForkedTestRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
68+
io.undertow:undertow-servlet:2.3.25.Final=latestDepForkedTestCompileClasspath,latestDepForkedTestRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
6969
io.undertow:undertow-websockets-jsr-jakarta:2.2.14.Final=latestDepForkedTestCompileClasspath,latestDepForkedTestRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
7070
io.undertow:undertow-websockets-jsr-jakarta:2.2.20.Final=latest22ForkedTestCompileClasspath,latest22ForkedTestRuntimeClasspath,latest22TestCompileClasspath,latest22TestRuntimeClasspath
71-
io.undertow:undertow-websockets-jsr:2.3.24.Final=latestDepForkedTestCompileClasspath,latestDepForkedTestRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
71+
io.undertow:undertow-websockets-jsr:2.3.25.Final=latestDepForkedTestCompileClasspath,latestDepForkedTestRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
7272
jakarta.annotation:jakarta.annotation-api:2.0.0=compileClasspath,latest22ForkedTestCompileClasspath,latest22ForkedTestRuntimeClasspath,latest22TestCompileClasspath,latest22TestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
7373
jakarta.annotation:jakarta.annotation-api:2.1.1=latestDepForkedTestCompileClasspath,latestDepForkedTestRuntimeClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
7474
jakarta.servlet:jakarta.servlet-api:5.0.0=compileClasspath,latest22ForkedTestCompileClasspath,latest22ForkedTestRuntimeClasspath,latest22TestCompileClasspath,latest22TestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath

0 commit comments

Comments
 (0)