From 9c50621895b554964a890595c8e70db1c8bfa271 Mon Sep 17 00:00:00 2001 From: Horis <821938089@qq.com> Date: Fri, 29 Mar 2024 12:39:43 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/proguard-rules.pro | 6 ++++ .../io/legado/app/help/http/HttpHelper.kt | 5 +-- .../java/io/legado/app/help/http/SSLHelper.kt | 9 +++++ .../io/legado/app/lib/cronet/CronetHelper.kt | 15 ++++++++ .../read/page/provider/TextChapterLayout.kt | 1 + .../io/legado/app/utils/GzipSourceCompat.kt | 26 -------------- .../java/io/legado/app/utils/NetworkUtils.kt | 35 ++++++++++--------- 7 files changed, 53 insertions(+), 44 deletions(-) delete mode 100644 app/src/main/java/io/legado/app/utils/GzipSourceCompat.kt diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 0c0f10985..a1751bc72 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -255,6 +255,12 @@ # 繁简转换 -keep class com.github.liuyueyi.quick.transfer.** {*;} +# Cronet +-keep class org.chromium.net.X509Util { + private static sDefaultTrustManager; + private static sTestTrustManager; +} + # Class.forName调用 -keep class io.legado.app.lib.cronet.CronetInterceptor{*;} -keep class io.legado.app.lib.cronet.CronetLoader{*;} diff --git a/app/src/main/java/io/legado/app/help/http/HttpHelper.kt b/app/src/main/java/io/legado/app/help/http/HttpHelper.kt index e479f0b4c..9c104f66b 100644 --- a/app/src/main/java/io/legado/app/help/http/HttpHelper.kt +++ b/app/src/main/java/io/legado/app/help/http/HttpHelper.kt @@ -4,7 +4,6 @@ import io.legado.app.constant.AppConst import io.legado.app.help.CacheManager import io.legado.app.help.config.AppConfig import io.legado.app.help.http.CookieManager.cookieJarHeader -import io.legado.app.utils.GzipSourceCompat import io.legado.app.utils.NetworkUtils import okhttp3.ConnectionSpec import okhttp3.Cookie @@ -16,12 +15,14 @@ import okhttp3.OkHttpClient import okhttp3.internal.http.RealResponseBody import okhttp3.internal.http.promisesBody import okio.buffer +import okio.source import java.net.InetSocketAddress import java.net.Proxy import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ThreadFactory import java.util.concurrent.ThreadPoolExecutor import java.util.concurrent.TimeUnit +import java.util.zip.GZIPInputStream private val proxyClientCache: ConcurrentHashMap by lazy { ConcurrentHashMap() @@ -123,7 +124,7 @@ val okHttpClient: OkHttpClient by lazy { && response.promisesBody() && responseBody != null ) { val responseBuilder = response.newBuilder() - val gzipSource = GzipSourceCompat(responseBody.source()) + val gzipSource = GZIPInputStream(responseBody.byteStream()).source() val strippedHeaders = response.headers.newBuilder() .removeAll("Content-Encoding") .removeAll("Content-Length") diff --git a/app/src/main/java/io/legado/app/help/http/SSLHelper.kt b/app/src/main/java/io/legado/app/help/http/SSLHelper.kt index a0f26f24f..e540282c7 100644 --- a/app/src/main/java/io/legado/app/help/http/SSLHelper.kt +++ b/app/src/main/java/io/legado/app/help/http/SSLHelper.kt @@ -1,6 +1,7 @@ package io.legado.app.help.http import android.annotation.SuppressLint +import android.net.http.X509TrustManagerExtensions import io.legado.app.utils.printOnDebug @@ -38,11 +39,19 @@ object SSLHelper { //do nothing,接受任意客户端证书 } + fun checkServerTrusted(chain: Array, authType: String, host: String): List { + return chain.toList() + } + override fun getAcceptedIssuers(): Array { return arrayOf() } } + val unsafeTrustManagerExtensions by lazy { + X509TrustManagerExtensions(unsafeTrustManager) + } + val unsafeSSLSocketFactory: SSLSocketFactory by lazy { try { val sslContext = SSLContext.getInstance("SSL") diff --git a/app/src/main/java/io/legado/app/lib/cronet/CronetHelper.kt b/app/src/main/java/io/legado/app/lib/cronet/CronetHelper.kt index 3e63bac22..80b1f45dd 100644 --- a/app/src/main/java/io/legado/app/lib/cronet/CronetHelper.kt +++ b/app/src/main/java/io/legado/app/lib/cronet/CronetHelper.kt @@ -6,6 +6,7 @@ package io.legado.app.lib.cronet import androidx.annotation.Keep import io.legado.app.constant.AppLog import io.legado.app.help.http.CookieManager.cookieJarHeader +import io.legado.app.help.http.SSLHelper import io.legado.app.help.http.okHttpClient import io.legado.app.utils.DebugLog import okhttp3.Headers @@ -15,6 +16,7 @@ import org.chromium.net.CronetEngine.Builder.HTTP_CACHE_DISK import org.chromium.net.ExperimentalCronetEngine import org.chromium.net.UploadDataProvider import org.chromium.net.UrlRequest +import org.chromium.net.X509Util import org.json.JSONObject import splitties.init.appCtx @@ -22,6 +24,7 @@ internal const val BUFFER_SIZE = 32 * 1024 val cronetEngine: ExperimentalCronetEngine? by lazy { CronetLoader.preDownload() + disableCertificateVerify() val builder = ExperimentalCronetEngine.Builder(appCtx).apply { if (CronetLoader.install()) { setLibraryLoader(CronetLoader)//设置自定义so库加载 @@ -103,3 +106,15 @@ fun buildRequest(request: Request, callback: UrlRequest.Callback): UrlRequest? { } +private fun disableCertificateVerify() { + runCatching { + val sDefaultTrustManager = X509Util::class.java.getDeclaredField("sTestTrustManager") + sDefaultTrustManager.isAccessible = true + sDefaultTrustManager.set(null, SSLHelper.unsafeTrustManagerExtensions) + } + runCatching { + val sTestTrustManager = X509Util::class.java.getDeclaredField("sTestTrustManager") + sTestTrustManager.isAccessible = true + sTestTrustManager.set(null, SSLHelper.unsafeTrustManagerExtensions) + } +} diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/provider/TextChapterLayout.kt b/app/src/main/java/io/legado/app/ui/book/read/page/provider/TextChapterLayout.kt index daab964f4..cf0e81e01 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/provider/TextChapterLayout.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/provider/TextChapterLayout.kt @@ -368,6 +368,7 @@ class TextChapterLayout( } } val textLine = TextLine(isImage = true) + textLine.text = " " textLine.lineTop = durY + paddingTop durY += height textLine.lineBottom = durY + paddingTop diff --git a/app/src/main/java/io/legado/app/utils/GzipSourceCompat.kt b/app/src/main/java/io/legado/app/utils/GzipSourceCompat.kt deleted file mode 100644 index 5d23f42d1..000000000 --- a/app/src/main/java/io/legado/app/utils/GzipSourceCompat.kt +++ /dev/null @@ -1,26 +0,0 @@ -package io.legado.app.utils - -import okio.Buffer -import okio.EOFException -import okio.GzipSource -import okio.Source - -class GzipSourceCompat(source: Source) : Source { - private val delegate = GzipSource(source) - - override fun close() = delegate.close() - - override fun read(sink: Buffer, byteCount: Long): Long { - try { - return delegate.read(sink, byteCount) - } catch (e: EOFException) { - if (e.message == "source exhausted prematurely") { - return -1 - } - throw e - } - } - - override fun timeout() = delegate.timeout() - -} diff --git a/app/src/main/java/io/legado/app/utils/NetworkUtils.kt b/app/src/main/java/io/legado/app/utils/NetworkUtils.kt index 830437fd4..d74e88f32 100644 --- a/app/src/main/java/io/legado/app/utils/NetworkUtils.kt +++ b/app/src/main/java/io/legado/app/utils/NetworkUtils.kt @@ -4,17 +4,16 @@ import android.annotation.SuppressLint import android.net.ConnectivityManager import android.net.NetworkCapabilities import android.os.Build +import cn.hutool.core.lang.Validator import io.legado.app.constant.AppLog import okhttp3.internal.publicsuffix.PublicSuffixDatabase import splitties.systemservices.connectivityManager - import java.net.InetAddress import java.net.NetworkInterface import java.net.SocketException import java.net.URL -import java.util.* - -import cn.hutool.core.lang.Validator +import java.util.BitSet +import java.util.Enumeration @Suppress("unused", "MemberVisibilityCanBePrivate") object NetworkUtils { @@ -190,28 +189,32 @@ object NetworkUtils { * Get local Ip address. */ fun getLocalIPAddress(): InetAddress? { - var enumeration: Enumeration? = null + val enumeration: Enumeration try { enumeration = NetworkInterface.getNetworkInterfaces() } catch (e: SocketException) { e.printOnDebug() + return null } - if (enumeration != null) { - while (enumeration.hasMoreElements()) { - val nif = enumeration.nextElement() - val addresses = nif.inetAddresses - if (addresses != null) { - while (addresses.hasMoreElements()) { - val address = addresses.nextElement() - if (!address.isLoopbackAddress && isIPv4Address(address.hostAddress)) { - return address - } + var fallbackAddress: InetAddress? = null + + while (enumeration.hasMoreElements()) { + val nif = enumeration.nextElement() + val addresses = nif.inetAddresses ?: continue + while (addresses.hasMoreElements()) { + val address = addresses.nextElement() + if (!address.isLoopbackAddress && isIPv4Address(address.hostAddress)) { + if (nif.name?.startsWith("wl") == true) { + return address + } + if (fallbackAddress == null) { + fallbackAddress = address } } } } - return null + return fallbackAddress } /**