Skip to content

Commit 5057539

Browse files
committed
fix(ffe): handle nullable agentless response bodies
1 parent 0f02a2a commit 5057539

3 files changed

Lines changed: 43 additions & 10 deletions

File tree

dd-trace-api/src/main/java/datadog/trace/api/ConfigDefaults.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,13 @@ public final class ConfigDefaults {
4545
public static final String DEFAULT_SERVLET_ROOT_CONTEXT_SERVICE_NAME = "root-servlet";
4646
public static final String DEFAULT_AGENT_WRITER_TYPE = "DDAgentWriter";
4747
public static final boolean DEFAULT_STARTUP_LOGS_ENABLED = true;
48-
49-
static final boolean DEFAULT_INJECT_DATADOG_ATTRIBUTE = true;
50-
static final String DEFAULT_SITE = "datadoghq.com";
51-
5248
public static final String DEFAULT_FEATURE_FLAGGING_CONFIGURATION_SOURCE = "agentless";
5349
public static final int DEFAULT_FEATURE_FLAGGING_CONFIGURATION_SOURCE_POLL_INTERVAL_SECONDS = 30;
5450
public static final int DEFAULT_FEATURE_FLAGGING_CONFIGURATION_SOURCE_REQUEST_TIMEOUT_SECONDS = 2;
5551

52+
static final boolean DEFAULT_INJECT_DATADOG_ATTRIBUTE = true;
53+
static final String DEFAULT_SITE = "datadoghq.com";
54+
5655
static final boolean DEFAULT_CODE_ORIGIN_FOR_SPANS_INTERFACE_SUPPORT = false;
5756
static final int DEFAULT_CODE_ORIGIN_MAX_USER_FRAMES = 8;
5857
static final boolean DEFAULT_TRACE_ENABLED = true;

products/feature-flagging/feature-flagging-lib/src/main/java/com/datadog/featureflag/AgentlessConfigurationSource.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.util.concurrent.atomic.AtomicBoolean;
2424
import java.util.concurrent.atomic.AtomicReference;
2525
import java.util.function.DoubleSupplier;
26+
import javax.annotation.Nullable;
2627
import okhttp3.Call;
2728
import okhttp3.HttpUrl;
2829
import okhttp3.OkHttpClient;
@@ -354,10 +355,10 @@ interface RetrySleeper {
354355

355356
static final class UfcHttpResponse {
356357
final int status;
357-
final String etag;
358-
final byte[] body;
358+
@Nullable final String etag;
359+
@Nullable final byte[] body;
359360

360-
UfcHttpResponse(final int status, final String etag, final byte[] body) {
361+
UfcHttpResponse(final int status, @Nullable final String etag, @Nullable final byte[] body) {
361362
this.status = status;
362363
this.etag = etag;
363364
this.body = body;
@@ -388,9 +389,12 @@ public UfcHttpResponse fetch(final HttpUrl endpoint, final Config config, final
388389
if (cancelled.get()) {
389390
call.cancel();
390391
}
391-
try (Response response = call.execute()) {
392-
final ResponseBody responseBody = response.body();
393-
return new UfcHttpResponse(response.code(), response.header("ETag"), responseBody.bytes());
392+
try {
393+
final Response response = call.execute();
394+
try (ResponseBody responseBody = response.body()) {
395+
final byte[] body = responseBody != null ? responseBody.bytes() : null;
396+
return new UfcHttpResponse(response.code(), response.header("ETag"), body);
397+
}
394398
} finally {
395399
activeCall.compareAndSet(call, null);
396400
}

products/feature-flagging/feature-flagging-lib/src/test/java/com/datadog/featureflag/AgentlessConfigurationSourceTest.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import static org.mockito.Mockito.times;
1414
import static org.mockito.Mockito.verify;
1515
import static org.mockito.Mockito.verifyNoInteractions;
16+
import static org.mockito.Mockito.when;
1617

1718
import datadog.communication.http.OkHttpUtils;
1819
import datadog.logging.RatelimitedLogger;
@@ -35,8 +36,11 @@
3536
import java.util.concurrent.ScheduledExecutorService;
3637
import java.util.concurrent.TimeUnit;
3738
import java.util.concurrent.atomic.AtomicInteger;
39+
import okhttp3.Call;
3840
import okhttp3.HttpUrl;
3941
import okhttp3.OkHttpClient;
42+
import okhttp3.Protocol;
43+
import okhttp3.Response;
4044
import org.junit.jupiter.api.AfterEach;
4145
import org.junit.jupiter.api.Nested;
4246
import org.junit.jupiter.api.Test;
@@ -191,6 +195,32 @@ void realHttpClientAllowsMissingEtagAndEmptyResponseBody() throws Exception {
191195
}
192196
}
193197

198+
@Test
199+
void httpClientAdapterPreservesMissingResponseBody() throws Exception {
200+
final OkHttpClient httpClient = mock(OkHttpClient.class);
201+
final Call call = mock(Call.class);
202+
final HttpUrl endpoint = HttpUrl.get("http://localhost");
203+
final okhttp3.Request request = new okhttp3.Request.Builder().url(endpoint).build();
204+
final Response okHttpResponse =
205+
new Response.Builder()
206+
.request(request)
207+
.protocol(Protocol.HTTP_1_1)
208+
.code(HttpURLConnection.HTTP_OK)
209+
.message("OK")
210+
.build();
211+
when(httpClient.newCall(any())).thenReturn(call);
212+
when(call.execute()).thenReturn(okHttpResponse);
213+
final AgentlessConfigurationSource.OkHttpUfcHttpClient client =
214+
new AgentlessConfigurationSource.OkHttpUfcHttpClient(httpClient);
215+
216+
final AgentlessConfigurationSource.UfcHttpResponse response =
217+
client.fetch(endpoint, config(), null);
218+
219+
assertEquals(HttpURLConnection.HTTP_OK, response.status);
220+
assertNull(response.etag);
221+
assertNull(response.body);
222+
}
223+
194224
@Test
195225
void realHttpClientCancellationInterruptsInFlightRequest() throws Exception {
196226
final CountDownLatch requestStarted = new CountDownLatch(1);

0 commit comments

Comments
 (0)