From d89071083b02ab8d40df27bcc4a25147690fcee4 Mon Sep 17 00:00:00 2001 From: Xavier Gouchet Date: Thu, 4 Mar 2021 10:25:44 +0100 Subject: [PATCH 1/2] :bug: (RUMM-1151): Use the Local first-party host detector --- .../com/datadog/android/DatadogInterceptor.kt | 10 +--- .../android/tracing/TracingInterceptor.kt | 13 ++--- .../TracingInterceptorNotSendingSpanTest.kt | 52 ++++++++++++------- .../android/tracing/TracingInterceptorTest.kt | 50 ++++++++++++------ 4 files changed, 73 insertions(+), 52 deletions(-) diff --git a/dd-sdk-android/src/main/kotlin/com/datadog/android/DatadogInterceptor.kt b/dd-sdk-android/src/main/kotlin/com/datadog/android/DatadogInterceptor.kt index a834668b3e..bef3285552 100644 --- a/dd-sdk-android/src/main/kotlin/com/datadog/android/DatadogInterceptor.kt +++ b/dd-sdk-android/src/main/kotlin/com/datadog/android/DatadogInterceptor.kt @@ -10,7 +10,6 @@ import com.datadog.android.core.internal.CoreFeature import com.datadog.android.core.internal.net.FirstPartyHostDetector import com.datadog.android.core.internal.net.identifyRequest import com.datadog.android.core.internal.utils.devLogger -import com.datadog.android.core.internal.utils.warnDeprecated import com.datadog.android.rum.GlobalRum import com.datadog.android.rum.RumAttributes import com.datadog.android.rum.RumErrorSource @@ -104,14 +103,7 @@ internal constructor( tracedRequestListener, CoreFeature.firstPartyHostDetector, { AndroidTracer.Builder().build() } - ) { - warnDeprecated( - "Constructor DatadogInterceptor(List, TracedRequestListener)", - "1.6.0", - "1.8.0", - "DatadogInterceptor(TracedRequestListener)" - ) - } + ) /** * Creates a [TracingInterceptor] to automatically create a trace around OkHttp [Request]s, and diff --git a/dd-sdk-android/src/main/kotlin/com/datadog/android/tracing/TracingInterceptor.kt b/dd-sdk-android/src/main/kotlin/com/datadog/android/tracing/TracingInterceptor.kt index ddaff7d85b..b1021a1cae 100644 --- a/dd-sdk-android/src/main/kotlin/com/datadog/android/tracing/TracingInterceptor.kt +++ b/dd-sdk-android/src/main/kotlin/com/datadog/android/tracing/TracingInterceptor.kt @@ -11,7 +11,6 @@ import com.datadog.android.core.internal.CoreFeature import com.datadog.android.core.internal.net.FirstPartyHostDetector import com.datadog.android.core.internal.utils.devLogger import com.datadog.android.core.internal.utils.loggableStackTrace -import com.datadog.android.core.internal.utils.warnDeprecated import com.datadog.android.tracing.internal.TracesFeature import com.datadog.opentracing.DDTracer import com.datadog.trace.api.DDTags @@ -98,14 +97,7 @@ internal constructor( CoreFeature.firstPartyHostDetector, null, { AndroidTracer.Builder().build() } - ) { - warnDeprecated( - "Constructor TracingInterceptor(List, TracedRequestListener)", - "1.6.0", - "1.8.0", - "TracingInterceptor(TracedRequestListener)" - ) - } + ) /** * Creates a [TracingInterceptor] to automatically create a trace around OkHttp [Request]s. @@ -174,7 +166,8 @@ internal constructor( private fun isRequestTraceable(request: Request): Boolean { val url = request.url() - return firstPartyHostDetector.isFirstPartyUrl(url) + return firstPartyHostDetector.isFirstPartyUrl(url) || + localFirstPartyHostDetector.isFirstPartyUrl(url) } @Suppress("TooGenericExceptionCaught", "ThrowingInternalException") diff --git a/dd-sdk-android/src/test/kotlin/com/datadog/android/tracing/TracingInterceptorNotSendingSpanTest.kt b/dd-sdk-android/src/test/kotlin/com/datadog/android/tracing/TracingInterceptorNotSendingSpanTest.kt index bd20c913e2..25206796c5 100644 --- a/dd-sdk-android/src/test/kotlin/com/datadog/android/tracing/TracingInterceptorNotSendingSpanTest.kt +++ b/dd-sdk-android/src/test/kotlin/com/datadog/android/tracing/TracingInterceptorNotSendingSpanTest.kt @@ -153,6 +153,9 @@ internal open class TracingInterceptorNotSendingSpanTest { @StringForgery lateinit var fakeOrigin: String + @StringForgery(regex = TracingInterceptorTest.HOSTNAME_PATTERN) + lateinit var fakeLocalHosts: List + // endregion @BeforeEach @@ -172,8 +175,8 @@ internal open class TracingInterceptorNotSendingSpanTest { val mediaType = forge.anElementFrom("application", "image", "text", "model") + "/" + forge.anAlphabeticalString() fakeMediaType = MediaType.parse(mediaType) - fakeRequest = forgeRequest(forge, false) - val tracedHosts = listOf(fakeHostIp, fakeHostName) + fakeUrl = forgeUrl(forge) + fakeRequest = forgeRequest(forge) TracesFeature.initialize( mockAppContext, fakeConfig @@ -182,7 +185,7 @@ internal open class TracingInterceptorNotSendingSpanTest { doAnswer { true }.whenever(mockDetector).isFirstPartyUrl(HttpUrl.get(fakeUrl)) GlobalTracer.registerIfAbsent(mockTracer) - testedInterceptor = instantiateTestedInterceptor(tracedHosts) { mockLocalTracer } + testedInterceptor = instantiateTestedInterceptor(fakeLocalHosts) { mockLocalTracer } } @AfterEach @@ -215,11 +218,12 @@ internal open class TracingInterceptorNotSendingSpanTest { } @Test - fun `𝕄 inject tracing header 𝕎 intercept() for any request`( + fun `𝕄 inject tracing header 𝕎 intercept() {global known host}`( @StringForgery key: String, @StringForgery(type = StringForgeryType.ALPHA_NUMERICAL) value: String, @IntForgery(min = 200, max = 600) statusCode: Int ) { + whenever(mockDetector.isFirstPartyUrl(HttpUrl.get(fakeUrl))).thenReturn(true) stubChain(mockChain, statusCode) doAnswer { invocation -> val carrier = invocation.arguments[2] as TextMapInject @@ -236,13 +240,15 @@ internal open class TracingInterceptorNotSendingSpanTest { } @Test - fun `𝕄 inject tracing header 𝕎 intercept() for any request with legacy host regex`( + fun `𝕄 inject tracing header 𝕎 intercept() {local known host}`( @StringForgery key: String, @StringForgery(type = StringForgeryType.ALPHA_NUMERICAL) value: String, @IntForgery(min = 200, max = 600) statusCode: Int, forge: Forge ) { - fakeRequest = forgeRequest(forge, true) + fakeUrl = forgeUrl(forge, forge.anElementFrom(fakeLocalHosts)) + fakeRequest = forgeRequest(forge) + whenever(mockDetector.isFirstPartyUrl(HttpUrl.get(fakeUrl))).thenReturn(false) stubChain(mockChain, statusCode) doAnswer { invocation -> val carrier = invocation.arguments[2] as TextMapInject @@ -270,6 +276,7 @@ internal open class TracingInterceptorNotSendingSpanTest { whenever(parentSpan.context()) doReturn parentSpanContext whenever(mockSpanBuilder.asChildOf(parentSpanContext)) doReturn mockSpanBuilder fakeRequest = forgeRequest(forge) { it.tag(Span::class.java, parentSpan) } + whenever(mockDetector.isFirstPartyUrl(HttpUrl.get(fakeUrl))).thenReturn(true) doAnswer { true }.whenever(mockDetector).isFirstPartyUrl(HttpUrl.get(fakeUrl)) stubChain(mockChain, statusCode) doAnswer { invocation -> @@ -300,6 +307,7 @@ internal open class TracingInterceptorNotSendingSpanTest { val parentSpanContext: SpanContext = mock() whenever(mockTracer.extract(any(), any())) doReturn parentSpanContext whenever(mockSpanBuilder.asChildOf(any())) doReturn mockSpanBuilder + whenever(mockDetector.isFirstPartyUrl(HttpUrl.get(fakeUrl))).thenReturn(true) fakeRequest = forgeRequest(forge) doAnswer { true }.whenever(mockDetector).isFirstPartyUrl(HttpUrl.get(fakeUrl)) stubChain(mockChain, statusCode) @@ -339,6 +347,7 @@ internal open class TracingInterceptorNotSendingSpanTest { fun `𝕄 create a span with info 𝕎 intercept() for failing request {4xx}`( @IntForgery(min = 400, max = 500) statusCode: Int ) { + whenever(mockDetector.isFirstPartyUrl(HttpUrl.get(fakeUrl))).thenReturn(true) stubChain(mockChain, statusCode) val response = testedInterceptor.intercept(mockChain) @@ -357,6 +366,7 @@ internal open class TracingInterceptorNotSendingSpanTest { fun `𝕄 create a span with info 𝕎 intercept() for failing request {5xx}`( @IntForgery(min = 500, max = 600) statusCode: Int ) { + whenever(mockDetector.isFirstPartyUrl(HttpUrl.get(fakeUrl))).thenReturn(true) stubChain(mockChain, statusCode) val response = testedInterceptor.intercept(mockChain) @@ -373,6 +383,7 @@ internal open class TracingInterceptorNotSendingSpanTest { @Test fun `𝕄 create a span with info 𝕎 intercept() for 404 request`() { + whenever(mockDetector.isFirstPartyUrl(HttpUrl.get(fakeUrl))).thenReturn(true) stubChain(mockChain, 404) val response = testedInterceptor.intercept(mockChain) @@ -391,6 +402,7 @@ internal open class TracingInterceptorNotSendingSpanTest { fun `𝕄 create a span with info 𝕎 intercept() for throwing request`( @Forgery throwable: Throwable ) { + whenever(mockDetector.isFirstPartyUrl(HttpUrl.get(fakeUrl))).thenReturn(true) whenever(mockChain.request()) doReturn fakeRequest whenever(mockChain.proceed(any())) doThrow throwable @@ -433,6 +445,7 @@ internal open class TracingInterceptorNotSendingSpanTest { val localSpanBuilder: DDTracer.DDSpanBuilder = mock() val localSpan: Span = mock(extraInterfaces = arrayOf(MutableSpan::class)) GlobalTracer::class.java.setStaticValue("isRegistered", false) + whenever(mockDetector.isFirstPartyUrl(HttpUrl.get(fakeUrl))).thenReturn(true) stubChain(mockChain, statusCode) whenever(localSpanBuilder.asChildOf(null as SpanContext?)) doReturn localSpanBuilder whenever(localSpanBuilder.start()) doReturn localSpan @@ -463,6 +476,7 @@ internal open class TracingInterceptorNotSendingSpanTest { val localSpanBuilder: DDTracer.DDSpanBuilder = mock() val localSpan: Span = mock(extraInterfaces = arrayOf(MutableSpan::class)) GlobalTracer::class.java.setStaticValue("isRegistered", false) + whenever(mockDetector.isFirstPartyUrl(HttpUrl.get(fakeUrl))).thenReturn(true) stubChain(mockChain, statusCode) whenever(localSpanBuilder.asChildOf(null as SpanContext?)) doReturn localSpanBuilder whenever(localSpanBuilder.start()) doReturn localSpan @@ -503,6 +517,7 @@ internal open class TracingInterceptorNotSendingSpanTest { @StringForgery tagKey: String, @StringForgery(type = StringForgeryType.ALPHA_NUMERICAL) tagValue: String ) { + whenever(mockDetector.isFirstPartyUrl(HttpUrl.get(fakeUrl))).thenReturn(true) stubChain(mockChain, statusCode) whenever( mockRequestListener.onRequestIntercepted(any(), any(), anyOrNull(), anyOrNull()) @@ -529,6 +544,7 @@ internal open class TracingInterceptorNotSendingSpanTest { @StringForgery tagKey: String, @StringForgery(type = StringForgeryType.ALPHA_NUMERICAL) tagValue: String ) { + whenever(mockDetector.isFirstPartyUrl(HttpUrl.get(fakeUrl))).thenReturn(true) stubChain(mockChain, statusCode) whenever( mockRequestListener.onRequestIntercepted(any(), any(), anyOrNull(), anyOrNull()) @@ -555,6 +571,7 @@ internal open class TracingInterceptorNotSendingSpanTest { @StringForgery tagKey: String, @StringForgery(type = StringForgeryType.ALPHA_NUMERICAL) tagValue: String ) { + whenever(mockDetector.isFirstPartyUrl(HttpUrl.get(fakeUrl))).thenReturn(true) whenever( mockRequestListener.onRequestIntercepted(any(), any(), anyOrNull(), anyOrNull()) ).doAnswer { @@ -582,8 +599,7 @@ internal open class TracingInterceptorNotSendingSpanTest { @Test fun `M do not update the hostDetector W host list provided`(forge: Forge) { // GIVEN - val localHosts = - forge.aList { forge.aStringMatching(TracingInterceptorTest.HOSTNAME_PATTERN) } + val localHosts = forge.aList { forge.aStringMatching(HOSTNAME_PATTERN) } // WHEN testedInterceptor = instantiateTestedInterceptor(localHosts) { mockLocalTracer } @@ -597,7 +613,8 @@ internal open class TracingInterceptorNotSendingSpanTest { @IntForgery(min = 200, max = 300) statusCode: Int, forge: Forge ) { - fakeRequest = forgeRequest(forge, false) + fakeRequest = forgeRequest(forge) + whenever(mockDetector.isFirstPartyUrl(HttpUrl.get(fakeUrl))).thenReturn(false) stubChain(mockChain, statusCode) val response = testedInterceptor.intercept(mockChain) @@ -629,6 +646,7 @@ internal open class TracingInterceptorNotSendingSpanTest { ) { var called = 0 val tracedHosts = listOf(fakeHostIp, fakeHostName) + whenever(mockDetector.isFirstPartyUrl(HttpUrl.get(fakeUrl))).thenReturn(true) testedInterceptor = instantiateTestedInterceptor(tracedHosts) { called++ mockLocalTracer @@ -661,19 +679,17 @@ internal open class TracingInterceptorNotSendingSpanTest { whenever(chain.proceed(any())) doReturn fakeResponse } + private fun forgeUrl(forge: Forge, knownHost: String? = null): String { + val protocol = forge.anElementFrom("http", "https") + val host = knownHost ?: forge.aStringMatching(TracingInterceptorTest.HOSTNAME_PATTERN) + val path = forge.anAlphaNumericalString() + return "$protocol://$host/$path" + } + private fun forgeRequest( forge: Forge, - validHost: Boolean = false, configure: (Request.Builder) -> Unit = {} ): Request { - val protocol = forge.anElementFrom("http", "https") - val host = forge.aStringMatching(TracingInterceptorTest.HOSTNAME_PATTERN) - val path = forge.anAlphaNumericalString() - fakeUrl = "$protocol://$host/$path" - if (validHost) { - whenever(mockDetector.isFirstPartyUrl(HttpUrl.get(fakeUrl))).thenReturn(true) - } - val builder = Request.Builder().url(fakeUrl) if (forge.aBool()) { fakeMethod = "POST" diff --git a/dd-sdk-android/src/test/kotlin/com/datadog/android/tracing/TracingInterceptorTest.kt b/dd-sdk-android/src/test/kotlin/com/datadog/android/tracing/TracingInterceptorTest.kt index 3906115fbb..039f581edd 100644 --- a/dd-sdk-android/src/test/kotlin/com/datadog/android/tracing/TracingInterceptorTest.kt +++ b/dd-sdk-android/src/test/kotlin/com/datadog/android/tracing/TracingInterceptorTest.kt @@ -147,6 +147,9 @@ internal open class TracingInterceptorTest { @StringForgery lateinit var fakeOrigin: String + @StringForgery(regex = HOSTNAME_PATTERN) + lateinit var fakeLocalHosts: List + // endregion @BeforeEach @@ -168,13 +171,13 @@ internal open class TracingInterceptorTest { val mediaType = forge.anElementFrom("application", "image", "text", "model") + "/" + forge.anAlphabeticalString() fakeMediaType = MediaType.parse(mediaType) - // by default the request has a valid host - fakeRequest = forgeRequest(forge, true) + fakeUrl = forgeUrl(forge) + fakeRequest = forgeRequest(forge) TracesFeature.initialize( mockAppContext, fakeConfig ) - testedInterceptor = instantiateTestedInterceptor { + testedInterceptor = instantiateTestedInterceptor(fakeLocalHosts) { mockLocalTracer } @@ -207,12 +210,13 @@ internal open class TracingInterceptorTest { } @Test - fun `𝕄 inject tracing header 𝕎 intercept() for any request`( + fun `𝕄 inject tracing header 𝕎 intercept() {global known host}`( @StringForgery key: String, @StringForgery(type = StringForgeryType.ALPHA_NUMERICAL) value: String, @IntForgery(min = 200, max = 600) statusCode: Int ) { stubChain(mockChain, statusCode) + whenever(mockDetector.isFirstPartyUrl(HttpUrl.get(fakeUrl))).thenReturn(true) doAnswer { invocation -> val carrier = invocation.arguments[2] as TextMapInject carrier.put(key, value) @@ -228,12 +232,15 @@ internal open class TracingInterceptorTest { } @Test - fun `𝕄 inject tracing header 𝕎 intercept() for any request with legacy host regex`( + fun `𝕄 inject tracing header 𝕎 intercept() {local known host}`( @StringForgery key: String, @StringForgery(type = StringForgeryType.ALPHA_NUMERICAL) value: String, @IntForgery(min = 200, max = 600) statusCode: Int, forge: Forge ) { + fakeUrl = forgeUrl(forge, forge.anElementFrom(fakeLocalHosts)) + fakeRequest = forgeRequest(forge) + whenever(mockDetector.isFirstPartyUrl(HttpUrl.get(fakeUrl))).thenReturn(false) stubChain(mockChain, statusCode) doAnswer { invocation -> val carrier = invocation.arguments[2] as TextMapInject @@ -260,7 +267,8 @@ internal open class TracingInterceptorTest { val parentSpanContext: SpanContext = mock() whenever(parentSpan.context()) doReturn parentSpanContext whenever(mockSpanBuilder.asChildOf(parentSpanContext)) doReturn mockSpanBuilder - fakeRequest = forgeRequest(forge, true) { it.tag(Span::class.java, parentSpan) } + fakeRequest = forgeRequest(forge) { it.tag(Span::class.java, parentSpan) } + whenever(mockDetector.isFirstPartyUrl(HttpUrl.get(fakeUrl))).thenReturn(true) stubChain(mockChain, statusCode) doAnswer { invocation -> val carrier = invocation.arguments[2] as TextMapInject @@ -290,6 +298,7 @@ internal open class TracingInterceptorTest { val parentSpanContext: SpanContext = mock() whenever(mockTracer.extract(any(), any())) doReturn parentSpanContext whenever(mockSpanBuilder.asChildOf(any())) doReturn mockSpanBuilder + whenever(mockDetector.isFirstPartyUrl(HttpUrl.get(fakeUrl))).thenReturn(true) stubChain(mockChain, statusCode) doAnswer { invocation -> val carrier = invocation.arguments[2] as TextMapInject @@ -311,6 +320,7 @@ internal open class TracingInterceptorTest { fun `𝕄 create a span with info 𝕎 intercept() for successful request`( @IntForgery(min = 200, max = 300) statusCode: Int ) { + whenever(mockDetector.isFirstPartyUrl(HttpUrl.get(fakeUrl))).thenReturn(true) stubChain(mockChain, statusCode) val response = testedInterceptor.intercept(mockChain) @@ -327,6 +337,7 @@ internal open class TracingInterceptorTest { fun `𝕄 create a span with info 𝕎 intercept() for failing request {4xx}`( @IntForgery(min = 400, max = 500) statusCode: Int ) { + whenever(mockDetector.isFirstPartyUrl(HttpUrl.get(fakeUrl))).thenReturn(true) stubChain(mockChain, statusCode) val response = testedInterceptor.intercept(mockChain) @@ -345,6 +356,7 @@ internal open class TracingInterceptorTest { fun `𝕄 create a span with info 𝕎 intercept() for failing request {5xx}`( @IntForgery(min = 500, max = 600) statusCode: Int ) { + whenever(mockDetector.isFirstPartyUrl(HttpUrl.get(fakeUrl))).thenReturn(true) stubChain(mockChain, statusCode) val response = testedInterceptor.intercept(mockChain) @@ -361,6 +373,7 @@ internal open class TracingInterceptorTest { @Test fun `𝕄 create a span with info 𝕎 intercept() for 404 request`() { + whenever(mockDetector.isFirstPartyUrl(HttpUrl.get(fakeUrl))).thenReturn(true) stubChain(mockChain, 404) val response = testedInterceptor.intercept(mockChain) @@ -379,6 +392,7 @@ internal open class TracingInterceptorTest { fun `𝕄 create a span with info 𝕎 intercept() for throwing request`( @Forgery throwable: Throwable ) { + whenever(mockDetector.isFirstPartyUrl(HttpUrl.get(fakeUrl))).thenReturn(true) whenever(mockChain.request()) doReturn fakeRequest whenever(mockChain.proceed(any())) doThrow throwable @@ -401,6 +415,7 @@ internal open class TracingInterceptorTest { ) { GlobalTracer::class.java.setStaticValue("isRegistered", false) TracesFeature.invokeMethod("stop") + whenever(mockDetector.isFirstPartyUrl(HttpUrl.get(fakeUrl))).thenReturn(true) stubChain(mockChain, statusCode) testedInterceptor.intercept(mockChain) @@ -421,6 +436,7 @@ internal open class TracingInterceptorTest { val localSpanBuilder: DDTracer.DDSpanBuilder = mock() val localSpan: Span = mock(extraInterfaces = arrayOf(MutableSpan::class)) GlobalTracer::class.java.setStaticValue("isRegistered", false) + whenever(mockDetector.isFirstPartyUrl(HttpUrl.get(fakeUrl))).thenReturn(true) stubChain(mockChain, statusCode) whenever(localSpanBuilder.asChildOf(null as SpanContext?)) doReturn localSpanBuilder whenever(localSpanBuilder.withOrigin(getExpectedOrigin())) doReturn localSpanBuilder @@ -452,6 +468,7 @@ internal open class TracingInterceptorTest { val localSpanBuilder: DDTracer.DDSpanBuilder = mock() val localSpan: Span = mock(extraInterfaces = arrayOf(MutableSpan::class)) GlobalTracer::class.java.setStaticValue("isRegistered", false) + whenever(mockDetector.isFirstPartyUrl(HttpUrl.get(fakeUrl))).thenReturn(true) stubChain(mockChain, statusCode) whenever(localSpanBuilder.asChildOf(null as SpanContext?)) doReturn localSpanBuilder whenever(localSpanBuilder.withOrigin(getExpectedOrigin())) doReturn localSpanBuilder @@ -493,6 +510,7 @@ internal open class TracingInterceptorTest { @StringForgery tagKey: String, @StringForgery(type = StringForgeryType.ALPHA_NUMERICAL) tagValue: String ) { + whenever(mockDetector.isFirstPartyUrl(HttpUrl.get(fakeUrl))).thenReturn(true) stubChain(mockChain, statusCode) whenever( mockRequestListener.onRequestIntercepted(any(), any(), anyOrNull(), anyOrNull()) @@ -519,6 +537,7 @@ internal open class TracingInterceptorTest { @StringForgery tagKey: String, @StringForgery(type = StringForgeryType.ALPHA_NUMERICAL) tagValue: String ) { + whenever(mockDetector.isFirstPartyUrl(HttpUrl.get(fakeUrl))).thenReturn(true) stubChain(mockChain, statusCode) whenever( mockRequestListener.onRequestIntercepted(any(), any(), anyOrNull(), anyOrNull()) @@ -545,6 +564,7 @@ internal open class TracingInterceptorTest { @StringForgery tagKey: String, @StringForgery(type = StringForgeryType.ALPHA_NUMERICAL) tagValue: String ) { + whenever(mockDetector.isFirstPartyUrl(HttpUrl.get(fakeUrl))).thenReturn(true) whenever( mockRequestListener.onRequestIntercepted(any(), any(), anyOrNull(), anyOrNull()) ).doAnswer { @@ -586,7 +606,7 @@ internal open class TracingInterceptorTest { @IntForgery(min = 200, max = 300) statusCode: Int, forge: Forge ) { - fakeRequest = forgeRequest(forge, false) + whenever(mockDetector.isFirstPartyUrl(HttpUrl.get(fakeUrl))).thenReturn(false) stubChain(mockChain, statusCode) val response = testedInterceptor.intercept(mockChain) @@ -625,6 +645,7 @@ internal open class TracingInterceptorTest { mockLocalTracer } GlobalTracer::class.java.setStaticValue("isRegistered", false) + whenever(mockDetector.isFirstPartyUrl(HttpUrl.get(fakeUrl))).thenReturn(true) stubChain(mockChain, statusCode) val countDownLatch = CountDownLatch(2) @@ -652,18 +673,17 @@ internal open class TracingInterceptorTest { whenever(chain.proceed(any())) doReturn fakeResponse } + private fun forgeUrl(forge: Forge, knownHost: String? = null): String { + val protocol = forge.anElementFrom("http", "https") + val host = knownHost ?: forge.aStringMatching(HOSTNAME_PATTERN) + val path = forge.anAlphaNumericalString() + return "$protocol://$host/$path" + } + private fun forgeRequest( forge: Forge, - validHost: Boolean = false, configure: (Request.Builder) -> Unit = {} ): Request { - val protocol = forge.anElementFrom("http", "https") - val host = forge.aStringMatching(HOSTNAME_PATTERN) - val path = forge.anAlphaNumericalString() - fakeUrl = "$protocol://$host/$path" - if (validHost) { - whenever(mockDetector.isFirstPartyUrl(HttpUrl.get(fakeUrl))).thenReturn(true) - } val builder = Request.Builder().url(fakeUrl) if (forge.aBool()) { fakeMethod = "POST" From cf6fe449ca5fbebdf6d4fc1ead6c2985cc9dfe40 Mon Sep 17 00:00:00 2001 From: Xavier Gouchet Date: Thu, 4 Mar 2021 11:23:11 +0100 Subject: [PATCH 2/2] Make the initialisation resilient when the OkHttp intereceptor is created before SDK config --- .../kotlin/com/datadog/android/core/internal/CoreFeature.kt | 2 +- .../datadog/android/core/internal/net/FirstPartyHostDetector.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dd-sdk-android/src/main/kotlin/com/datadog/android/core/internal/CoreFeature.kt b/dd-sdk-android/src/main/kotlin/com/datadog/android/core/internal/CoreFeature.kt index 1697529d0f..db2ec2bb88 100644 --- a/dd-sdk-android/src/main/kotlin/com/datadog/android/core/internal/CoreFeature.kt +++ b/dd-sdk-android/src/main/kotlin/com/datadog/android/core/internal/CoreFeature.kt @@ -102,7 +102,7 @@ internal object CoreFeature { initializeClockSync(appContext) setupInfoProviders(appContext, consent) setupOkHttpClient(configuration.needsClearTextHttp) - firstPartyHostDetector = FirstPartyHostDetector(configuration.firstPartyHosts) + firstPartyHostDetector.addKnownHosts(configuration.firstPartyHosts) setupExecutors() initialized.set(true) diff --git a/dd-sdk-android/src/main/kotlin/com/datadog/android/core/internal/net/FirstPartyHostDetector.kt b/dd-sdk-android/src/main/kotlin/com/datadog/android/core/internal/net/FirstPartyHostDetector.kt index cb7f07b5b7..16ada90581 100644 --- a/dd-sdk-android/src/main/kotlin/com/datadog/android/core/internal/net/FirstPartyHostDetector.kt +++ b/dd-sdk-android/src/main/kotlin/com/datadog/android/core/internal/net/FirstPartyHostDetector.kt @@ -33,6 +33,6 @@ internal class FirstPartyHostDetector( } fun addKnownHosts(hosts: List) { - knownHosts = knownHosts + hosts + knownHosts = knownHosts + hosts.map { it.toLowerCase(Locale.US) } } }