Are there new Proguard rules for 3.0.0? I was tryi...
# ktor
g
Are there new Proguard rules for 3.0.0? I was trying out SSE in 3.0.0 beta 1, and all of my non-SSE HTTP calls silently fail on Android at the moment. I didn’t have any issues in debug mode, but building in release mode to speed up the Compose UI seems to break everything.
Log:
Copy code
Encountered unknown error: io.ktor.client.call.NoTransformationFoundException: Expected response body of the type 'class <my data class annotated with @Serializable> (Kotlin reflection is not available)' but was 'class io.ktor.utils.io.ByteBufferChannel (Kotlin reflection is not available)'
                                                                                                    In response from `<my url>`
Response status `400 `
Response header `ContentType: text/plain` 
Request header `Accept: application/json`
I have one client for SSE and one for normal HTTP calls. My non-SSE client is configured like this on Android:
Copy code
HttpClient(OkHttp) {
    install(ContentNegotiation) {
        json(json = inject())
    }
    install(HttpTimeout)
}
c
JSON negations will only work with response header content type json. You need to configure the plugin if it should also be done with text content type.
4** usually don’t provide json bodies thought
g
Let me double check really quick, but I’m pretty sure the server is sending a json content type. I forgot about adding additional content types to the content negotiation plugin, though. That’ll probably get everything working even if there is an issue with the ktor or my server. Thanks!
Interesting. I got on the server and it looks like the plain text response type is actually because it is sending an error message. The request is supposed to attach a cookie, but the server never receives said cookie for some reason.
Copy code
<http://client.post|client.post> {
    method = <http://HttpMethod.Post|HttpMethod.Post>
    url(urlString = "$apiBaseUrl$ENDPOINT_PATH")
    contentType(type = ContentType.Application.Json)
    setBody(body = request)
    setCookie(name = "uuid_guest", value = requestData.guestId)
}
c
in the client you don’t
setCookie
you just add to the the headers via https://ktor.io/docs/request.html#cookies
g
Oh sorry, I forgot I use a wrapper function around my cookies. Set cookie just calls the built-in
cookie
function that does the header stuff under the hood:
Copy code
private fun HttpMessageBuilder.setCookie(
        name: String,
        value: String,
    ) {
        val now = Clock.System.now().toEpochMilliseconds()
        cookie(
            name = name,
            value = value,
            expires = GMTDate(timestamp = now + NINETY_DAYS_MS),
            domain = apiCookieDomain,
            secure = true,
            httpOnly = false,
        )
    }
The real call without my helper functions is:
Copy code
<http://client.post|client.post> {
    method = <http://HttpMethod.Post|HttpMethod.Post>
    url(urlString = "$apiBaseUrl$ENDPOINT_PATH")
    contentType(type = ContentType.Application.Json)
    setBody(body = request)
    cookie(
        name = "uuid_guest",
        value = requestData.guestId,
        expires = GMTDate(timestamp = now + NINETY_DAYS_MS),
        domain = apiCookieDomain,
        secure = true,
        httpOnly = false,
    )
}
Oh nevermind I guess. It started sending the cookie in release builds 🤔 . Maybe I just needed to gradle clean first.