fix(blossom-bridge): pick rightmost sha256 segment in URL path
CDNs like share.yabu.me serve blobs under `<cache-prefix-sha>/<blob-sha>.<ext>` where both path segments are 64-char hex. The bridge previously locked onto the first match (the cache prefix), dropping the blob segment from `xs` and asking the local cache for a non-existent blob. Walking the path right-to-left makes the rightmost sha — the one that carries the file extension — win, while the prefix segments stay in `xs` so the cache can fetch upstream on miss. Behaviour is unchanged when the path has a single sha; tests cover the new two-hash layout in both the Coil-model path and the OkHttp interceptor path.
This commit is contained in:
+7
-2
@@ -72,8 +72,13 @@ class LocalBlossomCacheRedirectInterceptor(
|
||||
}
|
||||
|
||||
private fun findSha256AndExtensionInPath(url: HttpUrl): Triple<Int, String, String>? {
|
||||
url.pathSegments.forEachIndexed { index, segment ->
|
||||
val match = SHA256_SEGMENT_REGEX.find(segment) ?: return@forEachIndexed
|
||||
// Walk segments right-to-left so CDNs that put a cache prefix (itself a
|
||||
// 64-char hex segment) ahead of the blob hash — e.g.
|
||||
// `https://share.yabu.me/<prefix>/<sha>.webp` — still resolve to the
|
||||
// blob and leave the prefix in `xs`.
|
||||
for (index in url.pathSegments.indices.reversed()) {
|
||||
val segment = url.pathSegments[index]
|
||||
val match = SHA256_SEGMENT_REGEX.find(segment) ?: continue
|
||||
val sha = match.value.lowercase()
|
||||
val ext = guessExtensionFrom(segment, sha) ?: "bin"
|
||||
return Triple(index, sha, ext)
|
||||
|
||||
+15
@@ -132,6 +132,21 @@ class LocalBlossomCacheRedirectInterceptorTest {
|
||||
response.close()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun bridgeOnPicksRightmostShaWhenPathHasTwoHashes() {
|
||||
// share.yabu.me layout: <cache-prefix-sha>/<blob-sha>.<ext>
|
||||
val prefix = "84b0c46ab699ac35eb2ca286470b85e081db2087cdef63932236c397417782f5"
|
||||
val blob = "28fa4d999af6ae3e4e11bfc2727130ef1b3a13cc0f981e5a93c3996cb2f524e5"
|
||||
val interceptor = LocalBlossomCacheRedirectInterceptor { true }
|
||||
val captured = mutableListOf<String>()
|
||||
val response = interceptor.intercept(fakeChain("https://share.yabu.me/$prefix/$blob.webp", captured))
|
||||
assertEquals(
|
||||
"http://127.0.0.1:24242/$blob.webp?xs=https%3A%2F%2Fshare.yabu.me%2F$prefix",
|
||||
captured.single(),
|
||||
)
|
||||
response.close()
|
||||
}
|
||||
|
||||
private fun fakeChain(
|
||||
url: String,
|
||||
captured: MutableList<String>,
|
||||
|
||||
Reference in New Issue
Block a user