perf(cdndownloader): bolt http resolver

This commit is contained in:
rhunk 2023-05-28 23:50:33 +02:00
parent 0f711b698e
commit c1a01bf169
2 changed files with 16 additions and 65 deletions

View File

@ -377,7 +377,7 @@ class MediaDownloader : Feature("MediaDownloader", loadParams = FeatureLoadParam
//download the message content //download the message content
try { try {
context.longToast("Querying $urlKey. It might take a while...") context.shortToast("Querying $urlKey")
val downloadedMedia = MediaDownloaderHelper.downloadMediaFromKey(urlKey, canMergeOverlay(), isPreviewMode) { val downloadedMedia = MediaDownloaderHelper.downloadMediaFromKey(urlKey, canMergeOverlay(), isPreviewMode) {
EncryptionUtils.decryptInputStreamFromArroyo(it, contentType, messageReader) EncryptionUtils.decryptInputStreamFromArroyo(it, contentType, messageReader)
}[MediaType.ORIGINAL] ?: throw Exception("Failed to download media for key $urlKey") }[MediaType.ORIGINAL] ?: throw Exception("Failed to download media for key $urlKey")

View File

@ -1,64 +1,21 @@
package me.rhunk.snapenhance.util.download package me.rhunk.snapenhance.util.download
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.joinAll
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import me.rhunk.snapenhance.Constants import me.rhunk.snapenhance.Constants
import me.rhunk.snapenhance.util.protobuf.ProtoWriter
import java.io.InputStream import java.io.InputStream
import java.net.URL import java.net.URL
import java.util.Base64
import javax.net.ssl.HttpsURLConnection import javax.net.ssl.HttpsURLConnection
object CdnDownloader { object CdnDownloader {
const val BOLT_CDN_U = "https://bolt-gcdn.sc-cdn.net/u/" private const val BOLT_HTTP_RESOLVER_URL = "https://aws.api.snapchat.com/bolt-http"
const val BOLT_CDN_X = "https://bolt-gcdn.sc-cdn.net/x/"
const val CF_ST_CDN_D = "https://cf-st.sc-cdn.net/d/" const val CF_ST_CDN_D = "https://cf-st.sc-cdn.net/d/"
const val CF_ST_CDN_F = "https://cf-st.sc-cdn.net/f/"
const val CF_ST_CDN_H = "https://cf-st.sc-cdn.net/h/"
const val CF_ST_CDN_G = "https://cf-st.sc-cdn.net/g/"
const val CF_ST_CDN_O = "https://cf-st.sc-cdn.net/o/"
const val CF_ST_CDN_I = "https://cf-st.sc-cdn.net/i/"
const val CF_ST_CDN_J = "https://cf-st.sc-cdn.net/j/"
const val CF_ST_CDN_C = "https://cf-st.sc-cdn.net/c/"
const val CF_ST_CDN_M = "https://cf-st.sc-cdn.net/m/"
const val CF_ST_CDN_A = "https://cf-st.sc-cdn.net/a/"
const val CF_ST_CDN_AA = "https://cf-st.sc-cdn.net/aa/"
private val keyCache: MutableMap<String, String> = mutableMapOf()
fun downloadRemoteContent(
key: String,
vararg endpoints: String
): InputStream? = runBlocking {
if (keyCache.containsKey(key)) {
return@runBlocking queryRemoteContent(
keyCache[key]!!
)
}
val jobs = mutableListOf<Job>()
var inputStream: InputStream? = null
endpoints.forEach {
launch(Dispatchers.IO) {
val url = it + key
queryRemoteContent(url)?.let { result ->
keyCache[key] = url
inputStream = result
jobs.forEach { it.cancel() }
}
}.also { jobs.add(it) }
}
jobs.joinAll()
inputStream
}
private fun queryRemoteContent(url: String): InputStream? { private fun queryRemoteContent(url: String): InputStream? {
try { try {
val connection = URL(url).openConnection() as HttpsURLConnection val connection = URL(url).openConnection() as HttpsURLConnection
connection.requestMethod = "GET" connection.requestMethod = "GET"
connection.connectTimeout = 5000 connection.instanceFollowRedirects = true
connection.setRequestProperty("User-Agent", Constants.USER_AGENT) connection.setRequestProperty("User-Agent", Constants.USER_AGENT)
return connection.inputStream return connection.inputStream
} catch (ignored: Throwable) { } catch (ignored: Throwable) {
@ -66,23 +23,17 @@ object CdnDownloader {
return null return null
} }
//TODO: automatically detect the correct endpoint
fun downloadWithDefaultEndpoints(key: String): InputStream? { fun downloadWithDefaultEndpoints(key: String): InputStream? {
return downloadRemoteContent( val payload = ProtoWriter().apply {
key, write(2) {
CF_ST_CDN_F, writeString(2, key)
CF_ST_CDN_H, writeBuffer(3, byteArrayOf())
BOLT_CDN_U, writeBuffer(3, byteArrayOf())
BOLT_CDN_X, writeConstant(6, 6)
CF_ST_CDN_O, writeConstant(10, 4)
CF_ST_CDN_I, writeConstant(12, 1)
CF_ST_CDN_C, }
CF_ST_CDN_J, }.toByteArray()
CF_ST_CDN_M, return queryRemoteContent(BOLT_HTTP_RESOLVER_URL + "/resolve?co=" + Base64.getUrlEncoder().encodeToString(payload))
CF_ST_CDN_A,
CF_ST_CDN_AA,
CF_ST_CDN_G,
CF_ST_CDN_D
)
} }
} }