From c666f78c2b876d9bcd54bb27264f02cdb0539241 Mon Sep 17 00:00:00 2001 From: Ian Rumac Date: Thu, 30 Apr 2026 17:27:18 +0200 Subject: [PATCH 1/2] Ensure timeout is applied at HttpUrlConenction level --- CHANGELOG.md | 1 + .../main/java/com/superwall/sdk/network/EnrichmentService.kt | 1 + .../java/com/superwall/sdk/network/NetworkRequestData.kt | 3 +++ .../main/java/com/superwall/sdk/network/NetworkService.kt | 5 +++++ .../main/java/com/superwall/sdk/network/RequestExecutor.kt | 2 ++ .../java/com/superwall/sdk/network/SubscriptionService.kt | 4 ++++ 6 files changed, 16 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 620c8b573..b12a04edb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ The changelog for `Superwall`. Also see the [releases](https://github.com/superw ## Fixes - Fix `device.appVersionPadded` and `device.sdkVersionPadded` emitting non-ASCII digits on devices whose default locale uses a non-Latin numbering system (e.g. `ar-EG`, `fa-IR`, `bn-BD`), which caused audience-rule version comparisons to misbucket affected users. +- Ensures timeout applies to HttpUrlConnection for enrichment and subscription API's ## 2.7.12 diff --git a/superwall/src/main/java/com/superwall/sdk/network/EnrichmentService.kt b/superwall/src/main/java/com/superwall/sdk/network/EnrichmentService.kt index 321b482b6..2d31635af 100644 --- a/superwall/src/main/java/com/superwall/sdk/network/EnrichmentService.kt +++ b/superwall/src/main/java/com/superwall/sdk/network/EnrichmentService.kt @@ -29,6 +29,7 @@ class EnrichmentService( "enrich", retryCount = maxRetry, body = factory.json().encodeToString(enrichmentRequest).toByteArray(), + timeout = timeout ) } } diff --git a/superwall/src/main/java/com/superwall/sdk/network/NetworkRequestData.kt b/superwall/src/main/java/com/superwall/sdk/network/NetworkRequestData.kt index cc3bf298a..40d798b2d 100644 --- a/superwall/src/main/java/com/superwall/sdk/network/NetworkRequestData.kt +++ b/superwall/src/main/java/com/superwall/sdk/network/NetworkRequestData.kt @@ -3,6 +3,7 @@ package com.superwall.sdk.network import kotlinx.serialization.Serializable import java.net.URI import java.util.* +import kotlin.time.Duration data class URLQueryItem( val name: String, @@ -16,6 +17,7 @@ class NetworkRequestData( var requestId: String = UUID.randomUUID().toString(), var isForDebugging: Boolean = false, val factory: suspend (isForDebugging: Boolean, requestId: String) -> Map, + val timeout: Duration? ) where Response : @Serializable Any { enum class HttpMethod( val method: String, @@ -51,5 +53,6 @@ class NetworkRequestData( requestId = requestId, isForDebugging = isForDebugging, factory = factory, + timeout = timeout ) } diff --git a/superwall/src/main/java/com/superwall/sdk/network/NetworkService.kt b/superwall/src/main/java/com/superwall/sdk/network/NetworkService.kt index bd37e59f5..bfb3e54ea 100644 --- a/superwall/src/main/java/com/superwall/sdk/network/NetworkService.kt +++ b/superwall/src/main/java/com/superwall/sdk/network/NetworkService.kt @@ -5,6 +5,7 @@ import com.superwall.sdk.network.NetworkRequestData.HttpMethod import com.superwall.sdk.network.session.CustomHttpUrlConnection import kotlinx.serialization.Serializable import java.util.UUID +import kotlin.time.Duration abstract class NetworkService { abstract val customHttpUrlConnection: CustomHttpUrlConnection @@ -23,6 +24,7 @@ abstract class NetworkService { isForDebugging: Boolean = false, requestId: String = UUID.randomUUID().toString(), retryCount: Int = NetworkConsts.retryCount(), + timeout: Duration? = null ): Either where T : @Serializable Any = customHttpUrlConnection.request( buildRequestData = { @@ -37,6 +39,7 @@ abstract class NetworkService { ), method = HttpMethod.GET, factory = this::makeHeaders, + timeout = timeout ) }, retryCount = retryCount, @@ -48,6 +51,7 @@ abstract class NetworkService { body: ByteArray? = null, requestId: String = UUID.randomUUID().toString(), retryCount: Int = 6, + timeout: Duration? = null ): Either where T : @Serializable Any = customHttpUrlConnection.request( buildRequestData = { @@ -62,6 +66,7 @@ abstract class NetworkService { ), method = HttpMethod.POST, factory = this::makeHeaders, + timeout = timeout ) }, retryCount = retryCount, diff --git a/superwall/src/main/java/com/superwall/sdk/network/RequestExecutor.kt b/superwall/src/main/java/com/superwall/sdk/network/RequestExecutor.kt index cd0a40e29..3d68fb709 100644 --- a/superwall/src/main/java/com/superwall/sdk/network/RequestExecutor.kt +++ b/superwall/src/main/java/com/superwall/sdk/network/RequestExecutor.kt @@ -143,6 +143,8 @@ class RequestExecutor( if (components?.bodyData != null) { connection.doInput = true } + connection.connectTimeout = timeout?.inWholeMilliseconds?.toInt()?:0 + connection.readTimeout = timeout?.inWholeMilliseconds?.toInt()?:0 if (components?.bodyData != null) { val outputStream = connection.outputStream diff --git a/superwall/src/main/java/com/superwall/sdk/network/SubscriptionService.kt b/superwall/src/main/java/com/superwall/sdk/network/SubscriptionService.kt index 98dc67288..058026625 100644 --- a/superwall/src/main/java/com/superwall/sdk/network/SubscriptionService.kt +++ b/superwall/src/main/java/com/superwall/sdk/network/SubscriptionService.kt @@ -13,6 +13,7 @@ import com.superwall.sdk.store.testmode.models.SuperwallProductsResponse import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonElement +import kotlin.time.Duration.Companion.seconds class SubscriptionService( override val host: String, @@ -58,6 +59,7 @@ class SubscriptionService( attributionProps, ), ).toByteArray(), + timeout = 10.seconds ) suspend fun webEntitlementsByUserId( @@ -66,12 +68,14 @@ class SubscriptionService( ) = get( "users/${userId?.value ?: deviceId.value}/entitlements", queryItems = listOf(URLQueryItem("deviceId", deviceId.value)), + timeout = 5.seconds ) suspend fun webEntitlementsByDeviceId(deviceId: DeviceVendorId) = get( "users/${deviceId.value}/entitlements", queryItems = listOf(URLQueryItem("deviceId", deviceId.value)), + timeout = 5.seconds ) suspend fun getProducts() = get("products") From ce72691ad337269c21f5ce2100a4aa71dfcbad58 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 30 Apr 2026 16:06:55 +0000 Subject: [PATCH 2/2] Update coverage badge [skip ci] --- .github/badges/jacoco.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/badges/jacoco.svg b/.github/badges/jacoco.svg index 2554fd02d..6adbbd285 100644 --- a/.github/badges/jacoco.svg +++ b/.github/badges/jacoco.svg @@ -1 +1 @@ -coverage39.4% \ No newline at end of file +coverage39.3% \ No newline at end of file