mirror of
https://github.com/rhunk/SnapEnhance.git
synced 2025-05-25 11:02:16 +02:00
perf(cdndownloader): bolt http resolver
This commit is contained in:
parent
0f711b698e
commit
c1a01bf169
@ -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")
|
||||||
|
@ -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
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user