https://kotlinlang.org logo
#ktor
Title
# ktor
v

Václav Benes

03/06/2024, 7:54 PM
Hi, I'd like to ask about Ktor Wasm client / Ktor server and Nginx Proxy manager. I build KMM project with wasm target and ktor server as different module. I serve build html/js/wasm resources to ktor server. I use nginx proxy for ssl , where I map my server to specific hostname. There is an issue , where ktor client accessing http instead of https. Is there nice way how to do it?
Copy code
HttpClient: REQUEST: <http://localhost:8080/api>
METHOD: HttpMethod(value=GET)
COMMON HEADERS
-> Accept: application/json
-> Accept-Charset: UTF-8
CONTENT HEADERS
-> Content-Length: 0
composeApp.uninstantiated.mjs:5846 
        
        
       GET <http://localhost:8080/api> net::ERR_CONNECTION_REFUSED
io.ktor.client.fetch.fetch_$external_fun @ composeApp.uninstantiated.mjs:5846
$func12705 @ composeApp.wasm:0x2d9cb4
$func12710 @ composeApp.wasm:0x2da6df
$func12317 @ composeApp.wasm:0x2cf011
$func12315 @ composeApp.wasm:0x2ceede
$func13384 @ composeApp.wasm:0x2fc0a7
$func12316 @ composeApp.wasm:0x2ceeed
$func2252 @ composeApp.wasm:0x1a5a15
$func2241 @ composeApp.wasm:0x1a56cf
$func3043 @ composeApp.wasm:0x1c1da0
$func3210 @ composeApp.wasm:0x1c46bb
$func3231 @ composeApp.wasm:0x1c4a8a
$func3232 @ composeApp.wasm:0x1c4a92
$__callFunction____->Unit_ @ composeApp.wasm:0x1abc6b
eval @ composeApp.uninstantiated.mjs:118
Promise.then (async)
eval @ composeApp.uninstantiated.mjs:4497
kotlinx.coroutines.__callJsClosure_(()->Unit) @ composeApp.uninstantiated.mjs:4498
$func3239 @ composeApp.wasm:0x1c4afe
$func3240 @ composeApp.wasm:0x1c4b06
$func3235 @ composeApp.wasm:0x1c4ac1
$func3209 @ composeApp.wasm:0x1c4633
$func3164 @ composeApp.wasm:0x1c4092
$func3149 @ composeApp.wasm:0x1c3d07
$func3039 @ composeApp.wasm:0x1c1a67
$func3054 @ composeApp.wasm:0x1c2201
$func2550 @ composeApp.wasm:0x1b13d8
$func2558 @ composeApp.wasm:0x1b1a86
$func2559 @ composeApp.wasm:0x1b1ab1
$main @ composeApp.wasm:0x2f7bf2
$_initialize @ composeApp.wasm:0x2fb933
instantiate @ composeApp.uninstantiated.mjs:5976
await in instantiate (async)
eval @ composeApp.mjs:3
__webpack_require__.a @ composeApp.js:123
eval @ composeApp.mjs:1
./kotlin/composeApp.mjs @ composeApp.js:29
__webpack_require__ @ composeApp.js:63
(anonymous) @ composeApp.js:367
(anonymous) @ composeApp.js:370
webpackUniversalModuleDefinition @ composeApp.js:17
(anonymous) @ composeApp.js:18
composeApp.uninstantiated.mjs:121 HttpClient: REQUEST <http://localhost:8080/api> failed with exception: Error: Fail to fetch
a

Aleksei Tirman [JB]

03/06/2024, 8:42 PM
Can you show how you make the request to
/api
?
v

Václav Benes

03/06/2024, 9:31 PM
I tried multiple things. This is working but not ideal 🙂 Client:
Copy code
fun getClient(host: String = "localhost", protocol: URLProtocol = URLProtocol.HTTP): HttpClient {
    return HttpClient {
        install(ContentNegotiation) {
            json()
        }
        install(HttpCache)
        install(Logging)
        defaultRequest {
            url {
                this.protocol = protocol
                this.host = host

            }
        }
    }
}

@OptIn(DelicateCoroutinesApi::class)
@Composable
fun app() {
    // TODO: not ideal

    GlobalScope.launch {
        val client = getClient(
            host = document.location?.host ?: "localhost",
            protocol = getProtocol(document.location?.protocol ?: "http")
        )
        UserRepository(client).getUsers()
    }
Server
Copy code
const val HOST = "0.0.0.0"
const val SERVER_PORT = 8080

fun main() {
    embeddedServer(
        Netty,
        port = SERVER_PORT,
        host = HOST,
        module = Application::module,
    ).start(wait = true)
}

fun Application.configureSerialization() {
    install(ContentNegotiation) {
        json()
    }
    install(CORS) {
        allowHeader(HttpHeaders.ContentType)
        allowMethod(HttpMethod.Get)
        allowMethod(HttpMethod.Post)
        allowMethod(HttpMethod.Delete)
        anyHost()
    }
}
a

Aleksei Tirman [JB]

03/07/2024, 8:24 AM
As I can see, either the
getProtocol(document.location?.protocol ?: "http")
call returns HTTP protocol or the protocol is overridden to HTTP in the
getUsers
method.
v

Václav Benes

03/07/2024, 8:37 AM
This example works in both cases for http and https that is not the case. Before I hard coded
localhost
and port
8080
on the client side and it worked locally, but after I added a proxy. It stopped. I'm just trying to find a way to do it without accessing dom.
31 Views