From c372386a772bc4ced1cd36260e011e44bbc0bcfa Mon Sep 17 00:00:00 2001 From: atsunatsu Date: Tue, 8 Sep 2026 00:05:22 +0800 Subject: [PATCH] =?UTF-8?q?fix(data):=20LoTW=20sync=20resilience=20?= =?UTF-8?q?=E2=80=94=20longer=20timeouts=20(30s/120s),=20gzip=20transfer,?= =?UTF-8?q?=20follow=20redirects;=20ARRL=20server-side=20latency=20is=20th?= =?UTF-8?q?e=20bottleneck?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/data/repository/LoTWRepository.kt | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/core/data/src/main/java/com/rtbishop/look4sat/core/data/repository/LoTWRepository.kt b/core/data/src/main/java/com/rtbishop/look4sat/core/data/repository/LoTWRepository.kt index b7f9fbb8..449cc5c2 100644 --- a/core/data/src/main/java/com/rtbishop/look4sat/core/data/repository/LoTWRepository.kt +++ b/core/data/src/main/java/com/rtbishop/look4sat/core/data/repository/LoTWRepository.kt @@ -57,15 +57,25 @@ class LoTWRepository : ILoTWRepository { } try { val connection = URL("$BASE_URL?$query").openConnection() as HttpURLConnection - connection.connectTimeout = 15_000 - connection.readTimeout = 60_000 + // ARRL can be slow to accept connections from mobile networks + // (long TLS handshakes across the Pacific, occasional server-side + // queueing). 30s connect + 120s read gives the request enough + // headroom; the sync button stays disabled meanwhile so users + // see progress rather than a hung dialog. + connection.connectTimeout = 30_000 + connection.readTimeout = 120_000 connection.requestMethod = "GET" + connection.setRequestProperty("Accept-Encoding", "gzip") + connection.instanceFollowRedirects = true val code = connection.responseCode if (code !in 200..299) { connection.disconnect() return@withContext null } - val body = connection.inputStream.bufferedReader().use { it.readText() } + val stream = connection.inputStream + val body = ("gzip".equals(connection.contentEncoding, ignoreCase = true)) + .let { gz -> if (gz) java.util.zip.GZIPInputStream(stream) else stream } + .bufferedReader().use { it.readText() } connection.disconnect() if (body.contains(" password=") && !body.startsWith("ARRL")) return@withContext null parseConfirmedGrids(body)