This commit is contained in:
Horis 2024-03-29 12:39:43 +08:00
parent 68eddefb94
commit 9c50621895
7 changed files with 53 additions and 44 deletions

View File

@ -255,6 +255,12 @@
# 繁简转换 # 繁简转换
-keep class com.github.liuyueyi.quick.transfer.** {*;} -keep class com.github.liuyueyi.quick.transfer.** {*;}
# Cronet
-keep class org.chromium.net.X509Util {
private static sDefaultTrustManager;
private static sTestTrustManager;
}
# Class.forName调用 # Class.forName调用
-keep class io.legado.app.lib.cronet.CronetInterceptor{*;} -keep class io.legado.app.lib.cronet.CronetInterceptor{*;}
-keep class io.legado.app.lib.cronet.CronetLoader{*;} -keep class io.legado.app.lib.cronet.CronetLoader{*;}

View File

@ -4,7 +4,6 @@ import io.legado.app.constant.AppConst
import io.legado.app.help.CacheManager import io.legado.app.help.CacheManager
import io.legado.app.help.config.AppConfig import io.legado.app.help.config.AppConfig
import io.legado.app.help.http.CookieManager.cookieJarHeader import io.legado.app.help.http.CookieManager.cookieJarHeader
import io.legado.app.utils.GzipSourceCompat
import io.legado.app.utils.NetworkUtils import io.legado.app.utils.NetworkUtils
import okhttp3.ConnectionSpec import okhttp3.ConnectionSpec
import okhttp3.Cookie import okhttp3.Cookie
@ -16,12 +15,14 @@ import okhttp3.OkHttpClient
import okhttp3.internal.http.RealResponseBody import okhttp3.internal.http.RealResponseBody
import okhttp3.internal.http.promisesBody import okhttp3.internal.http.promisesBody
import okio.buffer import okio.buffer
import okio.source
import java.net.InetSocketAddress import java.net.InetSocketAddress
import java.net.Proxy import java.net.Proxy
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ThreadFactory import java.util.concurrent.ThreadFactory
import java.util.concurrent.ThreadPoolExecutor import java.util.concurrent.ThreadPoolExecutor
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import java.util.zip.GZIPInputStream
private val proxyClientCache: ConcurrentHashMap<String, OkHttpClient> by lazy { private val proxyClientCache: ConcurrentHashMap<String, OkHttpClient> by lazy {
ConcurrentHashMap() ConcurrentHashMap()
@ -123,7 +124,7 @@ val okHttpClient: OkHttpClient by lazy {
&& response.promisesBody() && responseBody != null && response.promisesBody() && responseBody != null
) { ) {
val responseBuilder = response.newBuilder() val responseBuilder = response.newBuilder()
val gzipSource = GzipSourceCompat(responseBody.source()) val gzipSource = GZIPInputStream(responseBody.byteStream()).source()
val strippedHeaders = response.headers.newBuilder() val strippedHeaders = response.headers.newBuilder()
.removeAll("Content-Encoding") .removeAll("Content-Encoding")
.removeAll("Content-Length") .removeAll("Content-Length")

View File

@ -1,6 +1,7 @@
package io.legado.app.help.http package io.legado.app.help.http
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.net.http.X509TrustManagerExtensions
import io.legado.app.utils.printOnDebug import io.legado.app.utils.printOnDebug
@ -38,11 +39,19 @@ object SSLHelper {
//do nothing接受任意客户端证书 //do nothing接受任意客户端证书
} }
fun checkServerTrusted(chain: Array<X509Certificate>, authType: String, host: String): List<X509Certificate> {
return chain.toList()
}
override fun getAcceptedIssuers(): Array<X509Certificate> { override fun getAcceptedIssuers(): Array<X509Certificate> {
return arrayOf() return arrayOf()
} }
} }
val unsafeTrustManagerExtensions by lazy {
X509TrustManagerExtensions(unsafeTrustManager)
}
val unsafeSSLSocketFactory: SSLSocketFactory by lazy { val unsafeSSLSocketFactory: SSLSocketFactory by lazy {
try { try {
val sslContext = SSLContext.getInstance("SSL") val sslContext = SSLContext.getInstance("SSL")

View File

@ -6,6 +6,7 @@ package io.legado.app.lib.cronet
import androidx.annotation.Keep import androidx.annotation.Keep
import io.legado.app.constant.AppLog import io.legado.app.constant.AppLog
import io.legado.app.help.http.CookieManager.cookieJarHeader 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.help.http.okHttpClient
import io.legado.app.utils.DebugLog import io.legado.app.utils.DebugLog
import okhttp3.Headers 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.ExperimentalCronetEngine
import org.chromium.net.UploadDataProvider import org.chromium.net.UploadDataProvider
import org.chromium.net.UrlRequest import org.chromium.net.UrlRequest
import org.chromium.net.X509Util
import org.json.JSONObject import org.json.JSONObject
import splitties.init.appCtx import splitties.init.appCtx
@ -22,6 +24,7 @@ internal const val BUFFER_SIZE = 32 * 1024
val cronetEngine: ExperimentalCronetEngine? by lazy { val cronetEngine: ExperimentalCronetEngine? by lazy {
CronetLoader.preDownload() CronetLoader.preDownload()
disableCertificateVerify()
val builder = ExperimentalCronetEngine.Builder(appCtx).apply { val builder = ExperimentalCronetEngine.Builder(appCtx).apply {
if (CronetLoader.install()) { if (CronetLoader.install()) {
setLibraryLoader(CronetLoader)//设置自定义so库加载 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)
}
}

View File

@ -368,6 +368,7 @@ class TextChapterLayout(
} }
} }
val textLine = TextLine(isImage = true) val textLine = TextLine(isImage = true)
textLine.text = " "
textLine.lineTop = durY + paddingTop textLine.lineTop = durY + paddingTop
durY += height durY += height
textLine.lineBottom = durY + paddingTop textLine.lineBottom = durY + paddingTop

View File

@ -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()
}

View File

@ -4,17 +4,16 @@ import android.annotation.SuppressLint
import android.net.ConnectivityManager import android.net.ConnectivityManager
import android.net.NetworkCapabilities import android.net.NetworkCapabilities
import android.os.Build import android.os.Build
import cn.hutool.core.lang.Validator
import io.legado.app.constant.AppLog import io.legado.app.constant.AppLog
import okhttp3.internal.publicsuffix.PublicSuffixDatabase import okhttp3.internal.publicsuffix.PublicSuffixDatabase
import splitties.systemservices.connectivityManager import splitties.systemservices.connectivityManager
import java.net.InetAddress import java.net.InetAddress
import java.net.NetworkInterface import java.net.NetworkInterface
import java.net.SocketException import java.net.SocketException
import java.net.URL import java.net.URL
import java.util.* import java.util.BitSet
import java.util.Enumeration
import cn.hutool.core.lang.Validator
@Suppress("unused", "MemberVisibilityCanBePrivate") @Suppress("unused", "MemberVisibilityCanBePrivate")
object NetworkUtils { object NetworkUtils {
@ -190,28 +189,32 @@ object NetworkUtils {
* Get local Ip address. * Get local Ip address.
*/ */
fun getLocalIPAddress(): InetAddress? { fun getLocalIPAddress(): InetAddress? {
var enumeration: Enumeration<NetworkInterface>? = null val enumeration: Enumeration<NetworkInterface>
try { try {
enumeration = NetworkInterface.getNetworkInterfaces() enumeration = NetworkInterface.getNetworkInterfaces()
} catch (e: SocketException) { } catch (e: SocketException) {
e.printOnDebug() e.printOnDebug()
return null
} }
if (enumeration != null) { var fallbackAddress: InetAddress? = null
while (enumeration.hasMoreElements()) {
val nif = enumeration.nextElement() while (enumeration.hasMoreElements()) {
val addresses = nif.inetAddresses val nif = enumeration.nextElement()
if (addresses != null) { val addresses = nif.inetAddresses ?: continue
while (addresses.hasMoreElements()) { while (addresses.hasMoreElements()) {
val address = addresses.nextElement() val address = addresses.nextElement()
if (!address.isLoopbackAddress && isIPv4Address(address.hostAddress)) { if (!address.isLoopbackAddress && isIPv4Address(address.hostAddress)) {
return address if (nif.name?.startsWith("wl") == true) {
} return address
}
if (fallbackAddress == null) {
fallbackAddress = address
} }
} }
} }
} }
return null return fallbackAddress
} }
/** /**