From 3739951b360f9f2e10727cc9dd2e587aabcc791d Mon Sep 17 00:00:00 2001 From: Jason Date: Thu, 27 Nov 2025 19:10:01 -0800 Subject: [PATCH] fix(kobo): proxy 401 errors on initialization Co-authored-by: Gauthier Roebroeck --- .../komga/infrastructure/kobo/KoboProxy.kt | 40 +++++++++---------- .../interfaces/api/kobo/KoboController.kt | 5 ++- 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/komga/src/main/kotlin/org/gotson/komga/infrastructure/kobo/KoboProxy.kt b/komga/src/main/kotlin/org/gotson/komga/infrastructure/kobo/KoboProxy.kt index 70ea3080c..2df061ecb 100644 --- a/komga/src/main/kotlin/org/gotson/komga/infrastructure/kobo/KoboProxy.kt +++ b/komga/src/main/kotlin/org/gotson/komga/infrastructure/kobo/KoboProxy.kt @@ -30,28 +30,24 @@ class KoboProxy( private val komgaSyncTokenGenerator: KomgaSyncTokenGenerator, private val komgaSettingsProvider: KomgaSettingsProvider, ) { - private val koboApiClient: RestClient + private val koboApiClient: RestClient = + RestClient + .builder() + .uriBuilderFactory( + DefaultUriBuilderFactory("https://storeapi.kobo.com") + .apply { + this.encodingMode = DefaultUriBuilderFactory.EncodingMode.NONE + }, + ).requestFactory( + ClientHttpRequestFactoryBuilder.reactor().build( + ClientHttpRequestFactorySettings + .defaults() + .withReadTimeout(1.minutes.toJavaDuration()) + .withConnectTimeout(1.minutes.toJavaDuration()), + ), + ).build() - init { - val uriBuilderFactory = DefaultUriBuilderFactory("https://storeapi.kobo.com") - uriBuilderFactory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.NONE) - - koboApiClient = - RestClient - .builder() - .uriBuilderFactory( - uriBuilderFactory, - ).requestFactory( - ClientHttpRequestFactoryBuilder.reactor().build( - ClientHttpRequestFactorySettings - .defaults() - .withReadTimeout(1.minutes.toJavaDuration()) - .withConnectTimeout(1.minutes.toJavaDuration()), - ), - ).build() - } - - private val pathRegex = """\/kobo\/[-\w]*(.*)""".toRegex() + private val pathRegex = """/kobo/[-\w]*(.*)""".toRegex() private val headersOutInclude = setOf( @@ -120,7 +116,7 @@ class KoboProxy( }.apply { if (body != null) body(body) } .retrieve() .onStatus(HttpStatusCode::isError) { _, response -> - logger.debug { "Kobo response: $response" } + logger.debug { "Kobo response: ${response.statusCode}: ${response.body.bufferedReader().use { it.readText() }}" } throw ResponseStatusException(response.statusCode, response.statusText) }.toEntity() diff --git a/komga/src/main/kotlin/org/gotson/komga/interfaces/api/kobo/KoboController.kt b/komga/src/main/kotlin/org/gotson/komga/interfaces/api/kobo/KoboController.kt index f92fba46b..53eb11a6b 100644 --- a/komga/src/main/kotlin/org/gotson/komga/interfaces/api/kobo/KoboController.kt +++ b/komga/src/main/kotlin/org/gotson/komga/interfaces/api/kobo/KoboController.kt @@ -194,6 +194,7 @@ class KoboController( try { koboProxy.proxyCurrentRequest().body?.get("Resources") } catch (e: Exception) { + if (e is ResponseStatusException && e.statusCode == HttpStatus.UNAUTHORIZED) throw e logger.warn { "Failed to get response from Kobo /v1/initialization, fallback to noproxy" } null } ?: koboProxy.nativeKoboResources @@ -233,7 +234,7 @@ class KoboController( ): Any { try { return koboProxy.proxyCurrentRequest(body) - } catch (e: Exception) { + } catch (_: Exception) { logger.warn { "Failed to get response from Kobo /v1/auth/device, fallback to noproxy" } } @@ -395,7 +396,7 @@ class KoboController( addAll( // changed books are also passed as changed reading state because Kobo does not process ChangedEntitlement even if it contains a ReadingState (booksChanged.content + changedReadingState.content).mapNotNull { book -> - readProgress[book.bookId]?.let { it -> + readProgress[book.bookId]?.let { ChangedReadingStateDto( WrappedReadingStateDto( it.toDto(),