diff --git a/app/build.gradle.kts b/app/build.gradle.kts index dde28b0fc..8e7869f11 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -226,7 +226,6 @@ dependencies { implementation(platform("com.squareup.okhttp3:okhttp-bom:5.0.0-alpha.11")) implementation("com.squareup.okhttp3:okhttp-android") implementation("com.squareup.okhttp3:okhttp-coroutines") - implementation("com.squareup.okhttp3:okhttp-dnsoverhttps") implementation("com.squareup.okio:okio-jvm:3.3.0") diff --git a/app/src/main/java/com/hippo/ehviewer/EhApplication.kt b/app/src/main/java/com/hippo/ehviewer/EhApplication.kt index d9752e6a6..ba899c415 100644 --- a/app/src/main/java/com/hippo/ehviewer/EhApplication.kt +++ b/app/src/main/java/com/hippo/ehviewer/EhApplication.kt @@ -18,6 +18,7 @@ package com.hippo.ehviewer import android.app.Application import android.content.ComponentCallbacks2 +import android.os.Build import androidx.appcompat.app.AppCompatDelegate import androidx.collection.LruCache import androidx.lifecycle.ProcessLifecycleOwner @@ -26,11 +27,8 @@ import coil.decode.ImageDecoderDecoder import coil.util.DebugLogger import com.chuckerteam.chucker.api.ChuckerInterceptor 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.data.GalleryDetail -import com.hippo.ehviewer.client.install import com.hippo.ehviewer.coil.MergeInterceptor import com.hippo.ehviewer.coil.diskCache 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.withUIContext import kotlinx.coroutines.DelicateCoroutinesApi +import okhttp3.AsyncDns +import okhttp3.Dns +import okhttp3.android.AndroidAsyncDns import okio.Path.Companion.toOkioPath import splitties.arch.room.roomDb import splitties.init.appCtx @@ -146,15 +147,15 @@ class EhApplication : Application(), ImageLoaderFactory { companion object { 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 { cookieJar(EhCookieStore) - dns(EhDns) + dns(systemDns) addInterceptor( ChuckerInterceptor.Builder(appCtx).apply { alwaysReadResponseBody(false) }.build(), ) - if (Settings.dF) install(EhSSLSocketFactory) } } diff --git a/app/src/main/java/com/hippo/ehviewer/EhHostsConfig.kt b/app/src/main/java/com/hippo/ehviewer/EhHostsConfig.kt deleted file mode 100644 index 51c6c3b2b..000000000 --- a/app/src/main/java/com/hippo/ehviewer/EhHostsConfig.kt +++ /dev/null @@ -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 - } -} diff --git a/app/src/main/java/com/hippo/ehviewer/Settings.kt b/app/src/main/java/com/hippo/ehviewer/Settings.kt index 71d719001..c15fbbc91 100755 --- a/app/src/main/java/com/hippo/ehviewer/Settings.kt +++ b/app/src/main/java/com/hippo/ehviewer/Settings.kt @@ -12,8 +12,6 @@ import kotlin.reflect.KProperty object Settings : DataStorePreferences(null) { 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 downloadAuthority by stringOrNullPref("image_authority", null) @@ -48,14 +46,11 @@ object Settings : DataStorePreferences(null) { var saveParseErrorBody by boolPref("save_parse_error_body", true) var saveCrashLog by boolPref("save_crash_log", true) var security by boolPref("require_unlock", false) - var builtInHosts by boolPref(KEY_BUILT_IN_HOSTS, false) var removeImageFiles by boolPref("include_pic", true) var needSignIn by boolPref("need_sign_in", true) var blackDarkTheme by boolPref("black_dark_theme", false).observed { updateWhenAmoledModeChanges() } 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 bypassVpn by boolPref("bypass_vpn", true) var thumbSizeDp by intPref("thumb_size_", 120) var favLocalCount by intPref("fav_local", 0) var favCloudCount by intPref("fav_cloud", 0) @@ -78,8 +73,6 @@ object Settings : DataStorePreferences(null) { init { if ("CN" == Locale.getDefault().country) { 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 } } diff --git a/app/src/main/java/com/hippo/ehviewer/client/EhDns.kt b/app/src/main/java/com/hippo/ehviewer/client/EhDns.kt deleted file mode 100644 index 3b1c52d58..000000000 --- a/app/src/main/java/com/hippo/ehviewer/client/EhDns.kt +++ /dev/null @@ -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> - -fun hostsDsl(builder: HostsMap.() -> Unit): HostsMap = mutableMapOf>().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().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 = builtInHosts[hostname].takeIf { Settings.builtInHosts } ?: EhDoH.lookup(hostname) ?: systemDns.lookup(hostname) -} diff --git a/app/src/main/java/com/hippo/ehviewer/client/EhSSLSocketFactory.kt b/app/src/main/java/com/hippo/ehviewer/client/EhSSLSocketFactory.kt deleted file mode 100644 index f0df0236b..000000000 --- a/app/src/main/java/com/hippo/ehviewer/client/EhSSLSocketFactory.kt +++ /dev/null @@ -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 . - */ -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 = sslSocketFactory.defaultCipherSuites - override fun getSupportedCipherSuites(): Array = 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().first() - sslSocketFactory(sslSocketFactory, trustManager) -} diff --git a/app/src/main/java/com/hippo/ehviewer/ui/MainActivity.kt b/app/src/main/java/com/hippo/ehviewer/ui/MainActivity.kt index c816e26f8..38915c6e8 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/MainActivity.kt +++ b/app/src/main/java/com/hippo/ehviewer/ui/MainActivity.kt @@ -24,14 +24,10 @@ import android.content.pm.verify.domain.DomainVerificationManager import android.content.pm.verify.domain.DomainVerificationUserState import android.graphics.Bitmap import android.graphics.ImageDecoder -import android.net.ConnectivityManager import android.net.Network -import android.net.NetworkCapabilities -import android.net.NetworkRequest import android.net.Uri import android.os.Build import android.os.Bundle -import android.util.Log import android.view.View import android.widget.Toast import androidx.activity.result.contract.ActivityResultContracts @@ -201,9 +197,6 @@ class MainActivity : EhActivity() { } override fun onCreate(savedInstanceState: Bundle?) { - if (Settings.dF && Settings.bypassVpn) { - bypassVpn() - } super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) 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) @Throws(PackageManager.NameNotFoundException::class) private fun checkAppLinkVerify() { @@ -484,25 +464,4 @@ class MainActivity : EhActivity() { super.onProvideAssistContent(outContent) 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(), - ) - } - } - } } diff --git a/app/src/main/java/com/hippo/ehviewer/ui/settings/AdvancedScreen.kt b/app/src/main/java/com/hippo/ehviewer/ui/settings/AdvancedScreen.kt index f1da8e87d..be8116141 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/settings/AdvancedScreen.kt +++ b/app/src/main/java/com/hippo/ehviewer/ui/settings/AdvancedScreen.kt @@ -1,7 +1,6 @@ package com.hippo.ehviewer.ui.settings import android.annotation.SuppressLint -import android.content.DialogInterface import android.content.Intent import android.net.Uri 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 com.hippo.ehviewer.AppConfig import com.hippo.ehviewer.BuildConfig -import com.hippo.ehviewer.EhApplication import com.hippo.ehviewer.EhDB import com.hippo.ehviewer.R import com.hippo.ehviewer.Settings import com.hippo.ehviewer.client.EhEngine import com.hippo.ehviewer.client.data.FavListUrlBuilder -import com.hippo.ehviewer.client.systemDns import com.hippo.ehviewer.ui.LocalNavController -import com.hippo.ehviewer.ui.legacy.EditTextDialogBuilder import com.hippo.ehviewer.ui.tools.observed import com.hippo.ehviewer.util.LogCat import com.hippo.ehviewer.util.ReadableTime @@ -48,10 +44,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.launch import moe.tarsin.coroutines.runSuspendCatching -import okhttp3.HttpUrl.Companion.toHttpUrl -import okhttp3.dnsoverhttps.DnsOverHttps import java.io.File -import java.net.InetAddress import java.util.zip.ZipEntry import java.util.zip.ZipOutputStream @@ -133,37 +126,6 @@ fun AdvancedScreen() { entryValueRes = R.array.app_language_entry_values, 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( title = stringResource(id = R.string.preload_thumb_aggressively), 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? = doh?.runCatching { lookup(hostname).takeIf { it.isNotEmpty() } }?.onFailure { it.printStackTrace() }?.getOrNull() -}