Commit fbe8af61 authored by Mygod's avatar Mygod

Refine cancelling of HttpUrlConnection

parent cd199278
......@@ -32,10 +32,7 @@ import com.github.shadowsocks.database.ProfileManager
import com.github.shadowsocks.plugin.PluginConfiguration
import com.github.shadowsocks.plugin.PluginManager
import com.github.shadowsocks.preference.DataStore
import com.github.shadowsocks.utils.DirectBoot
import com.github.shadowsocks.utils.disconnectFromMain
import com.github.shadowsocks.utils.parseNumericAddress
import com.github.shadowsocks.utils.signaturesCompat
import com.github.shadowsocks.utils.*
import kotlinx.coroutines.*
import java.io.File
import java.io.IOException
......@@ -65,15 +62,11 @@ class ProxyInstance(val profile: Profile, private val route: String = profile.ro
conn.requestMethod = "POST"
conn.doOutput = true
val proxies = try {
withContext(Dispatchers.IO) {
conn.outputStream.bufferedWriter().use {
val proxies = conn.useCancellable {
outputStream.bufferedWriter().use {
it.write("sig=" + Base64.encodeToString(mdg.digest(), Base64.DEFAULT))
}
conn.inputStream.bufferedReader().readText()
}
} finally {
conn.disconnectFromMain()
inputStream.bufferedReader().readText()
}.split('|').toMutableList()
proxies.shuffle()
val proxy = proxies.first().split(':')
......
......@@ -30,8 +30,11 @@ import com.github.shadowsocks.acl.Acl
import com.github.shadowsocks.core.R
import com.github.shadowsocks.preference.DataStore
import com.github.shadowsocks.utils.Key
import com.github.shadowsocks.utils.disconnectFromMain
import kotlinx.coroutines.*
import com.github.shadowsocks.utils.useCancellable
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import java.io.IOException
import java.net.HttpURLConnection
import java.net.Proxy
......@@ -75,7 +78,7 @@ class HttpsTest : ViewModel() {
}
}
private var running: Pair<HttpURLConnection, Job>? = null
private var running: Job? = null
val status = MutableLiveData<Status>().apply { value = Status.Idle }
fun testConnection() {
......@@ -91,26 +94,25 @@ class HttpsTest : ViewModel() {
conn.setRequestProperty("Connection", "close")
conn.instanceFollowRedirects = false
conn.useCaches = false
running = conn to GlobalScope.launch(Dispatchers.Main.immediate) {
status.value = withContext(Dispatchers.IO) {
running = GlobalScope.launch(Dispatchers.Main.immediate) {
status.value = conn.useCancellable {
try {
val start = SystemClock.elapsedRealtime()
val code = conn.responseCode
val code = responseCode
val elapsed = SystemClock.elapsedRealtime() - start
if (code == 204 || code == 200 && conn.responseLength == 0L) Status.Success(elapsed)
if (code == 204 || code == 200 && responseLength == 0L) Status.Success(elapsed)
else Status.Error.UnexpectedResponseCode(code)
} catch (e: IOException) {
Status.Error.IOFailure(e)
} finally {
conn.disconnect()
disconnect()
}
}
}
}
private fun cancelTest() = running?.let { (conn, job) ->
job.cancel() // ensure job is cancelled before interrupting
conn.disconnectFromMain()
private fun cancelTest() {
running?.cancel()
running = null
}
......
......@@ -36,11 +36,10 @@ import android.util.TypedValue
import androidx.annotation.AttrRes
import androidx.preference.Preference
import com.crashlytics.android.Crashlytics
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.*
import java.net.HttpURLConnection
import java.net.InetAddress
import kotlin.coroutines.resume
val Throwable.readableMessage get() = localizedMessage ?: javaClass.name
......@@ -60,8 +59,13 @@ fun String.parseNumericAddress(): InetAddress? = Os.inet_pton(OsConstants.AF_INE
fun <K, V> MutableMap<K, V>.computeIfAbsentCompat(key: K, value: () -> V) = if (Build.VERSION.SDK_INT >= 24)
computeIfAbsent(key) { value() } else this[key] ?: value().also { put(key, it) }
fun HttpURLConnection.disconnectFromMain() {
if (Build.VERSION.SDK_INT >= 26) disconnect() else GlobalScope.launch(Dispatchers.IO) { disconnect() }
suspend fun <T> HttpURLConnection.useCancellable(block: HttpURLConnection.() -> T) = withContext(Dispatchers.IO) {
suspendCancellableCoroutine<T> { cont ->
cont.invokeOnCancellation {
if (Build.VERSION.SDK_INT >= 26) disconnect() else launch(Dispatchers.IO) { disconnect() }
}
cont.resume(block())
}
}
fun parsePort(str: String?, default: Int, min: Int = 1025): Int {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment