pull/737/head
Robot 5 years ago
commit a368ed651d
  1. 1
      app/build.gradle
  2. 34
      app/src/main/java/io/legado/app/help/http/CookieStore.kt
  3. 52
      app/src/main/java/io/legado/app/help/http/HttpHelper.kt
  4. 5
      app/src/main/java/io/legado/app/lib/webdav/WebDav.kt
  5. 12
      app/src/main/java/io/legado/app/ui/association/ImportBookSourceDialog.kt
  6. 27
      app/src/main/java/io/legado/app/utils/OkHttpExtensions.kt

@ -174,7 +174,6 @@ dependencies {
// //
implementation 'com.ljx.rxhttp:rxhttp:2.4.4-beta3' implementation 'com.ljx.rxhttp:rxhttp:2.4.4-beta3'
implementation 'com.squareup.okhttp3:okhttp:4.9.0' implementation 'com.squareup.okhttp3:okhttp:4.9.0'
implementation 'com.github.franmontiel:PersistentCookieJar:v1.0.1'
kapt 'com.ljx.rxhttp:rxhttp-compiler:2.4.4-beta3' kapt 'com.ljx.rxhttp:rxhttp-compiler:2.4.4-beta3'
//Glide //Glide

@ -3,14 +3,12 @@
package io.legado.app.help.http package io.legado.app.help.http
import android.text.TextUtils import android.text.TextUtils
import com.franmontiel.persistentcookiejar.persistence.CookiePersistor
import com.franmontiel.persistentcookiejar.persistence.SerializableCookie
import io.legado.app.App import io.legado.app.App
import io.legado.app.data.entities.Cookie import io.legado.app.data.entities.Cookie
import io.legado.app.help.http.api.CookieManager import io.legado.app.help.http.api.CookieManager
import io.legado.app.utils.NetworkUtils import io.legado.app.utils.NetworkUtils
object CookieStore : CookiePersistor, CookieManager { object CookieStore : CookieManager {
override fun setCookie(url: String, cookie: String?) { override fun setCookie(url: String, cookie: String?) {
val cookieBean = Cookie(NetworkUtils.getSubDomain(url), cookie ?: "") val cookieBean = Cookie(NetworkUtils.getSubDomain(url), cookie ?: "")
@ -78,36 +76,8 @@ object CookieStore : CookiePersistor, CookieManager {
return builder.deleteCharAt(builder.lastIndexOf(";")).toString() return builder.deleteCharAt(builder.lastIndexOf(";")).toString()
} }
override fun loadAll(): MutableList<okhttp3.Cookie> { fun clear() {
val cookies = arrayListOf<okhttp3.Cookie>()
App.db.cookieDao.getOkHttpCookies().forEach {
val serializedCookie = it.cookie
SerializableCookie().decode(serializedCookie)?.let { ck ->
cookies.add(ck)
}
}
return cookies
}
override fun saveAll(cookies: MutableCollection<okhttp3.Cookie>?) {
val mCookies = arrayListOf<Cookie>()
cookies?.forEach {
mCookies.add(Cookie(createCookieKey(it), SerializableCookie().encode(it)))
}
App.db.cookieDao.insert(*mCookies.toTypedArray())
}
override fun removeAll(cookies: MutableCollection<okhttp3.Cookie>?) {
cookies?.forEach {
App.db.cookieDao.delete(createCookieKey(it))
}
}
override fun clear() {
App.db.cookieDao.deleteOkHttp() App.db.cookieDao.deleteOkHttp()
} }
private fun createCookieKey(cookie: okhttp3.Cookie): String {
return (if (cookie.secure) "https" else "http") + "://" + cookie.domain + cookie.path + "|" + cookie.name
}
} }

@ -3,16 +3,19 @@ package io.legado.app.help.http
import io.legado.app.utils.msg import io.legado.app.utils.msg
import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.suspendCancellableCoroutine
import okhttp3.* import okhttp3.*
import java.io.IOException
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.TimeUnit import java.util.concurrent.TimeUnit
import kotlin.coroutines.resume import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
@Suppress("unused") @Suppress("unused")
object HttpHelper { object HttpHelper {
private val proxyClientCache: ConcurrentHashMap<String, OkHttpClient> by lazy {
ConcurrentHashMap()
}
val client: OkHttpClient by lazy { val client: OkHttpClient by lazy {
val specs = arrayListOf( val specs = arrayListOf(
@ -37,49 +40,30 @@ object HttpHelper {
builder.build() builder.build()
} }
suspend fun awaitResponse(request: Request): Response = suspendCancellableCoroutine { block -> /**
val call = client.newCall(request) * 缓存代理okHttp
*/
block.invokeOnCancellation {
call.cancel()
}
call.enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
block.resumeWithException(e)
}
override fun onResponse(call: Call, response: Response) {
block.resume(response)
}
})
}
fun getProxyClient(proxy: String? = null): OkHttpClient { fun getProxyClient(proxy: String? = null): OkHttpClient {
if (proxy.isNullOrBlank()) { if (proxy.isNullOrBlank()) {
return client return client
} }
proxyClientCache[proxy]?.let {
return it
}
val r = Regex("(http|socks4|socks5)://(.*):(\\d{2,5})(@.*@.*)?") val r = Regex("(http|socks4|socks5)://(.*):(\\d{2,5})(@.*@.*)?")
val ms = r.findAll(proxy) val ms = r.findAll(proxy)
val group = ms.first() val group = ms.first()
val type: String //直接连接
val host: String //代理服务器hostname
val port: Int //代理服务器port
var username = "" //代理服务器验证用户名 var username = "" //代理服务器验证用户名
var password = "" //代理服务器验证密码 var password = "" //代理服务器验证密码
type = if (group.groupValues[1] == "http") { val type = if (group.groupValues[1] == "http") "http" else "socks"
"http" val host = group.groupValues[2]
} else { val port = group.groupValues[3].toInt()
"socks"
}
host = group.groupValues[2]
port = group.groupValues[3].toInt()
if (group.groupValues[4] != "") { if (group.groupValues[4] != "") {
username = group.groupValues[4].split("@")[1] username = group.groupValues[4].split("@")[1]
password = group.groupValues[4].split("@")[2] password = group.groupValues[4].split("@")[2]
} }
val builder = client.newBuilder()
if (type != "direct" && host != "") { if (type != "direct" && host != "") {
val builder = client.newBuilder()
if (type == "http") { if (type == "http") {
builder.proxy(Proxy(Proxy.Type.HTTP, InetSocketAddress(host, port))) builder.proxy(Proxy(Proxy.Type.HTTP, InetSocketAddress(host, port)))
} else { } else {
@ -93,9 +77,11 @@ object HttpHelper {
.build() .build()
} }
} }
val proxyClient = builder.build()
proxyClientCache[proxy] = proxyClient
return proxyClient
} }
return builder.build() return client
} }
private fun getHeaderInterceptor(): Interceptor { private fun getHeaderInterceptor(): Interceptor {

@ -1,6 +1,7 @@
package io.legado.app.lib.webdav package io.legado.app.lib.webdav
import io.legado.app.help.http.HttpHelper import io.legado.app.help.http.HttpHelper
import io.legado.app.utils.await
import okhttp3.* import okhttp3.*
import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.asRequestBody
@ -119,7 +120,7 @@ class WebDav(urlStr: String) {
request.header("Authorization", Credentials.basic(it.user, it.pass)) request.header("Authorization", Credentials.basic(it.user, it.pass))
} }
request.header("Depth", if (depth < 0) "infinity" else depth.toString()) request.header("Depth", if (depth < 0) "infinity" else depth.toString())
return HttpHelper.awaitResponse(request.build()) return HttpHelper.client.newCall(request.build()).await()
} }
return null return null
} }
@ -233,7 +234,7 @@ class WebDav(urlStr: String) {
HttpAuth.auth?.let { HttpAuth.auth?.let {
requestBuilder.header("Authorization", Credentials.basic(it.user, it.pass)) requestBuilder.header("Authorization", Credentials.basic(it.user, it.pass))
} }
val response = HttpHelper.awaitResponse(requestBuilder.build()) val response = HttpHelper.client.newCall(requestBuilder.build()).await()
return response.isSuccessful return response.isSuccessful
} }

@ -141,12 +141,12 @@ class ImportBookSourceDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickList
binding.apply { binding.apply {
cbSourceName.isChecked = viewModel.selectStatus[holder.layoutPosition] cbSourceName.isChecked = viewModel.selectStatus[holder.layoutPosition]
cbSourceName.text = item.bookSourceName cbSourceName.text = item.bookSourceName
tvSourceState.text = val localSource = viewModel.checkSources[holder.layoutPosition]
if (viewModel.checkSources[holder.layoutPosition] != null) { tvSourceState.text = when {
"已存在" localSource == null -> "新书源"
} else { item.lastUpdateTime > localSource.lastUpdateTime -> "更新"
"新书源" else -> "已存在"
} }
} }
} }

@ -0,0 +1,27 @@
package io.legado.app.utils
import kotlinx.coroutines.suspendCancellableCoroutine
import okhttp3.Call
import okhttp3.Callback
import okhttp3.Response
import java.io.IOException
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
suspend fun Call.await(): Response = suspendCancellableCoroutine { block ->
block.invokeOnCancellation {
cancel()
}
enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
block.resumeWithException(e)
}
override fun onResponse(call: Call, response: Response) {
block.resume(response)
}
})
}
Loading…
Cancel
Save