| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- package com.example.modifier.http
- import com.example.modifier.http.response.ErrorResponse
- import com.example.modifier.repo.AppPrefsRepo
- import io.ktor.client.HttpClient
- import io.ktor.client.call.body
- import io.ktor.client.engine.okhttp.OkHttp
- import io.ktor.client.network.sockets.ConnectTimeoutException
- import io.ktor.client.network.sockets.SocketTimeoutException
- import io.ktor.client.plugins.ClientRequestException
- import io.ktor.client.plugins.HttpRequestRetry
- import io.ktor.client.plugins.HttpRequestTimeoutException
- import io.ktor.client.plugins.HttpResponseValidator
- import io.ktor.client.plugins.HttpSend
- import io.ktor.client.plugins.HttpTimeout
- import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
- import io.ktor.client.plugins.defaultRequest
- import io.ktor.client.plugins.logging.LogLevel
- import io.ktor.client.plugins.logging.Logging
- import io.ktor.client.plugins.resources.Resources
- import io.ktor.client.utils.unwrapCancellationException
- import io.ktor.serialization.kotlinx.json.json
- import kotlinx.coroutines.CancellationException
- import kotlinx.serialization.ExperimentalSerializationApi
- import kotlinx.serialization.json.Json
- private fun Throwable.isTimeoutException(): Boolean {
- val exception = unwrapCancellationException()
- return exception is HttpRequestTimeoutException ||
- exception is ConnectTimeoutException ||
- exception is SocketTimeoutException
- }
- @OptIn(ExperimentalSerializationApi::class)
- var ktorClient = HttpClient(OkHttp) {
- defaultRequest {
- val server = AppPrefsRepo.instance.appPrefs.value.server
- url(server.endsWith("/").let {
- if (it) server else "$server/"
- })
- }
- install(HttpSend) {
- maxSendCount = 200
- }
- install(Logging) {
- level = LogLevel.INFO
- }
- install(HttpRequestRetry) {
- maxRetries = 3
- retryOnExceptionIf { _, cause ->
- when {
- cause.isTimeoutException() -> true
- cause is CancellationException -> false
- else -> true
- }
- }
- retryIf { _, response ->
- response.status.value.let {
- when (it) {
- 425, 429, 502, 503, 504 -> true
- else -> false
- }
- }
- }
- delayMillis { 1000 }
- }
- install(HttpTimeout) {
- requestTimeoutMillis = 30 * 1000
- socketTimeoutMillis = 30 * 1000
- }
- install(Resources)
- install(ContentNegotiation) {
- json(Json {
- prettyPrint = true
- isLenient = true
- ignoreUnknownKeys = true
- explicitNulls = false
- })
- }
- HttpResponseValidator {
- validateResponse { response ->
- if (response.status.value !in 200..299) {
- val error = response.body<ErrorResponse>()
- throw ClientRequestException(response, error.message ?: "Unknown error")
- }
- }
- }
- }
|