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 324673c3a..f87085a9c 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 @@ -1,19 +1,11 @@ package io.legado.app.help.http import kotlinx.coroutines.suspendCancellableCoroutine -import okhttp3.Request -import okhttp3.Response import kotlin.coroutines.resume @Suppress("unused") object HttpHelper { - suspend fun newCall(builder: Request.Builder.() -> Unit, proxy: String? = null): Response { - val client = OkHttpHelper.getProxyClient(proxy) - val requestBuilder = Request.Builder().apply(builder) - return client.newCall(requestBuilder.build()).await() - } - suspend fun ajax(params: AjaxWebView.AjaxParams): StrResponse = suspendCancellableCoroutine { block -> val webView = AjaxWebView() diff --git a/app/src/main/java/io/legado/app/help/http/OkHttpHelper.kt b/app/src/main/java/io/legado/app/help/http/OkHttpHelper.kt index a97e784c8..dccf75d6b 100644 --- a/app/src/main/java/io/legado/app/help/http/OkHttpHelper.kt +++ b/app/src/main/java/io/legado/app/help/http/OkHttpHelper.kt @@ -13,6 +13,10 @@ import java.util.concurrent.TimeUnit import kotlin.coroutines.resume import kotlin.coroutines.resumeWithException +private val proxyClientCache: ConcurrentHashMap by lazy { + ConcurrentHashMap() +} + val okHttpClient: OkHttpClient by lazy { val specs = arrayListOf( @@ -44,54 +48,53 @@ val okHttpClient: OkHttpClient by lazy { builder.build() } -object OkHttpHelper { - private val proxyClientCache: ConcurrentHashMap by lazy { - ConcurrentHashMap() +/** + * 缓存代理okHttp + */ +fun getProxyClient(proxy: String? = null): OkHttpClient { + if (proxy.isNullOrBlank()) { + return okHttpClient } - - /** - * 缓存代理okHttp - */ - fun getProxyClient(proxy: String? = null): OkHttpClient { - if (proxy.isNullOrBlank()) { - return okHttpClient - } - proxyClientCache[proxy]?.let { - return it - } - val r = Regex("(http|socks4|socks5)://(.*):(\\d{2,5})(@.*@.*)?") - val ms = r.findAll(proxy) - val group = ms.first() - var username = "" //代理服务器验证用户名 - var password = "" //代理服务器验证密码 - val type = if (group.groupValues[1] == "http") "http" else "socks" - val host = group.groupValues[2] - val port = group.groupValues[3].toInt() - if (group.groupValues[4] != "") { - username = group.groupValues[4].split("@")[1] - password = group.groupValues[4].split("@")[2] + proxyClientCache[proxy]?.let { + return it + } + val r = Regex("(http|socks4|socks5)://(.*):(\\d{2,5})(@.*@.*)?") + val ms = r.findAll(proxy) + val group = ms.first() + var username = "" //代理服务器验证用户名 + var password = "" //代理服务器验证密码 + val type = if (group.groupValues[1] == "http") "http" else "socks" + val host = group.groupValues[2] + val port = group.groupValues[3].toInt() + if (group.groupValues[4] != "") { + username = group.groupValues[4].split("@")[1] + password = group.groupValues[4].split("@")[2] + } + if (type != "direct" && host != "") { + val builder = okHttpClient.newBuilder() + if (type == "http") { + builder.proxy(Proxy(Proxy.Type.HTTP, InetSocketAddress(host, port))) + } else { + builder.proxy(Proxy(Proxy.Type.SOCKS, InetSocketAddress(host, port))) } - if (type != "direct" && host != "") { - val builder = okHttpClient.newBuilder() - if (type == "http") { - builder.proxy(Proxy(Proxy.Type.HTTP, InetSocketAddress(host, port))) - } else { - builder.proxy(Proxy(Proxy.Type.SOCKS, InetSocketAddress(host, port))) - } - if (username != "" && password != "") { - builder.proxyAuthenticator { _, response -> //设置代理服务器账号密码 - val credential: String = Credentials.basic(username, password) - response.request.newBuilder() - .header("Proxy-Authorization", credential) - .build() - } + if (username != "" && password != "") { + builder.proxyAuthenticator { _, response -> //设置代理服务器账号密码 + val credential: String = Credentials.basic(username, password) + response.request.newBuilder() + .header("Proxy-Authorization", credential) + .build() } - val proxyClient = builder.build() - proxyClientCache[proxy] = proxyClient - return proxyClient } - return okHttpClient + val proxyClient = builder.build() + proxyClientCache[proxy] = proxyClient + return proxyClient } + return okHttpClient +} + +fun OkHttpClient.newCall(builder: Request.Builder.() -> Unit): Call { + val requestBuilder = Request.Builder().apply(builder) + return this.newCall(requestBuilder.build()) } suspend fun Call.await(): Response = suspendCancellableCoroutine { block -> diff --git a/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt b/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt index c98ee33d4..1cc1220bc 100644 --- a/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt +++ b/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt @@ -1,7 +1,7 @@ package io.legado.app.lib.webdav -import io.legado.app.help.http.HttpHelper import io.legado.app.help.http.await +import io.legado.app.help.http.newCall import io.legado.app.help.http.okHttpClient import okhttp3.* import okhttp3.MediaType.Companion.toMediaType @@ -21,17 +21,19 @@ class WebDav(urlStr: String) { companion object { // 指定返回哪些属性 private const val DIR = - """ - - - - - - - - %s - - """ + """ + + + + + + + + + %s + + + """ } private val url: URL = URL(urlStr) @@ -92,7 +94,7 @@ class WebDav(urlStr: String) { } @Throws(IOException::class) - private suspend fun propFindResponse(propsList: ArrayList, depth: Int = 1): Response? { + private suspend fun propFindResponse(propsList: ArrayList): Response? { val requestProps = StringBuilder() for (p in propsList) { requestProps.append("\n") @@ -102,19 +104,17 @@ class WebDav(urlStr: String) { } else { String.format(DIR, requestProps.toString() + "\n") } - httpUrl?.let { url -> - // 添加RequestBody对象,可以只返回的属性。如果设为null,则会返回全部属性 - // 注意:尽量手动指定需要返回的属性。若返回全部属性,可能后由于Prop.java里没有该属性名,而崩溃。 - val requestBody = requestPropsStr.toRequestBody("text/plain".toMediaType()) - val request = Request.Builder() - .url(url) - .method("PROPFIND", requestBody) - - HttpAuth.auth?.let { - request.header("Authorization", Credentials.basic(it.user, it.pass)) - } - request.header("Depth", if (depth < 0) "infinity" else depth.toString()) - return okHttpClient.newCall(request.build()).await() + val url = httpUrl + val auth = HttpAuth.auth + if (url != null && auth != null) { + return okHttpClient.newCall { + url(url) + addHeader("Authorization", Credentials.basic(auth.user, auth.pass)) + // 添加RequestBody对象,可以只返回的属性。如果设为null,则会返回全部属性 + // 注意:尽量手动指定需要返回的属性。若返回全部属性,可能后由于Prop.java里没有该属性名,而崩溃。 + val requestBody = requestPropsStr.toRequestBody("text/plain".toMediaType()) + method("PROPFIND", requestBody) + }.await() } return null } @@ -159,11 +159,14 @@ class WebDav(urlStr: String) { * @return 是否创建成功 */ suspend fun makeAsDir(): Boolean { - httpUrl?.let { url -> - val request = Request.Builder() - .url(url) - .method("MKCOL", null) - return execRequest(request) + val url = httpUrl + val auth = HttpAuth.auth + if (url != null && auth != null) { + return okHttpClient.newCall { + url(url) + method("MKCOL", null) + addHeader("Authorization", Credentials.basic(auth.user, auth.pass)) + }.await().isSuccessful } return false } @@ -197,11 +200,14 @@ class WebDav(urlStr: String) { if (!file.exists()) return false // 务必注意RequestBody不要嵌套,不然上传时内容可能会被追加多余的文件信息 val fileBody = file.asRequestBody(contentType?.toMediaType()) - httpUrl?.let { - val request = Request.Builder() - .url(it) - .put(fileBody) - return execRequest(request) + val url = httpUrl + val auth = HttpAuth.auth + if (url != null && auth != null) { + return okHttpClient.newCall { + url(url) + put(fileBody) + addHeader("Authorization", Credentials.basic(auth.user, auth.pass)) + }.await().isSuccessful } return false } @@ -209,38 +215,27 @@ class WebDav(urlStr: String) { suspend fun upload(byteArray: ByteArray, contentType: String? = null): Boolean { // 务必注意RequestBody不要嵌套,不然上传时内容可能会被追加多余的文件信息 val fileBody = byteArray.toRequestBody(contentType?.toMediaType()) - httpUrl?.let { - val request = Request.Builder() - .url(it) - .put(fileBody) - return execRequest(request) + val url = httpUrl + val auth = HttpAuth.auth + if (url != null && auth != null) { + return okHttpClient.newCall { + url(url) + put(fileBody) + addHeader("Authorization", Credentials.basic(auth.user, auth.pass)) + }.await().isSuccessful } return false } - /** - * 执行请求,获取响应结果 - * @param requestBuilder 因为还需要追加验证信息,所以此处传递Request.Builder的对象,而不是Request的对象 - * @return 请求执行的结果 - */ - @Throws(IOException::class) - private suspend fun execRequest(requestBuilder: Request.Builder): Boolean { - HttpAuth.auth?.let { - requestBuilder.header("Authorization", Credentials.basic(it.user, it.pass)) - } - val response = okHttpClient.newCall(requestBuilder.build()).await() - return response.isSuccessful - } - @Throws(IOException::class) private suspend fun getInputStream(): InputStream? { val url = httpUrl val auth = HttpAuth.auth if (url != null && auth != null) { - return HttpHelper.newCall({ + return okHttpClient.newCall { url(url) addHeader("Authorization", Credentials.basic(auth.user, auth.pass)) - }).body?.byteStream() + }.await().body?.byteStream() } return null } diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt index 0dc588990..d61ca7633 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt @@ -312,14 +312,14 @@ class AnalyzeUrl( if (fieldMap.isNotEmpty() || body.isNullOrBlank()) { RxHttp.postForm(url) .setAssemblyEnabled(false) - .setOkClient(OkHttpHelper.getProxyClient(proxy)) + .setOkClient(getProxyClient(proxy)) .addAllEncoded(fieldMap) .addAllHeader(headerMap) .toStrResponse().await() } else { RxHttp.postJson(url) .setAssemblyEnabled(false) - .setOkClient(OkHttpHelper.getProxyClient(proxy)) + .setOkClient(getProxyClient(proxy)) .addAll(body) .addAllHeader(headerMap) .toStrResponse().await() @@ -327,7 +327,7 @@ class AnalyzeUrl( } else -> RxHttp.get(url) .setAssemblyEnabled(false) - .setOkClient(OkHttpHelper.getProxyClient(proxy)) + .setOkClient(getProxyClient(proxy)) .addAllEncoded(fieldMap) .addAllHeader(headerMap) .toStrResponse().await() @@ -341,14 +341,14 @@ class AnalyzeUrl( if (fieldMap.isNotEmpty() || body.isNullOrBlank()) { RxHttp.postForm(url) .setAssemblyEnabled(false) - .setOkClient(OkHttpHelper.getProxyClient(proxy)) + .setOkClient(getProxyClient(proxy)) .addAllEncoded(fieldMap) .addAllHeader(headerMap) .toByteArray().await() } else { RxHttp.postJson(url) .setAssemblyEnabled(false) - .setOkClient(OkHttpHelper.getProxyClient(proxy)) + .setOkClient(getProxyClient(proxy)) .addAll(body) .addAllHeader(headerMap) .toByteArray().await() @@ -356,7 +356,7 @@ class AnalyzeUrl( } else -> RxHttp.get(url) .setAssemblyEnabled(false) - .setOkClient(OkHttpHelper.getProxyClient(proxy)) + .setOkClient(getProxyClient(proxy)) .addAllEncoded(fieldMap) .addAllHeader(headerMap) .toByteArray().await()