From 8c5d0a43be2bdb5e084937bc543ed1cae98aedf8 Mon Sep 17 00:00:00 2001 From: Benjamin Vadon Date: Tue, 19 May 2026 09:39:34 +0200 Subject: [PATCH 1/4] refactor: Use ktor's value instead of string --- .../infomaniak/core/network/networking/HttpUtils.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Network/src/main/kotlin/com/infomaniak/core/network/networking/HttpUtils.kt b/Network/src/main/kotlin/com/infomaniak/core/network/networking/HttpUtils.kt index c6b993afc..a5d9adb7b 100644 --- a/Network/src/main/kotlin/com/infomaniak/core/network/networking/HttpUtils.kt +++ b/Network/src/main/kotlin/com/infomaniak/core/network/networking/HttpUtils.kt @@ -65,13 +65,13 @@ object HttpUtils { private fun headerMap(contentType: String?): Map = with(NetworkConfiguration) { buildMap { - put("Accept-Language", getAcceptedLanguageHeaderValue()) - put("Accept-Encoding", "gzip") - put("User-Agent", getUserAgent) - if (HttpClientConfig.cacheDir == null) put("Cache-Control", "no-cache") + put(HttpHeaders.AcceptLanguage, getAcceptedLanguageHeaderValue()) + put(HttpHeaders.AcceptEncoding, AcceptEncoding.Gzip.toString()) + put(HttpHeaders.UserAgent, getUserAgent) + if (HttpClientConfig.cacheDir == null) put(HttpHeaders.CacheControl, CacheControl.NO_CACHE) contentType?.let { - put("Accept-type", contentType) - put("Content-type", contentType) + put(HttpHeaders.Accept, contentType) + put(HttpHeaders.ContentType, contentType) } customHeaders?.forEach { customHeader -> computeIfAbsent(customHeader.key) { From 7dccc1222181a32928c07b45f285e322baab18f1 Mon Sep 17 00:00:00 2001 From: Benjamin Vadon Date: Tue, 19 May 2026 09:42:08 +0200 Subject: [PATCH 2/4] fix: Apply headers correctly, content type at it's right level, and add two methods to call headers method at the right place --- .../Ktor/src/main/kotlin/CreateHttpClient.kt | 3 +-- .../core/network/networking/HttpUtils.kt | 26 +++++++++++++++++-- .../Back/src/main/kotlin/TwoFactorAuthImpl.kt | 3 +-- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/Network/Ktor/src/main/kotlin/CreateHttpClient.kt b/Network/Ktor/src/main/kotlin/CreateHttpClient.kt index d189a491e..d964c8567 100644 --- a/Network/Ktor/src/main/kotlin/CreateHttpClient.kt +++ b/Network/Ktor/src/main/kotlin/CreateHttpClient.kt @@ -30,7 +30,6 @@ import io.ktor.client.statement.HttpResponse import io.ktor.client.statement.request import io.ktor.http.ContentType import io.ktor.http.HttpHeaders -import io.ktor.http.headers import io.ktor.serialization.kotlinx.json.json import kotlinx.serialization.SerializationException import kotlinx.serialization.json.Json @@ -53,7 +52,7 @@ fun createHttpClient( retryOnExceptionIf { _, cause -> cause !is SerializationException } } defaultRequest { - headers { applyDefaultHeaders() } + applyDefaultHeaders() } HttpResponseValidator { validateResponse { response -> diff --git a/Network/src/main/kotlin/com/infomaniak/core/network/networking/HttpUtils.kt b/Network/src/main/kotlin/com/infomaniak/core/network/networking/HttpUtils.kt index a5d9adb7b..c621dde9c 100644 --- a/Network/src/main/kotlin/com/infomaniak/core/network/networking/HttpUtils.kt +++ b/Network/src/main/kotlin/com/infomaniak/core/network/networking/HttpUtils.kt @@ -20,8 +20,16 @@ package com.infomaniak.core.network.networking import android.os.Build import com.infomaniak.core.network.NetworkConfiguration import com.infomaniak.core.network.utils.Utils.getPreferredLocaleList +import io.ktor.client.plugins.DefaultRequest.DefaultRequestBuilder +import io.ktor.client.request.HttpRequestBuilder +import io.ktor.client.request.accept +import io.ktor.client.request.headers +import io.ktor.client.utils.CacheControl import io.ktor.http.ContentType import io.ktor.http.HeadersBuilder +import io.ktor.http.HttpHeaders +import io.ktor.http.contentType +import io.ktor.http.header.AcceptEncoding import io.ktor.util.appendIfNameAbsent import okhttp3.Headers import okhttp3.Headers.Companion.toHeaders @@ -57,8 +65,22 @@ object HttpUtils { } } - fun HeadersBuilder.applyDefaultHeaders(contentType: ContentType? = ContentType.Application.Json) { - headerMap(contentType?.toString()).forEach { + fun DefaultRequestBuilder.applyDefaultHeaders(contentType: ContentType? = ContentType.Application.Json) { + contentType?.let { + contentType(contentType) + accept(contentType) + } + headers { + applyDefaultHeaders() + } + } + + fun HttpRequestBuilder.applyDefaultHeaders() { + headers { applyDefaultHeaders() } + } + + private fun HeadersBuilder.applyDefaultHeaders() { + headerMap(contentType = null).forEach { appendIfNameAbsent(it.key, it.value) } } diff --git a/TwoFactorAuth/Back/src/main/kotlin/TwoFactorAuthImpl.kt b/TwoFactorAuth/Back/src/main/kotlin/TwoFactorAuthImpl.kt index c86f200ac..5437b96e9 100644 --- a/TwoFactorAuth/Back/src/main/kotlin/TwoFactorAuthImpl.kt +++ b/TwoFactorAuth/Back/src/main/kotlin/TwoFactorAuthImpl.kt @@ -31,7 +31,6 @@ import io.ktor.client.plugins.contentnegotiation.ContentNegotiation import io.ktor.client.plugins.defaultRequest import io.ktor.client.request.delete import io.ktor.client.request.get -import io.ktor.client.request.headers import io.ktor.client.request.patch import io.ktor.client.statement.HttpResponse import io.ktor.client.statement.bodyAsText @@ -76,8 +75,8 @@ internal class TwoFactorAuthImpl( retryOnExceptionIf { _, cause -> cause !is SerializationException } } defaultRequest { + applyDefaultHeaders() url("$LOGIN_ENDPOINT_URL/api/2fa/push/") - headers { applyDefaultHeaders() } } } From ba127073415b7c39497fc214195571d1655ff8d6 Mon Sep 17 00:00:00 2001 From: Benjamin Vadon Date: Tue, 19 May 2026 10:12:56 +0200 Subject: [PATCH 3/4] chore: Remove subsequently useless content type --- .../internal/deviceinfo/AbstractDeviceInfoUpdateWorker.kt | 5 +---- .../main/kotlin/AbstractNotificationsRegistrationWorker.kt | 3 --- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/CrossAppLogin/Back/src/main/kotlin/com/infomaniak/core/crossapplogin/back/internal/deviceinfo/AbstractDeviceInfoUpdateWorker.kt b/CrossAppLogin/Back/src/main/kotlin/com/infomaniak/core/crossapplogin/back/internal/deviceinfo/AbstractDeviceInfoUpdateWorker.kt index 72c7ed0ec..ac0968cd9 100644 --- a/CrossAppLogin/Back/src/main/kotlin/com/infomaniak/core/crossapplogin/back/internal/deviceinfo/AbstractDeviceInfoUpdateWorker.kt +++ b/CrossAppLogin/Back/src/main/kotlin/com/infomaniak/core/crossapplogin/back/internal/deviceinfo/AbstractDeviceInfoUpdateWorker.kt @@ -32,9 +32,9 @@ import androidx.work.OneTimeWorkRequestBuilder import androidx.work.WorkManager import androidx.work.WorkerParameters import androidx.work.await -import com.infomaniak.core.common.DynamicLazyMap import com.infomaniak.core.auth.api.ApiRoutesCore import com.infomaniak.core.auth.room.UserDatabase +import com.infomaniak.core.common.DynamicLazyMap import com.infomaniak.core.common.autoCancelScope import com.infomaniak.core.common.cancellable import com.infomaniak.core.crossapplogin.back.CrossAppLogin @@ -44,8 +44,6 @@ import createHttpClient import io.ktor.client.HttpClient import io.ktor.client.request.post import io.ktor.client.request.setBody -import io.ktor.http.ContentType -import io.ktor.http.contentType import io.ktor.http.isSuccess import kotlinx.coroutines.Deferred import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -138,7 +136,6 @@ abstract class AbstractDeviceInfoUpdateWorker( val url = ApiRoutesCore.sendDeviceInfo() val response = httpClient.post(url) { - contentType(ContentType.Application.Json) setBody(deviceInfo) } if (response.status.isSuccess()) { diff --git a/Notifications/Registration/src/main/kotlin/AbstractNotificationsRegistrationWorker.kt b/Notifications/Registration/src/main/kotlin/AbstractNotificationsRegistrationWorker.kt index 27ee01d72..4f03a4072 100644 --- a/Notifications/Registration/src/main/kotlin/AbstractNotificationsRegistrationWorker.kt +++ b/Notifications/Registration/src/main/kotlin/AbstractNotificationsRegistrationWorker.kt @@ -36,8 +36,6 @@ import createHttpClient import io.ktor.client.request.post import io.ktor.client.request.setBody import io.ktor.client.statement.HttpResponse -import io.ktor.http.ContentType -import io.ktor.http.contentType import io.ktor.http.isSuccess import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll @@ -96,7 +94,6 @@ abstract class AbstractNotificationsRegistrationWorker( val httpClient = createHttpClient(okHttpClient) return runCatching { val response = httpClient.post("$INFOMANIAK_API_V1/devices/register") { - contentType(ContentType.Application.Json) setBody(registrationInfo) } if (response.status.isSuccess()) { From 8713a208f438be85b99b861bb054a2c5a5ac6092 Mon Sep 17 00:00:00 2001 From: Benjamin Vadon Date: Tue, 19 May 2026 13:36:25 +0200 Subject: [PATCH 4/4] refactor: Merge applyDefaultHeaders methods to one with HttpMessageBuilder context --- .../com/infomaniak/core/network/networking/HttpUtils.kt | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/Network/src/main/kotlin/com/infomaniak/core/network/networking/HttpUtils.kt b/Network/src/main/kotlin/com/infomaniak/core/network/networking/HttpUtils.kt index c621dde9c..ed7cb7f54 100644 --- a/Network/src/main/kotlin/com/infomaniak/core/network/networking/HttpUtils.kt +++ b/Network/src/main/kotlin/com/infomaniak/core/network/networking/HttpUtils.kt @@ -20,14 +20,13 @@ package com.infomaniak.core.network.networking import android.os.Build import com.infomaniak.core.network.NetworkConfiguration import com.infomaniak.core.network.utils.Utils.getPreferredLocaleList -import io.ktor.client.plugins.DefaultRequest.DefaultRequestBuilder -import io.ktor.client.request.HttpRequestBuilder import io.ktor.client.request.accept import io.ktor.client.request.headers import io.ktor.client.utils.CacheControl import io.ktor.http.ContentType import io.ktor.http.HeadersBuilder import io.ktor.http.HttpHeaders +import io.ktor.http.HttpMessageBuilder import io.ktor.http.contentType import io.ktor.http.header.AcceptEncoding import io.ktor.util.appendIfNameAbsent @@ -65,7 +64,7 @@ object HttpUtils { } } - fun DefaultRequestBuilder.applyDefaultHeaders(contentType: ContentType? = ContentType.Application.Json) { + fun HttpMessageBuilder.applyDefaultHeaders(contentType: ContentType? = ContentType.Application.Json) { contentType?.let { contentType(contentType) accept(contentType) @@ -75,10 +74,6 @@ object HttpUtils { } } - fun HttpRequestBuilder.applyDefaultHeaders() { - headers { applyDefaultHeaders() } - } - private fun HeadersBuilder.applyDefaultHeaders() { headerMap(contentType = null).forEach { appendIfNameAbsent(it.key, it.value)