Skip to content

Commit 54c1d54

Browse files
authored
fix: don't apply Coder TLS alternate hostname to JetBrains IDE feed client (#311)
The IdeFeedManager fetches IDE metadata from data.services.jetbrains.com but was reusing the default Coder OkHttp client which is for Coder endpoints and it applies the user-configured TLS alternate hostname. That setting is meant for the Coder deployment and should not affect requests to JetBrains. The fix moves the JetBrains client construction into IdeFeedManager where it belongs, with only what it actually needs: user-agent, logging, proxy, retry. No Coder TLS context or hostname verifier touches that traffic anymore.
1 parent 12977b3 commit 54c1d54

4 files changed

Lines changed: 54 additions & 30 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## Unreleased
44

5+
### Changed
6+
7+
- skip the Coder TLS alternate hostname when fetching IDE metadata from JetBrains
8+
59
## 0.9.0 - 2026-05-14
610

711
### Added

src/main/kotlin/com/coder/toolbox/feed/IdeFeedManager.kt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package com.coder.toolbox.feed
22

33
import com.coder.toolbox.CoderToolboxContext
4-
import com.coder.toolbox.sdk.CoderHttpClientBuilder
4+
import com.coder.toolbox.plugin.PluginManager
5+
import com.coder.toolbox.sdk.interceptors.Interceptors
6+
import com.coder.toolbox.sdk.proxy.applyProxySettings
57
import com.squareup.moshi.Moshi
68
import com.squareup.moshi.Types
79
import kotlinx.coroutines.Dispatchers
810
import kotlinx.coroutines.withContext
11+
import okhttp3.OkHttpClient
912
import retrofit2.Retrofit
1013
import retrofit2.converter.moshi.MoshiConverterFactory
1114
import java.nio.file.Path
@@ -40,7 +43,12 @@ class IdeFeedManager(
4043
private val feedService: JetBrainsFeedService by lazy {
4144
if (feedService != null) return@lazy feedService
4245

43-
val okHttpClient = CoderHttpClientBuilder.default(context)
46+
val okHttpClient = OkHttpClient.Builder()
47+
.applyProxySettings(context)
48+
.addInterceptor(Interceptors.userAgent(PluginManager.pluginInfo.version))
49+
.addInterceptor(Interceptors.logging(context))
50+
.retryOnConnectionFailure(true)
51+
.build()
4452

4553
val retrofit = Retrofit.Builder()
4654
.baseUrl("https://data.services.jetbrains.com/")

src/main/kotlin/com/coder/toolbox/sdk/CoderHttpClientBuilder.kt

Lines changed: 4 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@ package com.coder.toolbox.sdk
33
import com.coder.toolbox.CoderToolboxContext
44
import com.coder.toolbox.plugin.PluginManager
55
import com.coder.toolbox.sdk.interceptors.Interceptors
6+
import com.coder.toolbox.sdk.proxy.applyProxySettings
67
import com.coder.toolbox.util.CoderHostnameVerifier
78
import com.coder.toolbox.util.ReloadableTlsContext
8-
import com.jetbrains.toolbox.api.remoteDev.connection.ProxyAuth
9-
import okhttp3.Credentials
109
import okhttp3.Interceptor
1110
import okhttp3.OkHttpClient
1211

@@ -17,36 +16,13 @@ object CoderHttpClientBuilder {
1716
tlsContext: ReloadableTlsContext
1817
): OkHttpClient {
1918
val builder = OkHttpClient.Builder()
20-
21-
context.proxySettings.getProxy()?.let { proxy ->
22-
context.logger.info("proxy: $proxy")
23-
builder.proxy(proxy)
24-
} ?: context.proxySettings.getProxySelector()?.let { proxySelector ->
25-
context.logger.info("proxy selector: $proxySelector")
26-
builder.proxySelector(proxySelector)
27-
}
28-
29-
// Note: This handles only HTTP/HTTPS proxy authentication.
30-
// SOCKS5 proxy authentication is currently not supported due to limitations described in:
31-
// https://youtrack.jetbrains.com/issue/TBX-14532/Missing-proxy-authentication-settings#focus=Comments-27-12265861.0-0
32-
builder.proxyAuthenticator { _, response ->
33-
val proxyAuth = context.proxySettings.getProxyAuth()
34-
if (proxyAuth == null || proxyAuth !is ProxyAuth.Basic) {
35-
return@proxyAuthenticator null
36-
}
37-
val credentials = Credentials.basic(proxyAuth.username, proxyAuth.password)
38-
response.request.newBuilder()
39-
.header("Proxy-Authorization", credentials)
40-
.build()
41-
}
42-
43-
builder.sslSocketFactory(tlsContext.sslSocketFactory, tlsContext.trustManager)
19+
.applyProxySettings(context)
20+
.sslSocketFactory(tlsContext.sslSocketFactory, tlsContext.trustManager)
4421
.hostnameVerifier(CoderHostnameVerifier(context.settingsStore.tls.altHostname))
4522
.retryOnConnectionFailure(true)
4623

4724
interceptors.forEach { interceptor ->
4825
builder.addInterceptor(interceptor)
49-
5026
}
5127
return builder.build()
5228
}
@@ -62,4 +38,4 @@ object CoderHttpClientBuilder {
6238
ReloadableTlsContext(context.settingsStore.readOnly().tls)
6339
)
6440
}
65-
}
41+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.coder.toolbox.sdk.proxy
2+
3+
import com.coder.toolbox.CoderToolboxContext
4+
import com.jetbrains.toolbox.api.remoteDev.connection.ProxyAuth
5+
import okhttp3.Credentials
6+
import okhttp3.OkHttpClient
7+
8+
/**
9+
* Applies the user's Toolbox proxy and proxy authentication settings to this builder.
10+
*
11+
* Note: This handles only HTTP/HTTPS proxy authentication. SOCKS5 proxy authentication is currently
12+
* not supported due to limitations described in:
13+
* https://youtrack.jetbrains.com/issue/TBX-14532/Missing-proxy-authentication-settings#focus=Comments-27-12265861.0-0
14+
*/
15+
fun OkHttpClient.Builder.applyProxySettings(context: CoderToolboxContext): OkHttpClient.Builder {
16+
context.proxySettings.getProxy()?.let { proxy ->
17+
context.logger.info("proxy: $proxy")
18+
proxy(proxy)
19+
} ?: context.proxySettings.getProxySelector()?.let { proxySelector ->
20+
context.logger.info("proxy selector: $proxySelector")
21+
proxySelector(proxySelector)
22+
}
23+
24+
proxyAuthenticator { _, response ->
25+
val proxyAuth = context.proxySettings.getProxyAuth()
26+
if (proxyAuth == null || proxyAuth !is ProxyAuth.Basic) {
27+
return@proxyAuthenticator null
28+
}
29+
val credentials = Credentials.basic(proxyAuth.username, proxyAuth.password)
30+
response.request.newBuilder()
31+
.header("Proxy-Authorization", credentials)
32+
.build()
33+
}
34+
35+
return this
36+
}

0 commit comments

Comments
 (0)