diff --git a/app/build.gradle b/app/build.gradle index f5baacd8e..d43b69821 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -172,10 +172,10 @@ dependencies { implementation 'com.github.gedoor:rhino-android:1.4' //网络 - implementation 'com.ljx.rxhttp:rxhttp:2.4.4' - implementation 'com.squareup.retrofit2:retrofit:2.9.0' + implementation 'com.ljx.rxhttp:rxhttp:2.4.4-beta2' + 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' + kapt 'com.ljx.rxhttp:rxhttp-compiler:2.4.4-beta2' //Glide implementation 'com.github.bumptech.glide:glide:4.11.0' diff --git a/app/src/main/java/io/legado/app/help/JsExtensions.kt b/app/src/main/java/io/legado/app/help/JsExtensions.kt index 9629e3efe..825141793 100644 --- a/app/src/main/java/io/legado/app/help/JsExtensions.kt +++ b/app/src/main/java/io/legado/app/help/JsExtensions.kt @@ -31,9 +31,9 @@ interface JsExtensions { fun ajax(urlStr: String): String? { return try { val analyzeUrl = AnalyzeUrl(urlStr) - val call = analyzeUrl.getResponse(urlStr) - val response = call.execute() - response.body() + runBlocking { + analyzeUrl.getStrResponse(urlStr).body + } } catch (e: Exception) { e.msg } @@ -45,9 +45,9 @@ interface JsExtensions { fun connect(urlStr: String): Any { return try { val analyzeUrl = AnalyzeUrl(urlStr) - val call = analyzeUrl.getResponse(urlStr) - val response = call.execute() - response + runBlocking { + analyzeUrl.getStrResponse(urlStr) + } } catch (e: Exception) { e.msg } diff --git a/app/src/main/java/io/legado/app/help/http/AjaxWebView.kt b/app/src/main/java/io/legado/app/help/http/AjaxWebView.kt index db6dc165b..c14423c8b 100644 --- a/app/src/main/java/io/legado/app/help/http/AjaxWebView.kt +++ b/app/src/main/java/io/legado/app/help/http/AjaxWebView.kt @@ -39,7 +39,7 @@ class AjaxWebView { mWebView = createAjaxWebView(params, this) } MSG_SUCCESS -> { - ajaxWebView.callback?.onResult(msg.obj as Res) + ajaxWebView.callback?.onResult(msg.obj as StrResponse) destroyWebView() } MSG_ERROR -> { @@ -160,7 +160,7 @@ class AjaxWebView { if (it.isNotEmpty() && it != "null") { val content = StringEscapeUtils.unescapeJson(it) .replace("^\"|\"$".toRegex(), "") - handler.obtainMessage(MSG_SUCCESS, Res(url, content)) + handler.obtainMessage(MSG_SUCCESS, StrResponse.success(content, url)) .sendToTarget() handler.removeCallbacks(this) return@evaluateJavascript @@ -186,8 +186,10 @@ class AjaxWebView { override fun onLoadResource(view: WebView, url: String) { params.sourceRegex?.let { if (url.matches(it.toRegex())) { - handler.obtainMessage(MSG_SUCCESS, Res(view.url ?: params.url, url)) - .sendToTarget() + handler.obtainMessage( + MSG_SUCCESS, + StrResponse.success(url, view.url ?: params.url) + ).sendToTarget() } } } @@ -226,7 +228,7 @@ class AjaxWebView { } abstract class Callback { - abstract fun onResult(response: Res) + abstract fun onResult(response: StrResponse) abstract fun onError(error: Throwable) } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/help/http/ByteConverter.kt b/app/src/main/java/io/legado/app/help/http/ByteConverter.kt deleted file mode 100644 index bb42ec3a8..000000000 --- a/app/src/main/java/io/legado/app/help/http/ByteConverter.kt +++ /dev/null @@ -1,20 +0,0 @@ -package io.legado.app.help.http - -import okhttp3.ResponseBody -import retrofit2.Converter -import retrofit2.Retrofit -import java.lang.reflect.Type - -class ByteConverter : Converter.Factory() { - - override fun responseBodyConverter( - type: Type?, - annotations: Array?, - retrofit: Retrofit? - ): Converter? { - return Converter { value -> - value.bytes() - } - } - -} diff --git a/app/src/main/java/io/legado/app/help/http/CookieStore.kt b/app/src/main/java/io/legado/app/help/http/CookieStore.kt index 55b5bb141..8c4aa34ec 100644 --- a/app/src/main/java/io/legado/app/help/http/CookieStore.kt +++ b/app/src/main/java/io/legado/app/help/http/CookieStore.kt @@ -108,6 +108,6 @@ object CookieStore : CookiePersistor, CookieManager { } private fun createCookieKey(cookie: okhttp3.Cookie): String { - return (if (cookie.secure()) "https" else "http") + "://" + cookie.domain() + cookie.path() + "|" + cookie.name() + return (if (cookie.secure) "https" else "http") + "://" + cookie.domain + cookie.path + "|" + cookie.name } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/help/http/EncodeConverter.kt b/app/src/main/java/io/legado/app/help/http/EncodeConverter.kt deleted file mode 100644 index 0cad990f0..000000000 --- a/app/src/main/java/io/legado/app/help/http/EncodeConverter.kt +++ /dev/null @@ -1,40 +0,0 @@ -package io.legado.app.help.http - -import io.legado.app.utils.EncodingDetect -import io.legado.app.utils.UTF8BOMFighter -import okhttp3.ResponseBody -import retrofit2.Converter -import retrofit2.Retrofit -import java.lang.reflect.Type -import java.nio.charset.Charset - -class EncodeConverter(private val encode: String? = null) : Converter.Factory() { - - override fun responseBodyConverter( - type: Type?, - annotations: Array?, - retrofit: Retrofit? - ): Converter? { - return Converter { value -> - val responseBytes = UTF8BOMFighter.removeUTF8BOM(value.bytes()) - var charsetName: String? = encode - - charsetName?.let { - try { - return@Converter String(responseBytes, Charset.forName(charsetName)) - } catch (e: Exception) { - } - } - - //根据http头判断 - value.contentType()?.charset()?.let { - return@Converter String(responseBytes, it) - } - - //根据内容判断 - charsetName = EncodingDetect.getHtmlEncode(responseBytes) - String(responseBytes, Charset.forName(charsetName)) - } - } - -} 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 fdd9e20fe..687057e6b 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,8 +1,8 @@ package io.legado.app.help.http +import io.legado.app.utils.msg import kotlinx.coroutines.suspendCancellableCoroutine import okhttp3.* -import retrofit2.Retrofit import java.io.IOException import java.net.InetSocketAddress import java.net.Proxy @@ -55,26 +55,6 @@ object HttpHelper { }) } - inline fun getApiService( - baseUrl: String, - encode: String? = null, - proxy: String? = null - ): T { - return getRetrofit(baseUrl, encode, proxy).create(T::class.java) - } - - fun getRetrofit( - baseUrl: String, - encode: String? = null, - proxy: String? = null - ): Retrofit { - return Retrofit.Builder().baseUrl(baseUrl) - //增加返回值为字符串的支持(以实体类返回) - .addConverterFactory(EncodeConverter(encode)) - .client(getProxyClient(proxy)) - .build() - } - fun getProxyClient(proxy: String? = null): OkHttpClient { if (proxy.isNullOrBlank()) { return client @@ -108,7 +88,7 @@ object HttpHelper { if (username != "" && password != "") { builder.proxyAuthenticator { _, response -> //设置代理服务器账号密码 val credential: String = Credentials.basic(username, password) - response.request().newBuilder() + response.request.newBuilder() .header("Proxy-Authorization", credential) .build() } @@ -130,21 +110,22 @@ object HttpHelper { } } - suspend fun ajax(params: AjaxWebView.AjaxParams): Res = + suspend fun ajax(params: AjaxWebView.AjaxParams): StrResponse = suspendCancellableCoroutine { block -> val webView = AjaxWebView() block.invokeOnCancellation { webView.destroyWebView() } webView.callback = object : AjaxWebView.Callback() { - override fun onResult(response: Res) { + override fun onResult(response: StrResponse) { + if (!block.isCompleted) block.resume(response) } override fun onError(error: Throwable) { if (!block.isCompleted) - block.resume(Res(params.url, error.localizedMessage)) + block.resume(StrResponse.success(error.msg, params.url)) } } webView.load(params) diff --git a/app/src/main/java/io/legado/app/help/http/Res.kt b/app/src/main/java/io/legado/app/help/http/Res.kt deleted file mode 100644 index e54832b40..000000000 --- a/app/src/main/java/io/legado/app/help/http/Res.kt +++ /dev/null @@ -1,6 +0,0 @@ -package io.legado.app.help.http - -data class Res( - val url: String, - val body: String?, -) \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/help/http/StrResponse.kt b/app/src/main/java/io/legado/app/help/http/StrResponse.kt new file mode 100644 index 000000000..823a0ba30 --- /dev/null +++ b/app/src/main/java/io/legado/app/help/http/StrResponse.kt @@ -0,0 +1,124 @@ +package io.legado.app.help.http + +import okhttp3.* +import okhttp3.Response.Builder +import java.util.* + +/** + * An HTTP response. + */ +@Suppress("unused", "MemberVisibilityCanBePrivate") +class StrResponse private constructor( + val rawResponse: Response, + val body: String?, + val errorBody: ResponseBody? +) { + val raw get() = rawResponse + + val url: String + get() { + raw.networkResponse?.let { + return it.request.url.toString() + } + return raw.request.url.toString() + } + + fun code(): Int { + return rawResponse.code + } + + fun message(): String { + return rawResponse.message + } + + fun headers(): Headers { + return rawResponse.headers + } + + val isSuccessful: Boolean + get() = rawResponse.isSuccessful + + fun errorBody(): ResponseBody? { + return errorBody + } + + override fun toString(): String { + return rawResponse.toString() + } + + companion object { + fun success(code: Int, body: String): StrResponse { + require(!(code < 200 || code >= 300)) { "code < 200 or >= 300: $code" } + return success( + body, + Builder() // + .code(code) + .message("Response.success()") + .protocol(Protocol.HTTP_1_1) + .request(Request.Builder().url("http://localhost/").build()) + .build() + ) + } + + fun success(body: String, headers: Headers): StrResponse { + return success( + body, + Builder() // + .code(200) + .message("OK") + .protocol(Protocol.HTTP_1_1) + .headers(headers) + .request(Request.Builder().url("http://localhost/").build()) + .build() + ) + } + + fun success(body: String, url: String): StrResponse { + return success( + body, + Builder() // + .code(200) + .message("OK") + .protocol(Protocol.HTTP_1_1) + .request(Request.Builder().url(url).build()) + .build() + ) + } + + @JvmOverloads + fun success( + body: String?, rawResponse: Response = + Builder() // + .code(200) + .message("OK") + .protocol(Protocol.HTTP_1_1) + .request(Request.Builder().url("http://localhost/").build()) + .build() + ): StrResponse { + Objects.requireNonNull(rawResponse, "rawResponse == null") + require(rawResponse.isSuccessful) { "rawResponse must be successful response" } + return StrResponse(rawResponse, body, null) + } + + fun error(code: Int, body: ResponseBody?): StrResponse { + Objects.requireNonNull(body, "body == null") + require(code >= 400) { "code < 400: $code" } + return error( + body, + Builder() // + .code(code) + .message("Response.error()") + .protocol(Protocol.HTTP_1_1) + .request(Request.Builder().url("http://localhost/").build()) + .build() + ) + } + + fun error(body: ResponseBody?, rawResponse: Response): StrResponse { + Objects.requireNonNull(body, "body == null") + Objects.requireNonNull(rawResponse, "rawResponse == null") + require(!rawResponse.isSuccessful) { "rawResponse should not be successful response" } + return StrResponse(rawResponse, null, body) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/help/http/api/HttpGetApi.kt b/app/src/main/java/io/legado/app/help/http/api/HttpGetApi.kt deleted file mode 100644 index 7138c8c20..000000000 --- a/app/src/main/java/io/legado/app/help/http/api/HttpGetApi.kt +++ /dev/null @@ -1,67 +0,0 @@ -package io.legado.app.help.http.api - -import retrofit2.Call -import retrofit2.Response -import retrofit2.http.GET -import retrofit2.http.HeaderMap -import retrofit2.http.QueryMap -import retrofit2.http.Url - -/** - * Created by GKF on 2018/1/21. - * get web content - */ -@Suppress("unused") -interface HttpGetApi { - @GET - suspend fun getAsync( - @Url url: String, - @HeaderMap headers: Map - ): Response - - @GET - suspend fun getMapAsync( - @Url url: String, - @QueryMap(encoded = true) queryMap: Map, - @HeaderMap headers: Map - ): Response - - @GET - fun get( - @Url url: String, - @HeaderMap headers: Map - ): Call - - @GET - fun getByte( - @Url url: String, - @HeaderMap headers: Map - ): Call - - @GET - fun getMap( - @Url url: String, - @QueryMap(encoded = true) queryMap: Map, - @HeaderMap headers: Map - ): Call - - @GET - fun getMapByte( - @Url url: String, - @QueryMap(encoded = true) queryMap: Map, - @HeaderMap headers: Map - ): Call - - @GET - suspend fun getByteAsync( - @Url url: String, - @HeaderMap headers: Map - ): Response - - @GET - suspend fun getMapByteAsync( - @Url url: String, - @QueryMap(encoded = true) queryMap: Map, - @HeaderMap headers: Map - ): Response -} diff --git a/app/src/main/java/io/legado/app/help/http/api/HttpPostApi.kt b/app/src/main/java/io/legado/app/help/http/api/HttpPostApi.kt deleted file mode 100644 index 170894390..000000000 --- a/app/src/main/java/io/legado/app/help/http/api/HttpPostApi.kt +++ /dev/null @@ -1,60 +0,0 @@ -package io.legado.app.help.http.api - -import okhttp3.RequestBody -import retrofit2.Call -import retrofit2.Response -import retrofit2.http.* - -/** - * Created by GKF on 2018/1/29. - * post - */ -@Suppress("unused") -interface HttpPostApi { - - @FormUrlEncoded - @POST - suspend fun postMapAsync( - @Url url: String, - @FieldMap(encoded = true) fieldMap: Map, - @HeaderMap headers: Map - ): Response - - @POST - suspend fun postBodyAsync( - @Url url: String, - @Body body: RequestBody, - @HeaderMap headers: Map - ): Response - - @FormUrlEncoded - @POST - fun postMap( - @Url url: String, - @FieldMap(encoded = true) fieldMap: Map, - @HeaderMap headers: Map - ): Call - - @POST - fun postBody( - @Url url: String, - @Body body: RequestBody, - @HeaderMap headers: Map - ): Call - - @FormUrlEncoded - @POST - suspend fun postMapByteAsync( - @Url url: String, - @FieldMap(encoded = true) fieldMap: Map, - @HeaderMap headers: Map - ): Response - - @POST - suspend fun postBodyByteAsync( - @Url url: String, - @Body body: RequestBody, - @HeaderMap headers: Map - ): Response - -} diff --git a/app/src/main/java/io/legado/app/help/http/parser/ByteParser.kt b/app/src/main/java/io/legado/app/help/http/parser/ByteParser.kt index 2419daeb0..b2812d41e 100644 --- a/app/src/main/java/io/legado/app/help/http/parser/ByteParser.kt +++ b/app/src/main/java/io/legado/app/help/http/parser/ByteParser.kt @@ -7,7 +7,7 @@ import rxhttp.wrapper.annotation.Parser class ByteParser : rxhttp.wrapper.parse.Parser { override fun onParse(response: Response): ByteArray { - return response.body()!!.bytes() + return response.body!!.bytes() } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/help/http/parser/InputStreamParser.kt b/app/src/main/java/io/legado/app/help/http/parser/InputStreamParser.kt index 0b4d61b2e..9ca0ffe4d 100644 --- a/app/src/main/java/io/legado/app/help/http/parser/InputStreamParser.kt +++ b/app/src/main/java/io/legado/app/help/http/parser/InputStreamParser.kt @@ -8,7 +8,7 @@ import java.io.InputStream class InputStreamParser : rxhttp.wrapper.parse.Parser { override fun onParse(response: Response): InputStream { - return response.body()!!.byteStream() + return response.body!!.byteStream() } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/help/http/parser/SimpleResponseParser.kt b/app/src/main/java/io/legado/app/help/http/parser/SimpleResponseParser.kt new file mode 100644 index 000000000..17fb1b181 --- /dev/null +++ b/app/src/main/java/io/legado/app/help/http/parser/SimpleResponseParser.kt @@ -0,0 +1,38 @@ +package io.legado.app.help.http.parser + +import io.legado.app.help.http.StrResponse +import io.legado.app.utils.EncodingDetect +import io.legado.app.utils.UTF8BOMFighter +import okhttp3.Response +import rxhttp.wrapper.annotation.Parser +import rxhttp.wrapper.exception.HttpStatusCodeException +import java.nio.charset.Charset + +@Parser(name = "StrResponse") +class StrResponseParser(val encode: String? = null) : rxhttp.wrapper.parse.Parser { + + override fun onParse(response: Response): StrResponse { + return StrResponse.success(getString(response), response) + } + + private fun getString(response: Response): String { + + val responseBody = response.body ?: throw HttpStatusCodeException(response, "内容为空") + val responseBytes = UTF8BOMFighter.removeUTF8BOM(responseBody.bytes()) + var charsetName: String? = encode + + charsetName?.let { + return String(responseBytes, Charset.forName(charsetName)) + } + + //根据http头判断 + responseBody.contentType()?.charset()?.let { + return String(responseBytes, it) + } + + //根据内容判断 + charsetName = EncodingDetect.getHtmlEncode(responseBytes) + return String(responseBytes, Charset.forName(charsetName)) + } + +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/help/http/parser/TextParser.kt b/app/src/main/java/io/legado/app/help/http/parser/TextParser.kt index 71ec1cece..09891944d 100644 --- a/app/src/main/java/io/legado/app/help/http/parser/TextParser.kt +++ b/app/src/main/java/io/legado/app/help/http/parser/TextParser.kt @@ -12,7 +12,7 @@ class TextParser(val encode: String? = null) : rxhttp.wrapper.parse.Parser = ArrayList()): List { propFindResponse(propsList)?.let { response -> if (response.isSuccessful) { - response.body()?.let { body -> + response.body?.let { body -> @Suppress("BlockingMethodInNonBlockingContext") return parseDir(body.string()) } @@ -107,7 +110,7 @@ class WebDav(urlStr: String) { httpUrl?.let { url -> // 添加RequestBody对象,可以只返回的属性。如果设为null,则会返回全部属性 // 注意:尽量手动指定需要返回的属性。若返回全部属性,可能后由于Prop.java里没有该属性名,而崩溃。 - val requestBody = RequestBody.create(MediaType.parse("text/plain"), requestPropsStr) + val requestBody = requestPropsStr.toRequestBody("text/plain".toMediaType()) val request = Request.Builder() .url(url) .method("PROPFIND", requestBody) @@ -197,9 +200,8 @@ class WebDav(urlStr: String) { suspend fun upload(localPath: String, contentType: String? = null): Boolean { val file = File(localPath) if (!file.exists()) return false - val mediaType = contentType?.let { MediaType.parse(it) } // 务必注意RequestBody不要嵌套,不然上传时内容可能会被追加多余的文件信息 - val fileBody = RequestBody.create(mediaType, file) + val fileBody = file.asRequestBody(contentType?.toMediaType()) httpUrl?.let { val request = Request.Builder() .url(it) @@ -210,9 +212,8 @@ class WebDav(urlStr: String) { } suspend fun upload(byteArray: ByteArray, contentType: String? = null): Boolean { - val mediaType = contentType?.let { MediaType.parse(it) } // 务必注意RequestBody不要嵌套,不然上传时内容可能会被追加多余的文件信息 - val fileBody = RequestBody.create(mediaType, byteArray) + val fileBody = byteArray.toRequestBody(contentType?.toMediaType()) httpUrl?.let { val request = Request.Builder() .url(it) diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt index 1877edf9d..bf812256e 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt @@ -647,7 +647,7 @@ class AnalyzeRule(var book: BaseBook? = null) : JsExtensions { return try { val analyzeUrl = AnalyzeUrl(urlStr, book = book) runBlocking { - analyzeUrl.getRes(urlStr).body + analyzeUrl.getStrResponse(urlStr).body } } catch (e: Exception) { e.localizedMessage 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 86910724a..6f962b421 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 @@ -15,15 +15,10 @@ import io.legado.app.help.AppConfig import io.legado.app.help.CacheManager import io.legado.app.help.JsExtensions import io.legado.app.help.http.* -import io.legado.app.help.http.api.HttpGetApi -import io.legado.app.help.http.api.HttpPostApi import io.legado.app.utils.* -import okhttp3.FormBody -import okhttp3.MediaType -import okhttp3.RequestBody -import retrofit2.Call import rxhttp.wrapper.param.RxHttp import rxhttp.wrapper.param.toByteArray +import rxhttp.wrapper.param.toStrResponse import java.net.URLEncoder import java.util.* import java.util.regex.Pattern @@ -50,7 +45,6 @@ class AnalyzeUrl( companion object { val splitUrlRegex = Regex(",\\s*(?=\\{)") private val pagePattern = Pattern.compile("<(.*?)>") - private val jsonType = MediaType.parse("application/json; charset=utf-8") } var url: String = "" @@ -61,7 +55,6 @@ class AnalyzeUrl( private var queryStr: String? = null private val fieldMap = LinkedHashMap() private var charset: String? = null - private var requestBody: RequestBody? = null private var method = RequestMethod.GET private var proxy: String? = null @@ -172,7 +165,7 @@ class AnalyzeUrl( */ private fun initUrl() { var urlArray = ruleUrl.split(splitUrlRegex, 2) - url = urlArray[0] + url = NetworkUtils.getAbsoluteURL(baseUrl, urlArray[0])!! urlHasQuery = urlArray[0] NetworkUtils.getBaseUrl(url)?.let { baseUrl = it @@ -223,13 +216,9 @@ class AnalyzeUrl( } RequestMethod.POST -> { body?.let { - if (it.isJson()) { - requestBody = RequestBody.create(jsonType, it) - } else { + if (!it.isJson()) { analyzeFields(it) } - } ?: let { - requestBody = FormBody.Builder().build() } } } @@ -285,56 +274,15 @@ class AnalyzeUrl( return book?.variableMap?.get(key) ?: "" } - fun getResponse(tag: String): Call { - val cookie = CookieStore.getCookie(tag) - if (cookie.isNotEmpty()) { - val cookieMap = CookieStore.cookieToMap(cookie) - val customCookieMap = CookieStore.cookieToMap(headerMap["Cookie"] ?: "") - cookieMap.putAll(customCookieMap) - val newCookie = CookieStore.mapToCookie(cookieMap) - newCookie?.let { - headerMap.put("Cookie", it) - } - } - return when { - method == RequestMethod.POST -> { - if (fieldMap.isNotEmpty()) { - HttpHelper - .getApiService(baseUrl, charset, proxy) - .postMap(url, fieldMap, headerMap) - } else { - HttpHelper - .getApiService(baseUrl, charset, proxy) - .postBody(url, requestBody!!, headerMap) - } - } - fieldMap.isEmpty() -> HttpHelper - .getApiService(baseUrl, charset, proxy) - .get(url, headerMap) - else -> HttpHelper - .getApiService(baseUrl, charset, proxy) - .getMap(url, fieldMap, headerMap) - } - } - - suspend fun getRes( + suspend fun getStrResponse( tag: String, jsStr: String? = null, sourceRegex: String? = null, - ): Res { + ): StrResponse { if (type != null) { - return Res(url, StringUtils.byteToHexString(getByteArray(tag))) - } - val cookie = CookieStore.getCookie(tag) - if (cookie.isNotEmpty()) { - val cookieMap = CookieStore.cookieToMap(cookie) - val customCookieMap = CookieStore.cookieToMap(headerMap["Cookie"] ?: "") - cookieMap.putAll(customCookieMap) - val newCookie = CookieStore.mapToCookie(cookieMap) - newCookie?.let { - headerMap.put("Cookie", it) - } + return StrResponse.success(StringUtils.byteToHexString(getByteArray(tag)), url) } + setCookie(tag) if (useWebView) { val params = AjaxWebView.AjaxParams(url) params.headerMap = headerMap @@ -345,65 +293,69 @@ class AnalyzeUrl( params.tag = tag return HttpHelper.ajax(params) } - val res = when { - method == RequestMethod.POST -> { + return when (method) { + RequestMethod.POST -> { if (fieldMap.isNotEmpty()) { - HttpHelper - .getApiService(baseUrl, charset, proxy) - .postMapAsync(url, fieldMap, headerMap) + RxHttp.postForm(url) + .setOkClient(HttpHelper.getProxyClient(proxy)) + .addAll(fieldMap) + .addAllHeader(headerMap) + .toStrResponse().await() } else { - HttpHelper - .getApiService(baseUrl, charset, proxy) - .postBodyAsync(url, requestBody!!, headerMap) + RxHttp.postJson(url) + .setOkClient(HttpHelper.getProxyClient(proxy)) + .addAll(body) + .addAllHeader(headerMap) + .toStrResponse().await() } } - fieldMap.isEmpty() -> { - HttpHelper - .getApiService(baseUrl, charset, proxy) - .getAsync(url, headerMap) - } - else -> { - HttpHelper - .getApiService(baseUrl, charset, proxy) - .getMapAsync(url, fieldMap, headerMap) - } + else -> RxHttp.get(url) + .setOkClient(HttpHelper.getProxyClient(proxy)) + .addAll(fieldMap) + .toStrResponse().await() } - return Res(NetworkUtils.getUrl(res), res.body()) } suspend fun getByteArray(tag: String? = null): ByteArray { - if (tag != null) { - val cookie = CookieStore.getCookie(tag) - if (cookie.isNotEmpty()) { - val cookieMap = CookieStore.cookieToMap(cookie) - val customCookieMap = CookieStore.cookieToMap(headerMap["Cookie"] ?: "") - cookieMap.putAll(customCookieMap) - val newCookie = CookieStore.mapToCookie(cookieMap) - newCookie?.let { - headerMap.put("Cookie", it) - } - } - } + setCookie(tag) return when (method) { RequestMethod.POST -> { if (fieldMap.isNotEmpty()) { RxHttp.postForm(url) + .setOkClient(HttpHelper.getProxyClient(proxy)) .addAll(fieldMap) .addAllHeader(headerMap) .toByteArray().await() } else { RxHttp.postJson(url) + .setOkClient(HttpHelper.getProxyClient(proxy)) .addAll(body) .addAllHeader(headerMap) .toByteArray().await() } } else -> RxHttp.get(url) + .setOkClient(HttpHelper.getProxyClient(proxy)) .addAll(fieldMap) .toByteArray().await() } } + private fun setCookie(tag: String?) { + if (tag != null) { + val cookie = CookieStore.getCookie(tag) + if (cookie.isNotEmpty()) { + val cookieMap = CookieStore.cookieToMap(cookie) + val customCookieMap = CookieStore.cookieToMap(headerMap["Cookie"] ?: "") + cookieMap.putAll(customCookieMap) + val newCookie = CookieStore.mapToCookie(cookieMap) + newCookie?.let { + headerMap.put("Cookie", it) + } + } + } + } + fun getGlideUrl(): GlideUrl { val headers = LazyHeaders.Builder() headerMap.forEach { (key, value) -> diff --git a/app/src/main/java/io/legado/app/model/rss/Rss.kt b/app/src/main/java/io/legado/app/model/rss/Rss.kt index 979d2e308..a757aed5f 100644 --- a/app/src/main/java/io/legado/app/model/rss/Rss.kt +++ b/app/src/main/java/io/legado/app/model/rss/Rss.kt @@ -26,7 +26,7 @@ object Rss { page = page, headerMapF = rssSource.getHeaderMap() ) - val body = analyzeUrl.getRes(rssSource.sourceUrl).body + val body = analyzeUrl.getStrResponse(rssSource.sourceUrl).body RssParserByRule.parseXML(sortName, sortUrl, body, rssSource) } } @@ -42,7 +42,7 @@ object Rss { val body = AnalyzeUrl( rssArticle.link, baseUrl = rssArticle.origin, headerMapF = rssSource?.getHeaderMap() - ).getRes(rssArticle.origin) + ).getStrResponse(rssArticle.origin) .body val analyzeRule = AnalyzeRule() analyzeRule.setContent(body) diff --git a/app/src/main/java/io/legado/app/model/webBook/BookChapterList.kt b/app/src/main/java/io/legado/app/model/webBook/BookChapterList.kt index fb51b4802..94ba0baf7 100644 --- a/app/src/main/java/io/legado/app/model/webBook/BookChapterList.kt +++ b/app/src/main/java/io/legado/app/model/webBook/BookChapterList.kt @@ -63,7 +63,7 @@ object BookChapterList { ruleUrl = nextUrl, book = book, headerMapF = bookSource.getHeaderMap() - ).getRes(bookSource.bookSourceUrl) + ).getStrResponse(bookSource.bookSourceUrl) .body?.let { nextBody -> chapterData = analyzeChapterList( book, nextUrl, nextBody, tocRule, listRule, bookSource @@ -132,7 +132,7 @@ object BookChapterList { ruleUrl = chapterData.nextUrl, book = book, headerMapF = bookSource.getHeaderMap() - ).getRes(bookSource.bookSourceUrl).body + ).getStrResponse(bookSource.bookSourceUrl).body ?: throw Exception("${chapterData.nextUrl}, 下载失败") val nextChapterData = analyzeChapterList( book, chapterData.nextUrl, nextBody, tocRule, listRule, bookSource, diff --git a/app/src/main/java/io/legado/app/model/webBook/BookContent.kt b/app/src/main/java/io/legado/app/model/webBook/BookContent.kt index d3d055ffa..f1bb8d405 100644 --- a/app/src/main/java/io/legado/app/model/webBook/BookContent.kt +++ b/app/src/main/java/io/legado/app/model/webBook/BookContent.kt @@ -56,7 +56,7 @@ object BookContent { ruleUrl = nextUrl, book = book, headerMapF = bookSource.getHeaderMap() - ).getRes(bookSource.bookSourceUrl).body?.let { nextBody -> + ).getStrResponse(bookSource.bookSourceUrl).body?.let { nextBody -> contentData = analyzeContent( book, nextUrl, nextBody, contentRule, bookChapter, bookSource, false ) @@ -78,7 +78,7 @@ object BookContent { ruleUrl = item.nextUrl, book = book, headerMapF = bookSource.getHeaderMap() - ).getRes(bookSource.bookSourceUrl).body?.let { + ).getStrResponse(bookSource.bookSourceUrl).body?.let { contentData = analyzeContent( book, item.nextUrl, it, contentRule, bookChapter, bookSource, false ) diff --git a/app/src/main/java/io/legado/app/model/webBook/WebBook.kt b/app/src/main/java/io/legado/app/model/webBook/WebBook.kt index b7057ee61..7a1c29a05 100644 --- a/app/src/main/java/io/legado/app/model/webBook/WebBook.kt +++ b/app/src/main/java/io/legado/app/model/webBook/WebBook.kt @@ -46,7 +46,7 @@ class WebBook(val bookSource: BookSource) { headerMapF = bookSource.getHeaderMap(), book = variableBook ) - val res = analyzeUrl.getRes(bookSource.bookSourceUrl) + val res = analyzeUrl.getStrResponse(bookSource.bookSourceUrl) return BookList.analyzeBookList( scope, res.body, @@ -77,7 +77,7 @@ class WebBook(val bookSource: BookSource) { baseUrl = sourceUrl, headerMapF = bookSource.getHeaderMap() ) - val res = analyzeUrl.getRes(bookSource.bookSourceUrl) + val res = analyzeUrl.getStrResponse(bookSource.bookSourceUrl) BookList.analyzeBookList( scope, res.body, @@ -110,7 +110,7 @@ class WebBook(val bookSource: BookSource) { baseUrl = sourceUrl, headerMapF = bookSource.getHeaderMap(), book = book - ).getRes(bookSource.bookSourceUrl) + ).getStrResponse(bookSource.bookSourceUrl) BookInfo.analyzeBookInfo(book, res.body, bookSource, book.bookUrl, canReName) } book @@ -141,7 +141,7 @@ class WebBook(val bookSource: BookSource) { ruleUrl = book.tocUrl, baseUrl = book.bookUrl, headerMapF = bookSource.getHeaderMap() - ).getRes(bookSource.bookSourceUrl) + ).getStrResponse(bookSource.bookSourceUrl) BookChapterList.analyzeChapterList( this, book, @@ -201,7 +201,7 @@ class WebBook(val bookSource: BookSource) { headerMapF = bookSource.getHeaderMap(), book = book, chapter = bookChapter - ).getRes( + ).getStrResponse( bookSource.bookSourceUrl, jsStr = bookSource.getContentRule().webJs, sourceRegex = bookSource.getContentRule().sourceRegex diff --git a/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowViewModel.kt b/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowViewModel.kt index 4473d00ca..f4e3e40be 100644 --- a/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowViewModel.kt @@ -8,6 +8,7 @@ import io.legado.app.base.BaseViewModel import io.legado.app.data.entities.BookSource import io.legado.app.data.entities.SearchBook import io.legado.app.model.webBook.WebBook +import io.legado.app.utils.msg import kotlinx.coroutines.Dispatchers.IO class ExploreShowViewModel(application: Application) : BaseViewModel(application) { @@ -39,6 +40,8 @@ class ExploreShowViewModel(application: Application) : BaseViewModel(application booksData.postValue(searchBooks) App.db.searchBookDao.insert(*searchBooks.toTypedArray()) page++ + }.onError { + toast(it.msg) } } } diff --git a/app/src/main/java/io/legado/app/utils/NetworkUtils.kt b/app/src/main/java/io/legado/app/utils/NetworkUtils.kt index d5464c6aa..79dcb5790 100644 --- a/app/src/main/java/io/legado/app/utils/NetworkUtils.kt +++ b/app/src/main/java/io/legado/app/utils/NetworkUtils.kt @@ -1,6 +1,5 @@ package io.legado.app.utils -import retrofit2.Response import java.net.InetAddress import java.net.NetworkInterface import java.net.SocketException @@ -11,13 +10,6 @@ import java.util.regex.Pattern @Suppress("unused", "MemberVisibilityCanBePrivate") object NetworkUtils { - fun getUrl(response: Response<*>): String { - response.raw().networkResponse()?.let { - return it.request().url().toString() - } - return response.raw().request().url().toString() - } - private val notNeedEncoding: BitSet by lazy { val bitSet = BitSet(256) for (i in 'a'.toInt()..'z'.toInt()) {