Drop domain fronting and other network hacks since #1147
This commit is contained in:
1 parent
cf95e7b034
commit
2d20da70b8
8 files changed
+6
-248
No files matched your search
@@ -226,7 +226,6 @@ dependencies {
|
|||||||
implementation(platform("com.squareup.okhttp3:okhttp-bom:5.0.0-alpha.11"))
|
implementation(platform("com.squareup.okhttp3:okhttp-bom:5.0.0-alpha.11"))
|
||||||
implementation("com.squareup.okhttp3:okhttp-android")
|
implementation("com.squareup.okhttp3:okhttp-android")
|
||||||
implementation("com.squareup.okhttp3:okhttp-coroutines")
|
implementation("com.squareup.okhttp3:okhttp-coroutines")
|
||||||
implementation("com.squareup.okhttp3:okhttp-dnsoverhttps")
|
|
||||||
|
|
||||||
implementation("com.squareup.okio:okio-jvm:3.3.0")
|
implementation("com.squareup.okio:okio-jvm:3.3.0")
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package com.hippo.ehviewer
|
|||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.content.ComponentCallbacks2
|
import android.content.ComponentCallbacks2
|
||||||
|
import android.os.Build
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
import androidx.collection.LruCache
|
import androidx.collection.LruCache
|
||||||
import androidx.lifecycle.ProcessLifecycleOwner
|
import androidx.lifecycle.ProcessLifecycleOwner
|
||||||
@@ -26,11 +27,8 @@ import coil.decode.ImageDecoderDecoder
|
|||||||
import coil.util.DebugLogger
|
import coil.util.DebugLogger
|
||||||
import com.chuckerteam.chucker.api.ChuckerInterceptor
|
import com.chuckerteam.chucker.api.ChuckerInterceptor
|
||||||
import com.hippo.ehviewer.client.EhCookieStore
|
import com.hippo.ehviewer.client.EhCookieStore
|
||||||
import com.hippo.ehviewer.client.EhDns
|
|
||||||
import com.hippo.ehviewer.client.EhSSLSocketFactory
|
|
||||||
import com.hippo.ehviewer.client.EhTagDatabase
|
import com.hippo.ehviewer.client.EhTagDatabase
|
||||||
import com.hippo.ehviewer.client.data.GalleryDetail
|
import com.hippo.ehviewer.client.data.GalleryDetail
|
||||||
import com.hippo.ehviewer.client.install
|
|
||||||
import com.hippo.ehviewer.coil.MergeInterceptor
|
import com.hippo.ehviewer.coil.MergeInterceptor
|
||||||
import com.hippo.ehviewer.coil.diskCache
|
import com.hippo.ehviewer.coil.diskCache
|
||||||
import com.hippo.ehviewer.coil.imageLoader
|
import com.hippo.ehviewer.coil.imageLoader
|
||||||
@@ -48,6 +46,9 @@ import com.hippo.ehviewer.yorozuya.FileUtils
|
|||||||
import eu.kanade.tachiyomi.util.lang.launchIO
|
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||||
import eu.kanade.tachiyomi.util.lang.withUIContext
|
import eu.kanade.tachiyomi.util.lang.withUIContext
|
||||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||||
|
import okhttp3.AsyncDns
|
||||||
|
import okhttp3.Dns
|
||||||
|
import okhttp3.android.AndroidAsyncDns
|
||||||
import okio.Path.Companion.toOkioPath
|
import okio.Path.Companion.toOkioPath
|
||||||
import splitties.arch.room.roomDb
|
import splitties.arch.room.roomDb
|
||||||
import splitties.init.appCtx
|
import splitties.init.appCtx
|
||||||
@@ -146,15 +147,15 @@ class EhApplication : Application(), ImageLoaderFactory {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val nonCacheOkHttpClient by lazy {
|
val nonCacheOkHttpClient by lazy {
|
||||||
|
val systemDns = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) AsyncDns.toDns(AndroidAsyncDns.IPv4, AndroidAsyncDns.IPv6) else Dns.SYSTEM
|
||||||
httpClient {
|
httpClient {
|
||||||
cookieJar(EhCookieStore)
|
cookieJar(EhCookieStore)
|
||||||
dns(EhDns)
|
dns(systemDns)
|
||||||
addInterceptor(
|
addInterceptor(
|
||||||
ChuckerInterceptor.Builder(appCtx).apply {
|
ChuckerInterceptor.Builder(appCtx).apply {
|
||||||
alwaysReadResponseBody(false)
|
alwaysReadResponseBody(false)
|
||||||
}.build(),
|
}.build(),
|
||||||
)
|
)
|
||||||
if (Settings.dF) install(EhSSLSocketFactory)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,52 +0,0 @@
|
|||||||
package com.hippo.ehviewer
|
|
||||||
|
|
||||||
import com.hippo.ehviewer.client.hosts
|
|
||||||
import com.hippo.ehviewer.client.hostsDsl
|
|
||||||
|
|
||||||
val builtInHosts = hostsDsl {
|
|
||||||
hosts("ehgt.org", "gt0.ehgt.org", "gt1.ehgt.org", "gt2.ehgt.org", "gt3.ehgt.org") {
|
|
||||||
"37.48.89.44" blockedInCN false
|
|
||||||
"81.171.10.48" blockedInCN false
|
|
||||||
"178.162.139.24" blockedInCN false
|
|
||||||
"178.162.140.212" blockedInCN false
|
|
||||||
"2001:1af8:4700:a062:8::47de" blockedInCN false
|
|
||||||
"2001:1af8:4700:a062:9::47de" blockedInCN true
|
|
||||||
"2001:1af8:4700:a0c9:4::47de" blockedInCN false
|
|
||||||
"2001:1af8:4700:a0c9:3::47de" blockedInCN true
|
|
||||||
}
|
|
||||||
hosts("e-hentai.org") {
|
|
||||||
"104.20.134.21" blockedInCN false
|
|
||||||
"104.20.135.21" blockedInCN false
|
|
||||||
"172.67.0.127" blockedInCN false
|
|
||||||
}
|
|
||||||
hosts("exhentai.org") {
|
|
||||||
"178.175.128.252" blockedInCN false
|
|
||||||
"178.175.129.252" blockedInCN false
|
|
||||||
"178.175.129.254" blockedInCN false
|
|
||||||
"178.175.128.254" blockedInCN false
|
|
||||||
"178.175.132.20" blockedInCN false
|
|
||||||
"178.175.132.22" blockedInCN false
|
|
||||||
}
|
|
||||||
hosts("s.exhentai.org") {
|
|
||||||
"178.175.129.254" blockedInCN false
|
|
||||||
"178.175.128.254" blockedInCN false
|
|
||||||
"178.175.132.22" blockedInCN false
|
|
||||||
}
|
|
||||||
hosts("repo.e-hentai.org") {
|
|
||||||
"94.100.28.57" blockedInCN true
|
|
||||||
"94.100.29.73" blockedInCN true
|
|
||||||
}
|
|
||||||
hosts("forums.e-hentai.org") {
|
|
||||||
"94.100.18.243" blockedInCN false
|
|
||||||
}
|
|
||||||
hosts("ul.ehgt.org") {
|
|
||||||
"94.100.24.82" blockedInCN true
|
|
||||||
"94.100.24.72" blockedInCN true
|
|
||||||
}
|
|
||||||
hosts("raw.githubusercontent.com") {
|
|
||||||
"151.101.0.133" blockedInCN true
|
|
||||||
"151.101.64.133" blockedInCN false
|
|
||||||
"151.101.128.133" blockedInCN false
|
|
||||||
"151.101.192.133" blockedInCN false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -12,8 +12,6 @@ import kotlin.reflect.KProperty
|
|||||||
|
|
||||||
object Settings : DataStorePreferences(null) {
|
object Settings : DataStorePreferences(null) {
|
||||||
private const val KEY_SHOW_TAG_TRANSLATIONS = "show_tag_translations"
|
private const val KEY_SHOW_TAG_TRANSLATIONS = "show_tag_translations"
|
||||||
private const val KEY_BUILT_IN_HOSTS = "built_in_hosts_2"
|
|
||||||
private const val KEY_DOMAIN_FRONTING = "domain_fronting"
|
|
||||||
|
|
||||||
var downloadScheme by stringOrNullPref("image_scheme", null)
|
var downloadScheme by stringOrNullPref("image_scheme", null)
|
||||||
var downloadAuthority by stringOrNullPref("image_authority", null)
|
var downloadAuthority by stringOrNullPref("image_authority", null)
|
||||||
@@ -48,14 +46,11 @@ object Settings : DataStorePreferences(null) {
|
|||||||
var saveParseErrorBody by boolPref("save_parse_error_body", true)
|
var saveParseErrorBody by boolPref("save_parse_error_body", true)
|
||||||
var saveCrashLog by boolPref("save_crash_log", true)
|
var saveCrashLog by boolPref("save_crash_log", true)
|
||||||
var security by boolPref("require_unlock", false)
|
var security by boolPref("require_unlock", false)
|
||||||
var builtInHosts by boolPref(KEY_BUILT_IN_HOSTS, false)
|
|
||||||
var removeImageFiles by boolPref("include_pic", true)
|
var removeImageFiles by boolPref("include_pic", true)
|
||||||
var needSignIn by boolPref("need_sign_in", true)
|
var needSignIn by boolPref("need_sign_in", true)
|
||||||
var blackDarkTheme by boolPref("black_dark_theme", false).observed { updateWhenAmoledModeChanges() }
|
var blackDarkTheme by boolPref("black_dark_theme", false).observed { updateWhenAmoledModeChanges() }
|
||||||
var preloadThumbAggressively by boolPref("preload_thumb_aggressively", false)
|
var preloadThumbAggressively by boolPref("preload_thumb_aggressively", false)
|
||||||
var dF by boolPref(KEY_DOMAIN_FRONTING, false)
|
|
||||||
var downloadOriginImage by boolPref("download_origin_image", false)
|
var downloadOriginImage by boolPref("download_origin_image", false)
|
||||||
var bypassVpn by boolPref("bypass_vpn", true)
|
|
||||||
var thumbSizeDp by intPref("thumb_size_", 120)
|
var thumbSizeDp by intPref("thumb_size_", 120)
|
||||||
var favLocalCount by intPref("fav_local", 0)
|
var favLocalCount by intPref("fav_local", 0)
|
||||||
var favCloudCount by intPref("fav_cloud", 0)
|
var favCloudCount by intPref("fav_cloud", 0)
|
||||||
@@ -78,8 +73,6 @@ object Settings : DataStorePreferences(null) {
|
|||||||
init {
|
init {
|
||||||
if ("CN" == Locale.getDefault().country) {
|
if ("CN" == Locale.getDefault().country) {
|
||||||
edit {
|
edit {
|
||||||
if (KEY_BUILT_IN_HOSTS !in prefs) builtInHosts = true
|
|
||||||
if (KEY_DOMAIN_FRONTING !in prefs) dF = true
|
|
||||||
if (KEY_SHOW_TAG_TRANSLATIONS !in prefs) showTagTranslations = true
|
if (KEY_SHOW_TAG_TRANSLATIONS !in prefs) showTagTranslations = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
package com.hippo.ehviewer.client
|
|
||||||
|
|
||||||
import android.os.Build
|
|
||||||
import com.hippo.ehviewer.Settings
|
|
||||||
import com.hippo.ehviewer.builtInHosts
|
|
||||||
import com.hippo.ehviewer.ui.settings.EhDoH
|
|
||||||
import okhttp3.AsyncDns
|
|
||||||
import okhttp3.Dns
|
|
||||||
import okhttp3.android.AndroidAsyncDns
|
|
||||||
import java.net.InetAddress
|
|
||||||
|
|
||||||
private typealias HostsMap = MutableMap<String, List<InetAddress>>
|
|
||||||
|
|
||||||
fun hostsDsl(builder: HostsMap.() -> Unit): HostsMap = mutableMapOf<String, List<InetAddress>>().apply(builder)
|
|
||||||
|
|
||||||
fun interface HostMapBuilder {
|
|
||||||
infix fun String.blockedInCN(boolean: Boolean)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun HostsMap.hosts(vararg hosts: String, builder: HostMapBuilder.() -> Unit) = apply {
|
|
||||||
hosts.forEach { host ->
|
|
||||||
fun String.toInetAddress() = InetAddress.getByName(this).let { InetAddress.getByAddress(host, it.address) }
|
|
||||||
mutableListOf<InetAddress>().apply {
|
|
||||||
HostMapBuilder { if (!(Settings.dF && it)) add(toInetAddress()) }.apply(builder)
|
|
||||||
put(host, this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val systemDns = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) AsyncDns.toDns(AndroidAsyncDns.IPv4, AndroidAsyncDns.IPv6) else Dns.SYSTEM
|
|
||||||
|
|
||||||
object EhDns : Dns {
|
|
||||||
override fun lookup(hostname: String): List<InetAddress> = builtInHosts[hostname].takeIf { Settings.builtInHosts } ?: EhDoH.lookup(hostname) ?: systemDns.lookup(hostname)
|
|
||||||
}
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2022 Tarsin Norbin
|
|
||||||
*
|
|
||||||
* This file is part of EhViewer
|
|
||||||
*
|
|
||||||
* EhViewer is free software: you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License as
|
|
||||||
* published by the Free Software Foundation, either version 3 of the
|
|
||||||
* License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* EhViewer is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along with EhViewer.
|
|
||||||
* If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package com.hippo.ehviewer.client
|
|
||||||
|
|
||||||
import android.util.Log
|
|
||||||
import com.hippo.ehviewer.Settings
|
|
||||||
import com.hippo.ehviewer.builtInHosts
|
|
||||||
import okhttp3.OkHttpClient
|
|
||||||
import java.net.InetAddress
|
|
||||||
import java.net.Socket
|
|
||||||
import java.security.KeyStore
|
|
||||||
import javax.net.ssl.SSLSocket
|
|
||||||
import javax.net.ssl.SSLSocketFactory
|
|
||||||
import javax.net.ssl.TrustManagerFactory
|
|
||||||
import javax.net.ssl.X509TrustManager
|
|
||||||
|
|
||||||
private const val EXCEPTIONAL_DOMAIN = "hath.network"
|
|
||||||
private val sslSocketFactory = SSLSocketFactory.getDefault() as SSLSocketFactory
|
|
||||||
|
|
||||||
object EhSSLSocketFactory : SSLSocketFactory() {
|
|
||||||
override fun getDefaultCipherSuites(): Array<String> = sslSocketFactory.defaultCipherSuites
|
|
||||||
override fun getSupportedCipherSuites(): Array<String> = sslSocketFactory.supportedCipherSuites
|
|
||||||
override fun createSocket(s: Socket, host: String, port: Int, autoClose: Boolean): Socket {
|
|
||||||
val address = s.inetAddress.hostAddress.takeIf { host in builtInHosts || EXCEPTIONAL_DOMAIN in host || host in Settings.dohUrl }
|
|
||||||
Log.d("EhSSLSocketFactory", "Host: $host Address: $address")
|
|
||||||
return sslSocketFactory.createSocket(s, address ?: host, port, autoClose) as SSLSocket
|
|
||||||
}
|
|
||||||
override fun createSocket(host: String, port: Int): Socket = sslSocketFactory.createSocket(host, port)
|
|
||||||
override fun createSocket(host: String, port: Int, localHost: InetAddress, localPort: Int): Socket = sslSocketFactory.createSocket(host, port, localHost, localPort)
|
|
||||||
override fun createSocket(host: InetAddress, port: Int): Socket = sslSocketFactory.createSocket(host, port)
|
|
||||||
override fun createSocket(address: InetAddress, port: Int, localAddress: InetAddress, localPort: Int): Socket = sslSocketFactory.createSocket(address, port, localAddress, localPort)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun OkHttpClient.Builder.install(sslSocketFactory: SSLSocketFactory) = apply {
|
|
||||||
val factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())!!
|
|
||||||
factory.init(null as KeyStore?)
|
|
||||||
val manager = factory.trustManagers!!
|
|
||||||
val trustManager = manager.filterIsInstance<X509TrustManager>().first()
|
|
||||||
sslSocketFactory(sslSocketFactory, trustManager)
|
|
||||||
}
|
|
||||||
@@ -24,14 +24,10 @@ import android.content.pm.verify.domain.DomainVerificationManager
|
|||||||
import android.content.pm.verify.domain.DomainVerificationUserState
|
import android.content.pm.verify.domain.DomainVerificationUserState
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.ImageDecoder
|
import android.graphics.ImageDecoder
|
||||||
import android.net.ConnectivityManager
|
|
||||||
import android.net.Network
|
import android.net.Network
|
||||||
import android.net.NetworkCapabilities
|
|
||||||
import android.net.NetworkRequest
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
@@ -201,9 +197,6 @@ class MainActivity : EhActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
if (Settings.dF && Settings.bypassVpn) {
|
|
||||||
bypassVpn()
|
|
||||||
}
|
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
binding = ActivityMainBinding.inflate(layoutInflater)
|
binding = ActivityMainBinding.inflate(layoutInflater)
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
@@ -251,19 +244,6 @@ class MainActivity : EhActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun bypassVpn() {
|
|
||||||
val network = connectivityManager.activeNetwork
|
|
||||||
val capabilities = connectivityManager.getNetworkCapabilities(network)
|
|
||||||
capabilities?.let {
|
|
||||||
if (it.hasTransport(NetworkCapabilities.TRANSPORT_VPN)) {
|
|
||||||
val builder = NetworkRequest.Builder()
|
|
||||||
.addCapability(NetworkCapabilities.NET_CAPABILITY_FOREGROUND)
|
|
||||||
.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
|
|
||||||
connectivityManager.registerNetworkCallback(builder.build(), mNetworkCallback)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.S)
|
@RequiresApi(Build.VERSION_CODES.S)
|
||||||
@Throws(PackageManager.NameNotFoundException::class)
|
@Throws(PackageManager.NameNotFoundException::class)
|
||||||
private fun checkAppLinkVerify() {
|
private fun checkAppLinkVerify() {
|
||||||
@@ -484,25 +464,4 @@ class MainActivity : EhActivity() {
|
|||||||
super.onProvideAssistContent(outContent)
|
super.onProvideAssistContent(outContent)
|
||||||
mShareUrl?.let { outContent?.webUri = Uri.parse(mShareUrl) }
|
mShareUrl?.let { outContent?.webUri = Uri.parse(mShareUrl) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private val mNetworkCallback = object : ConnectivityManager.NetworkCallback() {
|
|
||||||
private val TAG = "mNetworkCallback"
|
|
||||||
|
|
||||||
override fun onAvailable(network: Network) {
|
|
||||||
Log.d(TAG, "onAvailable: $network")
|
|
||||||
connectivityManager.bindProcessToNetwork(network)
|
|
||||||
availableNetworks.add(network)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onLost(network: Network) {
|
|
||||||
Log.d(TAG, "onLost: $network")
|
|
||||||
val activeNetwork = availableNetworks.last()
|
|
||||||
availableNetworks.remove(network)
|
|
||||||
if (network == activeNetwork) {
|
|
||||||
connectivityManager.bindProcessToNetwork(
|
|
||||||
availableNetworks.takeIf { it.isNotEmpty() }?.last(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
package com.hippo.ehviewer.ui.settings
|
package com.hippo.ehviewer.ui.settings
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.DialogInterface
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS
|
import android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS
|
||||||
@@ -32,15 +31,12 @@ import androidx.compose.ui.platform.LocalContext
|
|||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import com.hippo.ehviewer.AppConfig
|
import com.hippo.ehviewer.AppConfig
|
||||||
import com.hippo.ehviewer.BuildConfig
|
import com.hippo.ehviewer.BuildConfig
|
||||||
import com.hippo.ehviewer.EhApplication
|
|
||||||
import com.hippo.ehviewer.EhDB
|
import com.hippo.ehviewer.EhDB
|
||||||
import com.hippo.ehviewer.R
|
import com.hippo.ehviewer.R
|
||||||
import com.hippo.ehviewer.Settings
|
import com.hippo.ehviewer.Settings
|
||||||
import com.hippo.ehviewer.client.EhEngine
|
import com.hippo.ehviewer.client.EhEngine
|
||||||
import com.hippo.ehviewer.client.data.FavListUrlBuilder
|
import com.hippo.ehviewer.client.data.FavListUrlBuilder
|
||||||
import com.hippo.ehviewer.client.systemDns
|
|
||||||
import com.hippo.ehviewer.ui.LocalNavController
|
import com.hippo.ehviewer.ui.LocalNavController
|
||||||
import com.hippo.ehviewer.ui.legacy.EditTextDialogBuilder
|
|
||||||
import com.hippo.ehviewer.ui.tools.observed
|
import com.hippo.ehviewer.ui.tools.observed
|
||||||
import com.hippo.ehviewer.util.LogCat
|
import com.hippo.ehviewer.util.LogCat
|
||||||
import com.hippo.ehviewer.util.ReadableTime
|
import com.hippo.ehviewer.util.ReadableTime
|
||||||
@@ -48,10 +44,7 @@ import kotlinx.coroutines.Dispatchers
|
|||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import moe.tarsin.coroutines.runSuspendCatching
|
import moe.tarsin.coroutines.runSuspendCatching
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
|
||||||
import okhttp3.dnsoverhttps.DnsOverHttps
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.net.InetAddress
|
|
||||||
import java.util.zip.ZipEntry
|
import java.util.zip.ZipEntry
|
||||||
import java.util.zip.ZipOutputStream
|
import java.util.zip.ZipOutputStream
|
||||||
|
|
||||||
@@ -133,37 +126,6 @@ fun AdvancedScreen() {
|
|||||||
entryValueRes = R.array.app_language_entry_values,
|
entryValueRes = R.array.app_language_entry_values,
|
||||||
value = Settings::language,
|
value = Settings::language,
|
||||||
)
|
)
|
||||||
SwitchPreference(
|
|
||||||
title = stringResource(id = R.string.settings_advanced_built_in_hosts_title),
|
|
||||||
value = Settings::builtInHosts,
|
|
||||||
)
|
|
||||||
Preference(title = stringResource(id = R.string.settings_advanced_dns_over_http_title)) {
|
|
||||||
val builder = EditTextDialogBuilder(context, Settings.dohUrl, context.getString(R.string.settings_advanced_dns_over_http_hint))
|
|
||||||
builder.setTitle(R.string.settings_advanced_dns_over_http_title)
|
|
||||||
builder.setPositiveButton(android.R.string.ok, null)
|
|
||||||
val dialog = builder.create().apply { show() }
|
|
||||||
dialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener {
|
|
||||||
val text = builder.text.trim()
|
|
||||||
runCatching {
|
|
||||||
doh = if (text.isNotBlank()) buildDoHDNS(text) else null
|
|
||||||
}.onFailure {
|
|
||||||
builder.setError("Invalid URL!")
|
|
||||||
}.onSuccess {
|
|
||||||
Settings.dohUrl = text
|
|
||||||
dialog.dismiss()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SwitchPreference(
|
|
||||||
title = stringResource(id = R.string.settings_advanced_domain_fronting_title),
|
|
||||||
summary = stringResource(id = R.string.settings_advanced_domain_fronting_summary),
|
|
||||||
value = Settings::dF,
|
|
||||||
)
|
|
||||||
SwitchPreference(
|
|
||||||
title = stringResource(id = R.string.settings_advanced_bypass_vpn_title),
|
|
||||||
summary = stringResource(id = R.string.settings_advanced_bypass_vpn_summary),
|
|
||||||
value = Settings::bypassVpn,
|
|
||||||
)
|
|
||||||
SwitchPreference(
|
SwitchPreference(
|
||||||
title = stringResource(id = R.string.preload_thumb_aggressively),
|
title = stringResource(id = R.string.preload_thumb_aggressively),
|
||||||
value = Settings::preloadThumbAggressively,
|
value = Settings::preloadThumbAggressively,
|
||||||
@@ -265,18 +227,3 @@ fun AdvancedScreen() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildDoHDNS(url: String): DnsOverHttps {
|
|
||||||
return DnsOverHttps.Builder().apply {
|
|
||||||
client(EhApplication.okHttpClient)
|
|
||||||
url(url.toHttpUrl())
|
|
||||||
post(true)
|
|
||||||
systemDns(systemDns)
|
|
||||||
}.build()
|
|
||||||
}
|
|
||||||
|
|
||||||
private var doh: DnsOverHttps? = Settings.dohUrl.runCatching { buildDoHDNS(this) }.getOrNull()
|
|
||||||
|
|
||||||
object EhDoH {
|
|
||||||
fun lookup(hostname: String): List<InetAddress>? = doh?.runCatching { lookup(hostname).takeIf { it.isNotEmpty() } }?.onFailure { it.printStackTrace() }?.getOrNull()
|
|
||||||
}
|
|
||||||
Reference in new issue
Block a user