Skip to content

Commit 5956f8d

Browse files
emyllerclaude
andauthored
feat: Send a standard User-Agent: sdk-name/version header (#83)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 3076d21 commit 5956f8d

4 files changed

Lines changed: 76 additions & 1 deletion

File tree

FlagsmithClient/src/main/java/com/flagsmith/internal/FlagsmithEventService.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ internal class FlagsmithEventService constructor(
1919
) {
2020
private val sseClient = OkHttpClient.Builder()
2121
.addInterceptor(FlagsmithRetrofitService.envKeyInterceptor(environmentKey))
22+
.addInterceptor(FlagsmithRetrofitService.userAgentInterceptor())
2223
.connectTimeout(6, TimeUnit.SECONDS)
2324
.readTimeout(10, TimeUnit.MINUTES)
2425
.writeTimeout(10, TimeUnit.MINUTES)

FlagsmithClient/src/main/java/com/flagsmith/internal/FlagsmithRetrofitService.kt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,20 @@ interface FlagsmithRetrofitService {
3939
private const val UPDATED_AT_HEADER = "x-flagsmith-document-updated-at"
4040
private const val ACCEPT_HEADER_VALUE = "application/json"
4141
private const val CONTENT_TYPE_HEADER_VALUE = "application/json; charset=utf-8"
42+
private const val USER_AGENT_HEADER = "User-Agent"
43+
44+
// x-release-please-start-version
45+
private const val SDK_VERSION = "1.8.0"
46+
// x-release-please-end
47+
48+
fun userAgentInterceptor(): Interceptor {
49+
return Interceptor { chain ->
50+
val request = chain.request().newBuilder()
51+
.header(USER_AGENT_HEADER, "flagsmith-kotlin-android-sdk/$SDK_VERSION")
52+
.build()
53+
chain.proceed(request)
54+
}
55+
}
4256

4357
fun <T : FlagsmithRetrofitService> create(
4458
baseUrl: String,
@@ -92,6 +106,7 @@ interface FlagsmithRetrofitService {
92106

93107
val client = OkHttpClient.Builder()
94108
.addInterceptor(envKeyInterceptor(environmentKey))
109+
.addInterceptor(userAgentInterceptor())
95110
.addInterceptor(updatedAtInterceptor(timeTracker))
96111
.addInterceptor(jsonContentTypeInterceptor())
97112
.let { if (cacheConfig.enableCache) it.addNetworkInterceptor(cacheControlInterceptor()) else it }
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package com.flagsmith
2+
3+
import com.flagsmith.mockResponses.MockEndpoint
4+
import com.flagsmith.mockResponses.mockResponseFor
5+
import kotlinx.coroutines.runBlocking
6+
import org.junit.After
7+
import org.junit.Assert.assertEquals
8+
import org.junit.Assert.assertTrue
9+
import org.junit.Before
10+
import org.junit.Test
11+
import org.mockserver.integration.ClientAndServer
12+
import org.mockserver.model.HttpRequest.request
13+
14+
class UserAgentTests {
15+
16+
private lateinit var mockServer: ClientAndServer
17+
private lateinit var flagsmith: Flagsmith
18+
19+
@Before
20+
fun setup() {
21+
mockServer = ClientAndServer.startClientAndServer()
22+
flagsmith = Flagsmith(
23+
environmentKey = "",
24+
baseUrl = "http://localhost:${mockServer.localPort}",
25+
enableAnalytics = false,
26+
cacheConfig = FlagsmithCacheConfig(enableCache = false)
27+
)
28+
}
29+
30+
@After
31+
fun tearDown() {
32+
mockServer.stop()
33+
}
34+
35+
@Test
36+
fun testUserAgentHeaderIsSent() {
37+
mockServer.mockResponseFor(MockEndpoint.GET_FLAGS)
38+
runBlocking {
39+
val result = flagsmith.getFeatureFlagsSync()
40+
assertTrue(result.isSuccess)
41+
}
42+
43+
val requests = mockServer.retrieveRecordedRequests(
44+
request()
45+
.withPath("/flags/")
46+
.withMethod("GET")
47+
)
48+
assertEquals(1, requests.size)
49+
50+
val userAgent = requests[0].getFirstHeader("User-Agent")
51+
// x-release-please-start-version
52+
assertEquals("flagsmith-kotlin-android-sdk/1.8.0", userAgent)
53+
// x-release-please-end
54+
}
55+
}

release-please-config.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@
88
"bump-patch-for-minor-pre-major": false,
99
"draft": false,
1010
"prerelease": false,
11-
"include-component-in-tag": false
11+
"include-component-in-tag": false,
12+
"extra-files": [
13+
"FlagsmithClient/src/main/java/com/flagsmith/internal/FlagsmithRetrofitService.kt",
14+
"FlagsmithClient/src/test/java/com/flagsmith/UserAgentTests.kt"
15+
]
1216
}
1317
},
1418
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",

0 commit comments

Comments
 (0)