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 e0e582c9b..14121cb44 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/EhDns.kt +++ b/app/src/main/java/com/hippo/ehviewer/client/EhDns.kt @@ -2,6 +2,7 @@ package com.hippo.ehviewer.client import android.os.Build import com.hippo.ehviewer.Settings +import com.hippo.ehviewer.preference.EhDoH import okhttp3.AsyncDns import okhttp3.Dns import okhttp3.android.AndroidAsyncDns @@ -23,10 +24,10 @@ private fun HostsMap.hosts(vararg hosts: String, builder: HostMapBuilder.() -> U } } -private val dnsSystem = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) AsyncDns.toDns(AndroidAsyncDns.IPv4, AndroidAsyncDns.IPv6) else Dns.SYSTEM +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 } ?: dnsSystem.lookup(hostname) + override fun lookup(hostname: String): List = builtInHosts[hostname].takeIf { Settings.builtInHosts } ?: EhDoH.lookup(hostname) ?: systemDns.lookup(hostname) operator fun contains(hostname: String) = builtInHosts.contains(hostname) && Settings.builtInHosts } diff --git a/app/src/main/java/com/hippo/ehviewer/preference/DohPreference.kt b/app/src/main/java/com/hippo/ehviewer/preference/DohPreference.kt index 36074285d..886d23a47 100644 --- a/app/src/main/java/com/hippo/ehviewer/preference/DohPreference.kt +++ b/app/src/main/java/com/hippo/ehviewer/preference/DohPreference.kt @@ -1,11 +1,17 @@ package com.hippo.ehviewer.preference import android.content.Context +import android.content.DialogInterface import android.util.AttributeSet import androidx.preference.Preference +import com.hippo.ehviewer.EhApplication import com.hippo.ehviewer.R import com.hippo.ehviewer.Settings +import com.hippo.ehviewer.client.systemDns import com.hippo.ehviewer.ui.legacy.EditTextDialogBuilder +import okhttp3.HttpUrl.Companion.toHttpUrl +import okhttp3.dnsoverhttps.DnsOverHttps +import java.net.InetAddress class DohPreference @JvmOverloads constructor( context: Context, @@ -14,6 +20,34 @@ class DohPreference @JvmOverloads constructor( override fun onClick() { 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) { _, _ -> Settings.putDohUrl(builder.text.trim()) }.show() + builder.setPositiveButton(android.R.string.ok, null) + val dialog = builder.create() + dialog.show() + dialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener { + val text = builder.text.trim() + runCatching { + if (text.isNotBlank()) text.toHttpUrl() + }.onFailure { + builder.setError("Invalid URL!") + }.onSuccess { + Settings.putDohUrl(text) + dialog.dismiss() + } + } } } + +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() } }?.getOrNull() +}