Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
161655c
Stop AppSecInterceptor from silently retrying failed okhttp requests
dougqh Aug 19, 2026
efad531
Add JUnit5 regression test for AppSecInterceptor silent-retry fix
dougqh Aug 21, 2026
acf135f
Merge branch 'master' into dougqh/fix-appsec-interceptor-duplicate-re…
dougqh Aug 21, 2026
bfe37e7
Merge branch 'master' into dougqh/fix-appsec-interceptor-duplicate-re…
dougqh Sep 2, 2026
d8304f7
Merge branch 'master' into dougqh/fix-appsec-interceptor-duplicate-re…
dougqh Sep 2, 2026
5dc6c88
Guard against NPE reading HTTP_URL tag in AppSecInterceptor
dougqh Sep 2, 2026
04ae7fb
Preserve captured response body when AppSec response hook fails
dougqh Sep 3, 2026
b09c0d4
Merge branch 'master' into dougqh/fix-appsec-interceptor-duplicate-re…
dougqh Sep 4, 2026
8f3eb74
Merge branch 'master' into dougqh/fix-appsec-interceptor-duplicate-re…
dougqh Sep 8, 2026
c6a82cc
Merge branch 'master' into dougqh/fix-appsec-interceptor-duplicate-re…
dougqh Sep 9, 2026
4a66271
Merge branch 'dougqh/fix-appsec-interceptor-duplicate-request' into d…
dougqh Sep 10, 2026
bdd6ed3
Merge remote-tracking branch 'origin/master' into dougqh/fix-appsec-i…
dougqh Sep 10, 2026
47b65d5
Merge remote-tracking branch 'origin/dougqh/fix-appsec-interceptor-re…
dougqh Sep 10, 2026
8afd18c
Preserve rebuilt response body when the AppSec response hook fails
dougqh Sep 11, 2026
37614a5
Merge remote-tracking branch 'origin/dougqh/fix-appsec-interceptor-du…
dougqh Sep 11, 2026
7188831
Merge remote-tracking branch 'origin/dougqh/fix-appsec-interceptor-du…
dougqh Sep 11, 2026
78bfffc
Merge remote-tracking branch 'origin/master' into dougqh/fix-appsec-i…
dougqh Sep 29, 2026
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
@@ -1,5 +1,7 @@
package datadog.trace.instrumentation.okhttp2;

import static datadog.trace.api.gateway.Events.EVENTS;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
Expand All @@ -9,8 +11,13 @@
import static org.mockito.Mockito.when;

import com.squareup.okhttp.Interceptor;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.Protocol;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import com.squareup.okhttp.ResponseBody;
import datadog.trace.api.gateway.CallbackProvider;
import datadog.trace.api.gateway.Flow;
import datadog.trace.api.gateway.RequestContext;
import datadog.trace.api.gateway.RequestContextSlot;
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
Expand Down Expand Up @@ -65,4 +72,32 @@ void ioExceptionFromProceedPropagatesWithoutRetry() throws IOException {
assertSame(failure, thrown);
verify(chain, times(1)).proceed(request);
}

@Test
void responseHookFailureAfterBodyCapturePreservesCapturedBody() throws IOException {
final String json = "{\"hello\":\"world\"}";
final Response response =
new Response.Builder()
.request(request)
.protocol(Protocol.HTTP_1_1)
.code(200)
.message("OK")
.body(ResponseBody.create(MediaType.parse("application/json"), json))
.build();
when(chain.proceed(request)).thenReturn(response);

final CallbackProvider cbp = mock(CallbackProvider.class);
when(cbp.getCallback(EVENTS.httpClientSampling()))
.thenReturn((ctx, requestId) -> new Flow.ResultFlow<>(Boolean.TRUE));
when(cbp.getCallback(EVENTS.httpClientResponse()))
.thenReturn(
(ctx, clientResponse) -> {
throw new RuntimeException("boom");
});
when(AgentTracer.get().getCallbackProvider(any(RequestContextSlot.class))).thenReturn(cbp);

final Response result = interceptor.intercept(chain);

assertEquals(json, result.body().string());
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package datadog.trace.instrumentation.okhttp3;

import static datadog.trace.api.gateway.Events.EVENTS;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
Expand All @@ -9,14 +11,19 @@
import static org.mockito.Mockito.when;

import datadog.trace.api.gateway.CallbackProvider;
import datadog.trace.api.gateway.Flow;
import datadog.trace.api.gateway.RequestContext;
import datadog.trace.api.gateway.RequestContextSlot;
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
import datadog.trace.bootstrap.instrumentation.api.AgentTracer;
import datadog.trace.bootstrap.instrumentation.api.Tags;
import java.io.IOException;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Protocol;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -65,4 +72,32 @@ void ioExceptionFromProceedPropagatesWithoutRetry() throws IOException {
assertSame(failure, thrown);
verify(chain, times(1)).proceed(request);
}

@Test
void responseHookFailureAfterBodyCapturePreservesCapturedBody() throws IOException {
final String json = "{\"hello\":\"world\"}";
final Response response =
new Response.Builder()
.request(request)
.protocol(Protocol.HTTP_1_1)
.code(200)
.message("OK")
.body(ResponseBody.create(MediaType.parse("application/json"), json))
.build();
when(chain.proceed(request)).thenReturn(response);

final CallbackProvider cbp = mock(CallbackProvider.class);
when(cbp.getCallback(EVENTS.httpClientSampling()))
.thenReturn((ctx, requestId) -> new Flow.ResultFlow<>(Boolean.TRUE));
when(cbp.getCallback(EVENTS.httpClientResponse()))
.thenReturn(
(ctx, clientResponse) -> {
throw new RuntimeException("boom");
});
when(AgentTracer.get().getCallbackProvider(any(RequestContextSlot.class))).thenReturn(cbp);

final Response result = interceptor.intercept(chain);

assertEquals(json, result.body().string());
}
}
Loading