diff --git a/app/src/main/java/com/hippo/ehviewer/client/EhDns.kt b/app/src/main/java/com/hippo/ehviewer/client/EhDns.kt index 812c80ea1..3b1c52d58 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/EhDns.kt +++ b/app/src/main/java/com/hippo/ehviewer/client/EhDns.kt @@ -3,6 +3,7 @@ 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 @@ -29,5 +30,5 @@ fun HostsMap.hosts(vararg hosts: String, builder: HostMapBuilder.() -> Unit) = a 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 } ?: systemDns.lookup(hostname) + 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/ui/settings/AdvancedScreen.kt b/app/src/main/java/com/hippo/ehviewer/ui/settings/AdvancedScreen.kt index 9104a475c..e7222febe 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,6 +1,7 @@ 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,12 +33,15 @@ 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.legacy.BaseDialogBuilder +import com.hippo.ehviewer.ui.legacy.EditTextDialogBuilder import com.hippo.ehviewer.ui.login.LocalNavController import com.hippo.ehviewer.util.LogCat import com.hippo.ehviewer.util.ReadableTime @@ -46,7 +50,10 @@ 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 @@ -138,7 +145,23 @@ fun AdvancedScreen() { ) 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), @@ -265,3 +288,18 @@ 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() +}