pull/977/head
parent
da0d070bfe
commit
d9bcb7506a
@ -1,49 +0,0 @@ |
||||
package io.legado.app.help.http |
||||
|
||||
import io.legado.app.utils.EncodingDetect |
||||
import io.legado.app.utils.UTF8BOMFighter |
||||
import kotlinx.coroutines.suspendCancellableCoroutine |
||||
import okhttp3.Call |
||||
import okhttp3.Callback |
||||
import okhttp3.Response |
||||
import okhttp3.ResponseBody |
||||
import java.io.IOException |
||||
import java.nio.charset.Charset |
||||
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) |
||||
} |
||||
}) |
||||
|
||||
} |
||||
|
||||
fun ResponseBody.text(encode: String? = null): String { |
||||
val responseBytes = UTF8BOMFighter.removeUTF8BOM(bytes()) |
||||
var charsetName: String? = encode |
||||
|
||||
charsetName?.let { |
||||
return String(responseBytes, Charset.forName(charsetName)) |
||||
} |
||||
|
||||
//根据http头判断 |
||||
contentType()?.charset()?.let { |
||||
return String(responseBytes, it) |
||||
} |
||||
|
||||
//根据内容判断 |
||||
charsetName = EncodingDetect.getHtmlEncode(responseBytes) |
||||
return String(responseBytes, Charset.forName(charsetName)) |
||||
} |
@ -0,0 +1,131 @@ |
||||
package io.legado.app.help.http |
||||
|
||||
import io.legado.app.utils.EncodingDetect |
||||
import io.legado.app.utils.UTF8BOMFighter |
||||
import kotlinx.coroutines.suspendCancellableCoroutine |
||||
import okhttp3.* |
||||
import java.io.IOException |
||||
import java.net.InetSocketAddress |
||||
import java.net.Proxy |
||||
import java.nio.charset.Charset |
||||
import java.util.concurrent.ConcurrentHashMap |
||||
import java.util.concurrent.TimeUnit |
||||
import kotlin.coroutines.resume |
||||
import kotlin.coroutines.resumeWithException |
||||
|
||||
val okHttpClient: OkHttpClient by lazy { |
||||
|
||||
val specs = arrayListOf( |
||||
ConnectionSpec.MODERN_TLS, |
||||
ConnectionSpec.COMPATIBLE_TLS, |
||||
ConnectionSpec.CLEARTEXT |
||||
) |
||||
|
||||
val builder = OkHttpClient.Builder() |
||||
.connectTimeout(15, TimeUnit.SECONDS) |
||||
.writeTimeout(15, TimeUnit.SECONDS) |
||||
.readTimeout(15, TimeUnit.SECONDS) |
||||
.sslSocketFactory(SSLHelper.unsafeSSLSocketFactory, SSLHelper.unsafeTrustManager) |
||||
.retryOnConnectionFailure(true) |
||||
.hostnameVerifier(SSLHelper.unsafeHostnameVerifier) |
||||
.connectionSpecs(specs) |
||||
.followRedirects(true) |
||||
.followSslRedirects(true) |
||||
.addInterceptor(Interceptor { chain -> |
||||
val request = chain.request() |
||||
.newBuilder() |
||||
.addHeader("Keep-Alive", "300") |
||||
.addHeader("Connection", "Keep-Alive") |
||||
.addHeader("Cache-Control", "no-cache") |
||||
.build() |
||||
chain.proceed(request) |
||||
}) |
||||
|
||||
builder.build() |
||||
} |
||||
|
||||
object OkHttpHelper { |
||||
private val proxyClientCache: ConcurrentHashMap<String, OkHttpClient> by lazy { |
||||
ConcurrentHashMap() |
||||
} |
||||
|
||||
/** |
||||
* 缓存代理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] |
||||
} |
||||
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() |
||||
} |
||||
} |
||||
val proxyClient = builder.build() |
||||
proxyClientCache[proxy] = proxyClient |
||||
return proxyClient |
||||
} |
||||
return okHttpClient |
||||
} |
||||
} |
||||
|
||||
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) |
||||
} |
||||
}) |
||||
|
||||
} |
||||
|
||||
fun ResponseBody.text(encode: String? = null): String { |
||||
val responseBytes = UTF8BOMFighter.removeUTF8BOM(bytes()) |
||||
var charsetName: String? = encode |
||||
|
||||
charsetName?.let { |
||||
return String(responseBytes, Charset.forName(charsetName)) |
||||
} |
||||
|
||||
//根据http头判断 |
||||
contentType()?.charset()?.let { |
||||
return String(responseBytes, it) |
||||
} |
||||
|
||||
//根据内容判断 |
||||
charsetName = EncodingDetect.getHtmlEncode(responseBytes) |
||||
return String(responseBytes, Charset.forName(charsetName)) |
||||
} |
Loading…
Reference in new issue