Skip to content

Commit f0c3268

Browse files
committed
Refac host override to avoid relying on DefaultRequest
1 parent ffdbaac commit f0c3268

File tree

1 file changed

+26
-26
lines changed

1 file changed

+26
-26
lines changed

src/commonMain/kotlin/org/hildan/chrome/devtools/protocol/ChromeDPClient.kt

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package org.hildan.chrome.devtools.protocol
22

33
import io.ktor.client.*
44
import io.ktor.client.call.*
5-
import io.ktor.client.plugins.*
65
import io.ktor.client.plugins.contentnegotiation.*
76
import io.ktor.client.plugins.websocket.*
87
import io.ktor.client.request.*
@@ -14,20 +13,13 @@ import kotlinx.serialization.Serializable
1413
import kotlinx.serialization.json.Json
1514
import org.hildan.chrome.devtools.sessions.*
1615

17-
private val DEFAULT_HTTP_CLIENT by lazy { createHttpClient(overrideHostHeader = false) }
16+
private val DEFAULT_HTTP_CLIENT by lazy { createHttpClient() }
1817

19-
private val DEFAULT_HTTP_CLIENT_WITH_HOST_OVERRIDE by lazy { createHttpClient(overrideHostHeader = true) }
20-
21-
private fun createHttpClient(overrideHostHeader: Boolean) = HttpClient {
18+
private fun createHttpClient() = HttpClient {
2219
install(ContentNegotiation) {
2320
json(Json { ignoreUnknownKeys = true })
2421
}
2522
install(WebSockets)
26-
if (overrideHostHeader) {
27-
install(DefaultRequest) {
28-
headers["Host"] = "localhost"
29-
}
30-
}
3123
}
3224

3325
/**
@@ -42,14 +34,12 @@ private fun createHttpClient(overrideHostHeader: Boolean) = HttpClient {
4234
*
4335
* ## Host override
4436
*
45-
* Chrome doesn't accept a `Host` header that is not an IP nor `localhost`, but in some environments it might be hard
46-
* to provide this (e.g. docker services in a docker swarm, communicating using service names).
37+
* Chrome doesn't accept a `Host` header that is not an IP nor `localhost`, but in some environments the URL has to
38+
* have a named host (e.g. docker services in a docker swarm, communicating using service names).
4739
*
48-
* To work around this problem, simply set [overrideHostHeader] to true.
49-
* This overrides the `Host` header to "localhost" in the HTTP requests to the Chrome debugger to make it happy, and
50-
* also replaces the host in subsequent web socket URLs (returned by Chrome) by the initial host provided in
51-
* [remoteDebugUrl].
52-
* This is necessary because Chrome uses the `Host` header to build these URLs, and it would be incorrect to keep this.
40+
* Enabling [overrideHostHeader] works around this problem by setting the `Host` header to "localhost" in the HTTP
41+
* requests to the Chrome debugger. It also restores the original host in URLs that are returned by Chrome
42+
* (Chrome uses the `Host` header to build the URLs that it returns, so they would contain `localhost` otherwise).
5343
*/
5444
class ChromeDPClient(
5545
/**
@@ -74,7 +64,7 @@ class ChromeDPClient(
7464
* You should only need to override it to work around an issue in the client's configuration/behaviour, or if you
7565
* want to also reuse your own client here.
7666
*/
77-
private val httpClient: HttpClient = if (overrideHostHeader) DEFAULT_HTTP_CLIENT_WITH_HOST_OVERRIDE else DEFAULT_HTTP_CLIENT,
67+
private val httpClient: HttpClient = DEFAULT_HTTP_CLIENT,
7868
) {
7969
init {
8070
require(remoteDebugUrl.startsWith("http://") || remoteDebugUrl.startsWith("https://")) {
@@ -86,19 +76,17 @@ class ChromeDPClient(
8676
/**
8777
* Fetches the browser version metadata via the debugger's HTTP API.
8878
*/
89-
suspend fun version(): ChromeVersion =
90-
httpClient.get("$remoteDebugUrl/json/version").body<ChromeVersion>().fixHost()
79+
suspend fun version(): ChromeVersion = httpGet("/json/version").body<ChromeVersion>().fixHost()
9180

9281
/**
9382
* Fetches the current Chrome DevTools Protocol definition, as a JSON string.
9483
*/
95-
suspend fun protocolJson(): String = httpClient.get("$remoteDebugUrl/json/protocol").bodyAsText()
84+
suspend fun protocolJson(): String = httpGet("/json/protocol").bodyAsText()
9685

9786
/**
9887
* Fetches the list of all available web socket targets (e.g. browser tabs).
9988
*/
100-
suspend fun targets(): List<ChromeDPTarget> =
101-
httpClient.get("$remoteDebugUrl/json/list").body<List<ChromeDPTarget>>().map { it.fixHost() }
89+
suspend fun targets(): List<ChromeDPTarget> = httpGet("/json/list").body<List<ChromeDPTarget>>().map { it.fixHost() }
10290

10391
/**
10492
* Opens a new tab, and returns the websocket target data for the new tab.
@@ -114,17 +102,17 @@ class ChromeDPClient(
114102
),
115103
)
116104
suspend fun newTab(url: String = "about:blank"): ChromeDPTarget =
117-
httpClient.put("$remoteDebugUrl/json/new?$url").body<ChromeDPTarget>().fixHost()
105+
httpPut("/json/new?$url").body<ChromeDPTarget>().fixHost()
118106

119107
/**
120108
* Brings the page identified by the given [targetId] into the foreground (activates a tab).
121109
*/
122-
suspend fun activateTab(targetId: String): String = httpClient.get("$remoteDebugUrl/json/activate/$targetId").body()
110+
suspend fun activateTab(targetId: String): String = httpGet("/json/activate/$targetId").body()
123111

124112
/**
125113
* Closes the page identified by [targetId].
126114
*/
127-
suspend fun closeTab(targetId: String): String = httpClient.get("$remoteDebugUrl/json/close/$targetId").body()
115+
suspend fun closeTab(targetId: String): String = httpGet("/json/close/$targetId").body()
128116

129117
/**
130118
* Closes all targets.
@@ -156,6 +144,18 @@ class ChromeDPClient(
156144
return httpClient.chromeWebSocket(browserDebuggerUrl)
157145
}
158146

147+
private suspend fun httpPut(endpoint: String): HttpResponse = httpClient.put(remoteDebugUrl + endpoint) {
148+
if (overrideHostHeader) {
149+
headers["Host"] = "localhost"
150+
}
151+
}
152+
153+
private suspend fun httpGet(endpoint: String): HttpResponse = httpClient.get(remoteDebugUrl + endpoint) {
154+
if (overrideHostHeader) {
155+
headers["Host"] = "localhost"
156+
}
157+
}
158+
159159
private fun ChromeVersion.fixHost() = when {
160160
overrideHostHeader -> copy(webSocketDebuggerUrl = webSocketDebuggerUrl.fixHost())
161161
else -> this

0 commit comments

Comments
 (0)