Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ public abstract class HttpClientDecorator<REQUEST, RESPONSE> extends UriBasedCli
* not be traced to avoid self-tracing loops.
*/
public boolean isAgentRequest(final REQUEST request) {
// Advice runs before the instrumented method's own argument validation, so a caller
// passing a null request must not NPE here — let the real method report that itself.
if (request == null) {
return false;
}
return getRequestHeader(request, DATADOG_META_LANG_HEADER_NAME) != null
|| getRequestHeader(request, DD_CLIENT_LIBRARY_LANGUAGE_HEADER_NAME) != null;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package datadog.trace.bootstrap.instrumentation.decorator;

import static org.junit.jupiter.api.Assertions.assertFalse;

import java.net.URI;
import java.net.URISyntaxException;
import org.junit.jupiter.api.Test;

class HttpClientDecoratorIsAgentRequestTest {

// Regression test: advice runs before the instrumented method's own argument validation, so a
// caller passing a null request (e.g. HttpClient.sendAsync(null, ...)) must not NPE inside
// isAgentRequest -> getRequestHeader. See
// datadog.trace.instrumentation.httpclient.SendAsyncAdvice.
@Test
void isAgentRequestOfNullRequestReturnsFalseInsteadOfThrowing() {
HttpClientDecorator<Object, Object> decorator =
new HttpClientDecorator<Object, Object>() {
@Override
protected String[] instrumentationNames() {
return new String[] {"test"};
}

@Override
protected CharSequence component() {
return "test-component";
}

@Override
protected String method(Object request) {
return null;
}

@Override
protected URI url(Object request) throws URISyntaxException {
return null;
}

@Override
protected int status(Object response) {
return 0;
}

@Override
protected String getRequestHeader(Object request, String headerName) {
throw new NullPointerException("should not be reached for a null request");
}

@Override
protected String getResponseHeader(Object response, String headerName) {
return null;
}
};

assertFalse(decorator.isAgentRequest(null));
}
}