Skip to content

Commit 2353213

Browse files
authored
Fix reduced timeouts being used for HTTP requests when a proxy URL is configured (#3188)
## Summary - When a proxy URL is configured, fallback URLs are disabled (`AppConfig.fallbackBaseURLs` is empty). However, the timeout manager still applied the aggressive 5s/2s timeouts meant for endpoints with fallback support. - This caused proxy requests to time out with no fallback recovery path, making the proxy unusable for slow connections. - Added `hasProxyURL` parameter to `HTTPTimeoutManager.getTimeoutForRequest()` so it uses the default timeout when a proxy is active. **Related PR:** RevenueCat/purchases-ios#6416 ## Test plan - [x] Added `getTimeoutForRequest returns DEFAULT_TIMEOUT_MS for fallback-supporting endpoint when proxy URL is set` - [x] Added `getTimeoutForRequest returns DEFAULT_TIMEOUT_MS after timeout when proxy URL is set` - [x] All 17 existing HTTPTimeoutManager tests pass
1 parent 5fed3cf commit 2353213

File tree

4 files changed

+71
-81
lines changed

4 files changed

+71
-81
lines changed

purchases/src/main/kotlin/com/revenuecat/purchases/common/HTTPClient.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,10 @@ internal class HTTPClient(
291291
debugLog { "HTTP request:\\n ${toCurlRequest(httpRequest)}" }
292292
}
293293

294-
val timeout = timeoutManager.getTimeoutForRequest(endpoint, isFallbackURL)
294+
val timeout = timeoutManager.getTimeoutForRequest(
295+
isFallback = isFallbackURL,
296+
fallbackAvailable = endpoint.supportsFallbackBaseURLs && appConfig.fallbackBaseURLs.isNotEmpty(),
297+
)
295298

296299
connection = getConnection(httpRequest, timeout)
297300
} catch (e: MalformedURLException) {

purchases/src/main/kotlin/com/revenuecat/purchases/common/networking/HTTPTimeoutManager.kt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,20 +42,19 @@ internal class HTTPTimeoutManager(
4242
private val lastTimeoutRequestTime = AtomicLong(0L)
4343

4444
/**
45-
* Calculates the timeout for a request based on the endpoint and whether it's a fallback call.
46-
* @param endpoint The endpoint being requested
45+
* Calculates the timeout for a request based on whether fallback URLs are available.
4746
* @param isFallback Whether this is a fallback request
47+
* @param fallbackAvailable Whether fallback URLs are available for this request
4848
* @return The timeout in milliseconds
4949
*/
50-
fun getTimeoutForRequest(endpoint: Endpoint, isFallback: Boolean): Long {
50+
fun getTimeoutForRequest(isFallback: Boolean, fallbackAvailable: Boolean): Long {
5151
// Check if reset is needed (10 minutes elapsed)
5252
if (shouldResetTimeout()) {
5353
resetTimeout()
5454
}
5555

5656
val timeout = when {
57-
isFallback -> DEFAULT_TIMEOUT_MS
58-
!endpoint.supportsFallbackBaseURLs -> DEFAULT_TIMEOUT_MS
57+
isFallback || !fallbackAvailable -> DEFAULT_TIMEOUT_MS
5958
lastTimeoutRequestTime.get() > 0L -> REDUCED_TIMEOUT_MS
6059
else -> SUPPORTED_FALLBACK_TIMEOUT_MS
6160
}

purchases/src/test/java/com/revenuecat/purchases/common/HTTPClientTest.kt

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,7 +1091,7 @@ internal class HTTPClientTest: BaseHTTPClientTest() {
10911091
timeoutManager.recordRequestResult(
10921092
HTTPTimeoutManager.RequestResult.TIMEOUT_ON_MAIN_BACKEND_FOR_FALLBACK_SUPPORTED_ENDPOINT
10931093
)
1094-
assertThat(timeoutManager.getTimeoutForRequest(endpoint, isFallback = false))
1094+
assertThat(timeoutManager.getTimeoutForRequest(isFallback = false, fallbackAvailable = true))
10951095
.isEqualTo(HTTPTimeoutManager.REDUCED_TIMEOUT_MS / HTTPTimeoutManager.TEST_DIVIDER)
10961096

10971097
// Setup successful response
@@ -1116,7 +1116,7 @@ internal class HTTPClientTest: BaseHTTPClientTest() {
11161116

11171117
// Verify timeout was reset
11181118
assertThat(result.responseCode).isEqualTo(RCHTTPStatusCodes.SUCCESS)
1119-
assertThat(timeoutManager.getTimeoutForRequest(endpoint, isFallback = false))
1119+
assertThat(timeoutManager.getTimeoutForRequest(isFallback = false, fallbackAvailable = true))
11201120
.isEqualTo(HTTPTimeoutManager.SUPPORTED_FALLBACK_TIMEOUT_MS / HTTPTimeoutManager.TEST_DIVIDER)
11211121
verify(exactly = 1) {
11221122
timeoutManager.recordRequestResult(HTTPTimeoutManager.RequestResult.SUCCESS_ON_MAIN_BACKEND)
@@ -1135,7 +1135,7 @@ internal class HTTPClientTest: BaseHTTPClientTest() {
11351135
client = createClient(appConfig = appConfig, timeoutManager = timeoutManager)
11361136

11371137
// Initially timeout should be default
1138-
assertThat(timeoutManager.getTimeoutForRequest(endpoint, isFallback = false))
1138+
assertThat(timeoutManager.getTimeoutForRequest(isFallback = false, fallbackAvailable = true))
11391139
.isEqualTo(HTTPTimeoutManager.SUPPORTED_FALLBACK_TIMEOUT_MS / HTTPTimeoutManager.TEST_DIVIDER)
11401140

11411141
// Setup fallback server response
@@ -1184,7 +1184,7 @@ internal class HTTPClientTest: BaseHTTPClientTest() {
11841184

11851185
// Verify HTTPClient recorded TIMEOUT_ON_MAIN_BACKEND_FOR_FALLBACK_SUPPORTED_ENDPOINT
11861186
assertThat(result.responseCode).isEqualTo(RCHTTPStatusCodes.SUCCESS)
1187-
assertThat(timeoutManager.getTimeoutForRequest(endpoint, isFallback = false))
1187+
assertThat(timeoutManager.getTimeoutForRequest(isFallback = false, fallbackAvailable = true))
11881188
.isEqualTo(HTTPTimeoutManager.REDUCED_TIMEOUT_MS / HTTPTimeoutManager.TEST_DIVIDER)
11891189
verify(exactly = 1) {
11901190
timeoutManager.recordRequestResult(
@@ -1207,7 +1207,7 @@ internal class HTTPClientTest: BaseHTTPClientTest() {
12071207
client = createClient(appConfig = appConfig, timeoutManager = timeoutManager)
12081208

12091209
// Initially timeout should be default
1210-
assertThat(timeoutManager.getTimeoutForRequest(endpoint, isFallback = false))
1210+
assertThat(timeoutManager.getTimeoutForRequest(isFallback = false, fallbackAvailable = false))
12111211
.isEqualTo(HTTPTimeoutManager.DEFAULT_TIMEOUT_MS / HTTPTimeoutManager.TEST_DIVIDER)
12121212

12131213
enqueue(
@@ -1231,10 +1231,10 @@ internal class HTTPClientTest: BaseHTTPClientTest() {
12311231
)
12321232
}.isInstanceOf(SocketTimeoutException::class.java)
12331233

1234-
// Verify HTTPClient recorded TIMEOUT_ON_MAIN_BACKEND_WITH_FALLBACK
1235-
assertThat(timeoutManager.getTimeoutForRequest(endpoint, isFallback = false))
1234+
// Verify HTTPClient recorded OTHER_RESULT (not timeout for fallback endpoint)
1235+
assertThat(timeoutManager.getTimeoutForRequest(isFallback = false, fallbackAvailable = false))
12361236
.isEqualTo(HTTPTimeoutManager.DEFAULT_TIMEOUT_MS / HTTPTimeoutManager.TEST_DIVIDER)
1237-
assertThat(timeoutManager.getTimeoutForRequest(Endpoint.GetProductEntitlementMapping, isFallback = false))
1237+
assertThat(timeoutManager.getTimeoutForRequest(isFallback = false, fallbackAvailable = true))
12381238
.isEqualTo(HTTPTimeoutManager.SUPPORTED_FALLBACK_TIMEOUT_MS / HTTPTimeoutManager.TEST_DIVIDER)
12391239
verify(exactly = 1) {
12401240
timeoutManager.recordRequestResult(HTTPTimeoutManager.RequestResult.OTHER_RESULT)
@@ -1255,7 +1255,7 @@ internal class HTTPClientTest: BaseHTTPClientTest() {
12551255
timeoutManager.recordRequestResult(
12561256
HTTPTimeoutManager.RequestResult.TIMEOUT_ON_MAIN_BACKEND_FOR_FALLBACK_SUPPORTED_ENDPOINT
12571257
)
1258-
assertThat(timeoutManager.getTimeoutForRequest(endpoint, isFallback = false))
1258+
assertThat(timeoutManager.getTimeoutForRequest(isFallback = false, fallbackAvailable = true))
12591259
.isEqualTo(HTTPTimeoutManager.REDUCED_TIMEOUT_MS / HTTPTimeoutManager.TEST_DIVIDER)
12601260

12611261
// Setup error response (non-timeout error)
@@ -1280,7 +1280,7 @@ internal class HTTPClientTest: BaseHTTPClientTest() {
12801280

12811281
// Verify HTTPClient recorded OTHER_RESULT and did NOT reset timeout
12821282
assertThat(result.responseCode).isEqualTo(RCHTTPStatusCodes.NOT_FOUND)
1283-
assertThat(timeoutManager.getTimeoutForRequest(endpoint, isFallback = false))
1283+
assertThat(timeoutManager.getTimeoutForRequest(isFallback = false, fallbackAvailable = true))
12841284
.isEqualTo(HTTPTimeoutManager.REDUCED_TIMEOUT_MS / HTTPTimeoutManager.TEST_DIVIDER)
12851285
verify(exactly = 1) {
12861286
timeoutManager.recordRequestResult(HTTPTimeoutManager.RequestResult.OTHER_RESULT)

0 commit comments

Comments
 (0)