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