From f72fad4d595efbe76ffff9816fbca9ab6e5ba7a5 Mon Sep 17 00:00:00 2001
From: Andy Ye <35905412+TurboTheTurtle@users.noreply.github.com>
Date: Tue, 19 May 2026 15:20:58 -0700
Subject: [PATCH] Make connection test URL editable
---
.../main/java/com/github/shadowsocks/net/HttpsTest.kt | 9 +++++++--
.../java/com/github/shadowsocks/preference/DataStore.kt | 6 ++++++
.../preference/EditTextPreferenceModifiers.kt | 9 +++++++++
.../main/java/com/github/shadowsocks/utils/Constants.kt | 1 +
core/src/main/res/values/strings.xml | 1 +
.../shadowsocks/GlobalSettingsPreferenceFragment.kt | 2 ++
mobile/src/main/res/xml/pref_global.xml | 4 ++++
.../com/github/shadowsocks/tv/MainPreferenceFragment.kt | 2 ++
tv/src/main/res/xml/pref_main.xml | 4 ++++
9 files changed, 36 insertions(+), 2 deletions(-)
diff --git a/core/src/main/java/com/github/shadowsocks/net/HttpsTest.kt b/core/src/main/java/com/github/shadowsocks/net/HttpsTest.kt
index 16e8160adc..214edca768 100644
--- a/core/src/main/java/com/github/shadowsocks/net/HttpsTest.kt
+++ b/core/src/main/java/com/github/shadowsocks/net/HttpsTest.kt
@@ -80,8 +80,13 @@ class HttpsTest : ViewModel() {
fun testConnection() {
cancelTest()
status.value = Status.Testing
- val url = URL("https://cp.cloudflare.com")
- val conn = url.openConnection(DataStore.proxy) as HttpURLConnection
+ val conn = try {
+ URL(DataStore.connectionTestUrl).openConnection(DataStore.proxy) as? HttpURLConnection
+ ?: throw IOException("URL is not HTTP(S)")
+ } catch (e: IOException) {
+ status.value = Status.Error.IOFailure(e)
+ return
+ }
conn.setRequestProperty("Connection", "close")
conn.instanceFollowRedirects = false
conn.useCaches = false
diff --git a/core/src/main/java/com/github/shadowsocks/preference/DataStore.kt b/core/src/main/java/com/github/shadowsocks/preference/DataStore.kt
index 5f3a772bf4..3c30dabe1c 100644
--- a/core/src/main/java/com/github/shadowsocks/preference/DataStore.kt
+++ b/core/src/main/java/com/github/shadowsocks/preference/DataStore.kt
@@ -33,6 +33,8 @@ import java.net.InetSocketAddress
import java.net.Proxy
object DataStore : OnPreferenceDataStoreChangeListener {
+ private const val DEFAULT_CONNECTION_TEST_URL = "https://cp.cloudflare.com"
+
val publicStore = RoomPreferenceDataStore(PublicDatabase.kvPairDao)
// privateStore will only be used as temp storage for ProfileConfigFragment
val privateStore = RoomPreferenceDataStore(PrivateDatabase.kvPairDao)
@@ -76,6 +78,7 @@ object DataStore : OnPreferenceDataStoreChangeListener {
var portTransproxy: Int
get() = getLocalPort(Key.portTransproxy, 8200)
set(value) = publicStore.putString(Key.portTransproxy, value.toString())
+ val connectionTestUrl get() = publicStore.getString(Key.connectionTestUrl) ?: DEFAULT_CONNECTION_TEST_URL
/**
* Initialize settings that have complicated default values.
@@ -85,6 +88,9 @@ object DataStore : OnPreferenceDataStoreChangeListener {
if (publicStore.getString(Key.portProxy) == null) portProxy = portProxy
if (publicStore.getString(Key.portLocalDns) == null) portLocalDns = portLocalDns
if (publicStore.getString(Key.portTransproxy) == null) portTransproxy = portTransproxy
+ if (publicStore.getString(Key.connectionTestUrl) == null) {
+ publicStore.putString(Key.connectionTestUrl, connectionTestUrl)
+ }
}
var editingId: Long?
diff --git a/core/src/main/java/com/github/shadowsocks/preference/EditTextPreferenceModifiers.kt b/core/src/main/java/com/github/shadowsocks/preference/EditTextPreferenceModifiers.kt
index 1385c77ed5..63a097d322 100644
--- a/core/src/main/java/com/github/shadowsocks/preference/EditTextPreferenceModifiers.kt
+++ b/core/src/main/java/com/github/shadowsocks/preference/EditTextPreferenceModifiers.kt
@@ -22,6 +22,7 @@ package com.github.shadowsocks.preference
import android.graphics.Typeface
import android.text.InputFilter
+import android.text.InputType
import android.view.inputmethod.EditorInfo
import android.widget.EditText
import androidx.preference.EditTextPreference
@@ -43,4 +44,12 @@ object EditTextPreferenceModifiers {
editText.setSelection(editText.text.length)
}
}
+
+ object Url : EditTextPreference.OnBindEditTextListener {
+ override fun onBindEditText(editText: EditText) {
+ editText.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_URI
+ editText.setSingleLine()
+ editText.setSelection(editText.text.length)
+ }
+ }
}
diff --git a/core/src/main/java/com/github/shadowsocks/utils/Constants.kt b/core/src/main/java/com/github/shadowsocks/utils/Constants.kt
index 52b6de20ec..8704f64d18 100644
--- a/core/src/main/java/com/github/shadowsocks/utils/Constants.kt
+++ b/core/src/main/java/com/github/shadowsocks/utils/Constants.kt
@@ -40,6 +40,7 @@ object Key {
const val portProxy = "portProxy"
const val portLocalDns = "portLocalDns"
const val portTransproxy = "portTransproxy"
+ const val connectionTestUrl = "connectionTestUrl"
const val route = "route"
diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml
index 04ed7d9d67..60f8ed00f5 100644
--- a/core/src/main/res/values/strings.xml
+++ b/core/src/main/res/values/strings.xml
@@ -14,6 +14,7 @@
SOCKS5 proxy port
Local DNS port
Transproxy port
+ Connection test URL
Remote DNS
%1$s↑\t%2$s↓
diff --git a/mobile/src/main/java/com/github/shadowsocks/GlobalSettingsPreferenceFragment.kt b/mobile/src/main/java/com/github/shadowsocks/GlobalSettingsPreferenceFragment.kt
index cc7ac91647..202b1ae448 100644
--- a/mobile/src/main/java/com/github/shadowsocks/GlobalSettingsPreferenceFragment.kt
+++ b/mobile/src/main/java/com/github/shadowsocks/GlobalSettingsPreferenceFragment.kt
@@ -59,6 +59,8 @@ class GlobalSettingsPreferenceFragment : PreferenceFragmentCompat() {
portLocalDns.setOnBindEditTextListener(EditTextPreferenceModifiers.Port)
val portTransproxy = findPreference(Key.portTransproxy)!!
portTransproxy.setOnBindEditTextListener(EditTextPreferenceModifiers.Port)
+ val connectionTestUrl = findPreference(Key.connectionTestUrl)!!
+ connectionTestUrl.setOnBindEditTextListener(EditTextPreferenceModifiers.Url)
val onServiceModeChange = Preference.OnPreferenceChangeListener { _, newValue ->
portTransproxy.isEnabled = newValue as String? == Key.modeTransproxy
true
diff --git a/mobile/src/main/res/xml/pref_global.xml b/mobile/src/main/res/xml/pref_global.xml
index 9a4808d8b3..817bbe19d6 100644
--- a/mobile/src/main/res/xml/pref_global.xml
+++ b/mobile/src/main/res/xml/pref_global.xml
@@ -34,4 +34,8 @@
app:key="portTransproxy"
app:title="@string/port_transproxy"
app:useSimpleSummaryProvider="true"/>
+
diff --git a/tv/src/main/java/com/github/shadowsocks/tv/MainPreferenceFragment.kt b/tv/src/main/java/com/github/shadowsocks/tv/MainPreferenceFragment.kt
index 198245f728..9722bd663a 100644
--- a/tv/src/main/java/com/github/shadowsocks/tv/MainPreferenceFragment.kt
+++ b/tv/src/main/java/com/github/shadowsocks/tv/MainPreferenceFragment.kt
@@ -141,6 +141,8 @@ class MainPreferenceFragment : LeanbackPreferenceFragmentCompat(), ShadowsocksCo
portLocalDns.setOnBindEditTextListener(EditTextPreferenceModifiers.Port)
portTransproxy = findPreference(Key.portTransproxy)!!
portTransproxy.setOnBindEditTextListener(EditTextPreferenceModifiers.Port)
+ findPreference(Key.connectionTestUrl)!!
+ .setOnBindEditTextListener(EditTextPreferenceModifiers.Url)
serviceMode.onPreferenceChangeListener = onServiceModeChange
findPreference(Key.about)!!.summary = getString(R.string.about_title, BuildConfig.VERSION_NAME)
diff --git a/tv/src/main/res/xml/pref_main.xml b/tv/src/main/res/xml/pref_main.xml
index 1e60152712..af2f33c139 100644
--- a/tv/src/main/res/xml/pref_main.xml
+++ b/tv/src/main/res/xml/pref_main.xml
@@ -48,6 +48,10 @@
app:key="portTransproxy"
app:title="@string/port_transproxy"
app:useSimpleSummaryProvider="true"/>
+