Skip to content

Commit ccd7723

Browse files
committed
When using offline caching, don't mask HTTP redirects. This lets Turbo see the resulting redirect and properly propose a redirect "replace" visit.
1 parent f2105b1 commit ccd7723

File tree

2 files changed

+35
-10
lines changed

2 files changed

+35
-10
lines changed

turbo/src/main/kotlin/dev/hotwire/turbo/http/TurboHttpRepository.kt

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ internal class TurboHttpRepository(private val coroutineScope: CoroutineScope) {
2828

2929
data class Result(
3030
val response: WebResourceResponse?,
31-
val offline: Boolean
31+
val offline: Boolean,
32+
val redirectToLocation: String? = null
3233
)
3334

3435
internal fun preCache(
@@ -74,15 +75,26 @@ internal class TurboHttpRepository(private val coroutineScope: CoroutineScope) {
7475
return try {
7576
val response = issueRequest(resourceRequest)
7677

78+
// Cache based on the response's request url, which may have been a redirect
79+
val responseUrl = response?.request?.url.toString()
80+
val isRedirect = url != responseUrl
81+
7782
// Let the app cache the response
7883
val resourceResponse = resourceResponse(response)
7984
val cachedResponse = resourceResponse?.let {
80-
requestHandler.cacheResponse(url, it)
85+
requestHandler.cacheResponse(responseUrl, it)
8186
}
8287

83-
Result(cachedResponse ?: resourceResponse, false)
88+
Result(
89+
response = cachedResponse ?: resourceResponse,
90+
offline = false,
91+
redirectToLocation = if (isRedirect) responseUrl else null
92+
)
8493
} catch (e: IOException) {
85-
Result(requestHandler.getCachedResponse(url, allowStaleResponse = true), true)
94+
Result(
95+
response = requestHandler.getCachedResponse(url, allowStaleResponse = true),
96+
offline = true
97+
)
8698
}
8799
}
88100

turbo/src/main/kotlin/dev/hotwire/turbo/session/TurboSession.kt

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -657,15 +657,28 @@ class TurboSession internal constructor(
657657
}
658658

659659
val url = request.url.toString()
660+
val isCurrentVisitRequest = url == currentVisit?.location
660661
val result = httpRepository.fetch(requestHandler, request)
661662

662-
currentVisit?.let { visit ->
663-
if (visit.location == url) {
664-
visit.completedOffline = result.offline
665-
}
663+
return if (isCurrentVisitRequest && result.redirectToLocation != null) {
664+
// Let Turbo see the redirect, so a redirect "replace" visit can be proposed
665+
logEvent("shouldInterceptRequest",
666+
"location" to url,
667+
"redirectToLocation" to result.redirectToLocation,
668+
"statusCode" to (result.response?.statusCode ?: "<none>")
669+
)
670+
null
671+
} else if (isCurrentVisitRequest) {
672+
logEvent("shouldInterceptRequest",
673+
"location" to url,
674+
"statusCode" to (result.response?.statusCode ?: "<none>"),
675+
"completedOffline" to result.offline
676+
)
677+
currentVisit?.completedOffline = result.offline
678+
result.response
679+
} else {
680+
result.response
666681
}
667-
668-
return result.response
669682
}
670683

671684
override fun onReceivedError(view: WebView, request: WebResourceRequest, error: WebResourceErrorCompat) {

0 commit comments

Comments
 (0)