mirror of
https://github.com/gedoor/legado.git
synced 2024-07-19 01:17:25 +08:00
Compare commits
2 Commits
a2ada281d8
...
eaea482827
Author | SHA1 | Date | |
---|---|---|---|
|
eaea482827 | ||
|
aebdd9f946 |
@ -133,7 +133,10 @@ object ExoPlayerHelper {
|
|||||||
* Okhttp DataSource.Factory
|
* Okhttp DataSource.Factory
|
||||||
*/
|
*/
|
||||||
private val okhttpDataFactory by lazy {
|
private val okhttpDataFactory by lazy {
|
||||||
OkHttpDataSource.Factory(okHttpClient)
|
val client = okHttpClient.newBuilder()
|
||||||
|
.callTimeout(0, TimeUnit.SECONDS)
|
||||||
|
.build()
|
||||||
|
OkHttpDataSource.Factory(client)
|
||||||
.setCacheControl(CacheControl.Builder().maxAge(1, TimeUnit.DAYS).build())
|
.setCacheControl(CacheControl.Builder().maxAge(1, TimeUnit.DAYS).build())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ import java.util.concurrent.atomic.AtomicBoolean
|
|||||||
abstract class AbsCallBack(
|
abstract class AbsCallBack(
|
||||||
var originalRequest: Request,
|
var originalRequest: Request,
|
||||||
val mCall: Call,
|
val mCall: Call,
|
||||||
|
var readTimeoutMillis: Int,
|
||||||
private val eventListener: EventListener? = null,
|
private val eventListener: EventListener? = null,
|
||||||
private val responseCallback: Callback? = null
|
private val responseCallback: Callback? = null
|
||||||
) : UrlRequest.Callback() {
|
) : UrlRequest.Callback() {
|
||||||
@ -52,6 +53,9 @@ abstract class AbsCallBack(
|
|||||||
private var redirectRequest: Request? = null
|
private var redirectRequest: Request? = null
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
if (readTimeoutMillis == 0) {
|
||||||
|
readTimeoutMillis = Int.MAX_VALUE
|
||||||
|
}
|
||||||
if (originalRequest.header(cookieJarHeader) != null) {
|
if (originalRequest.header(cookieJarHeader) != null) {
|
||||||
enableCookieJar = true
|
enableCookieJar = true
|
||||||
originalRequest = originalRequest.newBuilder()
|
originalRequest = originalRequest.newBuilder()
|
||||||
@ -411,7 +415,7 @@ abstract class AbsCallBack(
|
|||||||
|
|
||||||
private var buffer = ByteBuffer.allocateDirect(32 * 1024)
|
private var buffer = ByteBuffer.allocateDirect(32 * 1024)
|
||||||
private var closed = false
|
private var closed = false
|
||||||
private val timeout = mCall.timeout().timeoutNanos()
|
private val timeout = readTimeoutMillis.toLong()
|
||||||
|
|
||||||
override fun close() {
|
override fun close() {
|
||||||
cancelJob?.cancel()
|
cancelJob?.cancel()
|
||||||
@ -443,7 +447,7 @@ abstract class AbsCallBack(
|
|||||||
|
|
||||||
request?.read(buffer)
|
request?.read(buffer)
|
||||||
|
|
||||||
val result = callbackResults.poll(timeout, TimeUnit.NANOSECONDS)
|
val result = callbackResults.poll(timeout, TimeUnit.MILLISECONDS)
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
request?.cancel()
|
request?.cancel()
|
||||||
throw IOException("Body Read Timeout")
|
throw IOException("Body Read Timeout")
|
||||||
|
@ -5,7 +5,12 @@ import io.legado.app.utils.printOnDebug
|
|||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||||
import kotlinx.coroutines.withTimeout
|
import kotlinx.coroutines.withTimeout
|
||||||
import okhttp3.*
|
import okhttp3.Call
|
||||||
|
import okhttp3.CookieJar
|
||||||
|
import okhttp3.HttpUrl
|
||||||
|
import okhttp3.Interceptor
|
||||||
|
import okhttp3.Request
|
||||||
|
import okhttp3.Response
|
||||||
import okhttp3.internal.http.receiveHeaders
|
import okhttp3.internal.http.receiveHeaders
|
||||||
import org.chromium.net.UrlRequest
|
import org.chromium.net.UrlRequest
|
||||||
import org.chromium.net.UrlResponseInfo
|
import org.chromium.net.UrlResponseInfo
|
||||||
@ -43,12 +48,12 @@ class CronetCoroutineInterceptor(private val cookieJar: CookieJar) : Interceptor
|
|||||||
runBlocking() {
|
runBlocking() {
|
||||||
if (timeout > 0) {
|
if (timeout > 0) {
|
||||||
withTimeout(timeout) {
|
withTimeout(timeout) {
|
||||||
proceedWithCronet(newReq, chain.call()).also { response ->
|
proceedWithCronet(newReq, chain.call(), chain.readTimeoutMillis()).also { response ->
|
||||||
cookieJar.receiveHeaders(newReq.url, response.headers)
|
cookieJar.receiveHeaders(newReq.url, response.headers)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
proceedWithCronet(newReq, chain.call()).also { response ->
|
proceedWithCronet(newReq, chain.call(), chain.readTimeoutMillis()).also { response ->
|
||||||
cookieJar.receiveHeaders(newReq.url, response.headers)
|
cookieJar.receiveHeaders(newReq.url, response.headers)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -68,10 +73,14 @@ class CronetCoroutineInterceptor(private val cookieJar: CookieJar) : Interceptor
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private suspend fun proceedWithCronet(request: Request, call: Call): Response =
|
private suspend fun proceedWithCronet(
|
||||||
|
request: Request,
|
||||||
|
call: Call,
|
||||||
|
readTimeoutMillis: Int
|
||||||
|
): Response =
|
||||||
suspendCancellableCoroutine<Response> { coroutine ->
|
suspendCancellableCoroutine<Response> { coroutine ->
|
||||||
|
|
||||||
val callBack = object : AbsCallBack(originalRequest = request, mCall = call) {
|
val callBack = object : AbsCallBack(request, call, readTimeoutMillis) {
|
||||||
override fun waitForDone(urlRequest: UrlRequest): Response {
|
override fun waitForDone(urlRequest: UrlRequest): Response {
|
||||||
TODO("Not yet implemented")
|
TODO("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ class CronetInterceptor(private val cookieJar: CookieJar) : Interceptor {
|
|||||||
builder.removeHeader("Accept-Encoding")
|
builder.removeHeader("Accept-Encoding")
|
||||||
|
|
||||||
val newReq = builder.build()
|
val newReq = builder.build()
|
||||||
proceedWithCronet(newReq, chain.call())/*?.let { response ->
|
proceedWithCronet(newReq, chain.call(), chain.readTimeoutMillis())/*?.let { response ->
|
||||||
//从Response 中保存Cookie到CookieJar
|
//从Response 中保存Cookie到CookieJar
|
||||||
//cookieJar.receiveHeaders(newReq.url, response.headers)
|
//cookieJar.receiveHeaders(newReq.url, response.headers)
|
||||||
response
|
response
|
||||||
@ -45,11 +45,11 @@ class CronetInterceptor(private val cookieJar: CookieJar) : Interceptor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("ObsoleteSdkInt")
|
@SuppressLint("ObsoleteSdkInt")
|
||||||
private fun proceedWithCronet(request: Request, call: Call): Response? {
|
private fun proceedWithCronet(request: Request, call: Call, readTimeoutMillis: Int): Response? {
|
||||||
val callBack = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
val callBack = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
NewCallBack(request, call)
|
NewCallBack(request, call, readTimeoutMillis)
|
||||||
} else {
|
} else {
|
||||||
OldCallback(request, call)
|
OldCallback(request, call, readTimeoutMillis)
|
||||||
}
|
}
|
||||||
buildRequest(request, callBack)?.runCatching {
|
buildRequest(request, callBack)?.runCatching {
|
||||||
return callBack.waitForDone(this)
|
return callBack.waitForDone(this)
|
||||||
|
@ -15,7 +15,8 @@ import java.util.concurrent.TimeUnit
|
|||||||
@SuppressLint("ObsoleteSdkInt")
|
@SuppressLint("ObsoleteSdkInt")
|
||||||
@Keep
|
@Keep
|
||||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||||
class NewCallBack(originalRequest: Request, mCall: Call) : AbsCallBack(originalRequest, mCall) {
|
class NewCallBack(originalRequest: Request, mCall: Call, readTimeoutMillis: Int) :
|
||||||
|
AbsCallBack(originalRequest, mCall, readTimeoutMillis) {
|
||||||
|
|
||||||
private val responseFuture = CompletableFuture<Response>()
|
private val responseFuture = CompletableFuture<Response>()
|
||||||
|
|
||||||
|
@ -9,7 +9,8 @@ import org.chromium.net.UrlRequest
|
|||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
|
||||||
@Keep
|
@Keep
|
||||||
class OldCallback(originalRequest: Request, mCall: Call) : AbsCallBack(originalRequest, mCall) {
|
class OldCallback(originalRequest: Request, mCall: Call, readTimeoutMillis: Int) :
|
||||||
|
AbsCallBack(originalRequest, mCall, readTimeoutMillis) {
|
||||||
|
|
||||||
private val mResponseCondition = ConditionVariable()
|
private val mResponseCondition = ConditionVariable()
|
||||||
private var mException: IOException? = null
|
private var mException: IOException? = null
|
||||||
|
@ -30,6 +30,7 @@ import java.net.URLEncoder
|
|||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
import java.time.ZoneOffset
|
import java.time.ZoneOffset
|
||||||
import java.time.format.DateTimeFormatter
|
import java.time.format.DateTimeFormatter
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
@Suppress("unused", "MemberVisibilityCanBePrivate")
|
@Suppress("unused", "MemberVisibilityCanBePrivate")
|
||||||
open class WebDav(
|
open class WebDav(
|
||||||
@ -97,6 +98,7 @@ open class WebDav(
|
|||||||
chain.proceed(request)
|
chain.proceed(request)
|
||||||
}
|
}
|
||||||
okHttpClient.newBuilder().run {
|
okHttpClient.newBuilder().run {
|
||||||
|
callTimeout(0, TimeUnit.SECONDS)
|
||||||
interceptors().add(0, authInterceptor)
|
interceptors().add(0, authInterceptor)
|
||||||
addNetworkInterceptor(authInterceptor)
|
addNetworkInterceptor(authInterceptor)
|
||||||
build()
|
build()
|
||||||
|
@ -27,12 +27,15 @@ import io.legado.app.utils.*
|
|||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import okhttp3.MediaType.Companion.toMediaType
|
import okhttp3.MediaType.Companion.toMediaType
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.RequestBody.Companion.toRequestBody
|
import okhttp3.RequestBody.Companion.toRequestBody
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import java.io.ByteArrayInputStream
|
import java.io.ByteArrayInputStream
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.net.URLEncoder
|
import java.net.URLEncoder
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
import java.util.regex.Pattern
|
import java.util.regex.Pattern
|
||||||
|
import kotlin.math.max
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by GKF on 2018/1/24.
|
* Created by GKF on 2018/1/24.
|
||||||
@ -51,6 +54,7 @@ class AnalyzeUrl(
|
|||||||
private val source: BaseSource? = null,
|
private val source: BaseSource? = null,
|
||||||
private val ruleData: RuleDataInterface? = null,
|
private val ruleData: RuleDataInterface? = null,
|
||||||
private val chapter: BookChapter? = null,
|
private val chapter: BookChapter? = null,
|
||||||
|
private val readTimeout: Long? = null,
|
||||||
headerMapF: Map<String, String>? = null,
|
headerMapF: Map<String, String>? = null,
|
||||||
) : JsExtensions {
|
) : JsExtensions {
|
||||||
companion object {
|
companion object {
|
||||||
@ -404,7 +408,7 @@ class AnalyzeUrl(
|
|||||||
if (this.useWebView && useWebView) {
|
if (this.useWebView && useWebView) {
|
||||||
strResponse = when (method) {
|
strResponse = when (method) {
|
||||||
RequestMethod.POST -> {
|
RequestMethod.POST -> {
|
||||||
val res = getProxyClient(proxy).newCallStrResponse(retry) {
|
val res = getClient().newCallStrResponse(retry) {
|
||||||
addHeaders(headerMap)
|
addHeaders(headerMap)
|
||||||
url(urlNoQuery)
|
url(urlNoQuery)
|
||||||
if (fieldMap.isNotEmpty() || body.isNullOrBlank()) {
|
if (fieldMap.isNotEmpty() || body.isNullOrBlank()) {
|
||||||
@ -432,7 +436,7 @@ class AnalyzeUrl(
|
|||||||
).getStrResponse()
|
).getStrResponse()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
strResponse = getProxyClient(proxy).newCallStrResponse(retry) {
|
strResponse = getClient().newCallStrResponse(retry) {
|
||||||
addHeaders(headerMap)
|
addHeaders(headerMap)
|
||||||
when (method) {
|
when (method) {
|
||||||
RequestMethod.POST -> {
|
RequestMethod.POST -> {
|
||||||
@ -484,7 +488,7 @@ class AnalyzeUrl(
|
|||||||
val concurrentRecord = getConcurrentRecord()
|
val concurrentRecord = getConcurrentRecord()
|
||||||
try {
|
try {
|
||||||
setCookie()
|
setCookie()
|
||||||
val response = getProxyClient(proxy).newCallResponse(retry) {
|
val response = getClient().newCallResponse(retry) {
|
||||||
addHeaders(headerMap)
|
addHeaders(headerMap)
|
||||||
when (method) {
|
when (method) {
|
||||||
RequestMethod.POST -> {
|
RequestMethod.POST -> {
|
||||||
@ -511,15 +515,24 @@ class AnalyzeUrl(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getClient(): OkHttpClient {
|
||||||
|
val client = getProxyClient(proxy)
|
||||||
|
if (readTimeout == null) {
|
||||||
|
return client
|
||||||
|
}
|
||||||
|
return client.newBuilder()
|
||||||
|
.readTimeout(readTimeout, TimeUnit.MILLISECONDS)
|
||||||
|
.callTimeout(max(60 * 1000L, readTimeout * 2), TimeUnit.MILLISECONDS)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
fun getResponse(): Response {
|
fun getResponse(): Response {
|
||||||
return runBlocking {
|
return runBlocking {
|
||||||
getResponseAwait()
|
getResponseAwait()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UnnecessaryVariable")
|
|
||||||
private fun getByteArrayIfDataUri(): ByteArray? {
|
private fun getByteArrayIfDataUri(): ByteArray? {
|
||||||
@Suppress("RegExpRedundantEscape")
|
|
||||||
val dataUriFindResult = dataUriRegex.find(urlNoQuery)
|
val dataUriFindResult = dataUriRegex.find(urlNoQuery)
|
||||||
if (dataUriFindResult != null) {
|
if (dataUriFindResult != null) {
|
||||||
val dataUriBase64 = dataUriFindResult.groupValues[1]
|
val dataUriBase64 = dataUriFindResult.groupValues[1]
|
||||||
|
@ -167,7 +167,8 @@ class HttpReadAloudService : BaseReadAloudService(),
|
|||||||
speakText = speakText,
|
speakText = speakText,
|
||||||
speakSpeed = speechRate,
|
speakSpeed = speechRate,
|
||||||
source = httpTts,
|
source = httpTts,
|
||||||
headerMapF = httpTts.getHeaderMap(true)
|
headerMapF = httpTts.getHeaderMap(true),
|
||||||
|
readTimeout = 300 * 1000L
|
||||||
)
|
)
|
||||||
var response = analyzeUrl.getResponseAwait()
|
var response = analyzeUrl.getResponseAwait()
|
||||||
coroutineContext.ensureActive()
|
coroutineContext.ensureActive()
|
||||||
|
Loading…
Reference in New Issue
Block a user