better handle http errors

Signed-off-by: androidacy-user <opensource@androidacy.com>
pull/89/head
androidacy-user 2 years ago
parent 4c34f3b478
commit b82d128f5a

@ -526,7 +526,7 @@ dependencies {
implementation("org.jetbrains:annotations-java5:24.0.1") implementation("org.jetbrains:annotations-java5:24.0.1")
// debugging // debugging
debugImplementation("com.squareup.leakcanary:leakcanary-android:2.11") debugImplementation("com.squareup.leakcanary:leakcanary-android:2.12")
// desugaring // desugaring
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.3") coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.3")

@ -300,7 +300,7 @@ class AndroidacyActivity : FoxActivity() {
} }
override fun onConsoleMessage(consoleMessage: ConsoleMessage): Boolean { override fun onConsoleMessage(consoleMessage: ConsoleMessage): Boolean {
if (BuildConfig.DEBUG_HTTP) { return if (BuildConfig.DEBUG) {
when (consoleMessage.messageLevel()) { when (consoleMessage.messageLevel()) {
MessageLevel.TIP -> Timber.tag("JSLog").i(consoleMessage.message()) MessageLevel.TIP -> Timber.tag("JSLog").i(consoleMessage.message())
MessageLevel.LOG -> Timber.tag("JSLog").d(consoleMessage.message()) MessageLevel.LOG -> Timber.tag("JSLog").d(consoleMessage.message())
@ -308,8 +308,10 @@ class AndroidacyActivity : FoxActivity() {
MessageLevel.ERROR -> Timber.tag("JSLog").e(consoleMessage.message()) MessageLevel.ERROR -> Timber.tag("JSLog").e(consoleMessage.message())
else -> Timber.tag("JSLog").v(consoleMessage.message()) else -> Timber.tag("JSLog").v(consoleMessage.message())
} }
true
} else {
false
} }
return true
} }
override fun onProgressChanged(view: WebView, newProgress: Int) { override fun onProgressChanged(view: WebView, newProgress: Int) {
@ -323,8 +325,8 @@ class AndroidacyActivity : FoxActivity() {
Timber.i("Progress: %d, setting indeterminate to false", newProgress) Timber.i("Progress: %d, setting indeterminate to false", newProgress)
prgInd.isIndeterminate = false prgInd.isIndeterminate = false
} }
prgInd.setProgressCompat(newProgress, true) prgInd.setProgress(newProgress, true)
if (newProgress == 100 && prgInd.visibility != View.INVISIBLE) { if (newProgress == 100 && prgInd.visibility != View.GONE) {
Timber.i("Progress: %d, hiding progress bar", newProgress) Timber.i("Progress: %d, hiding progress bar", newProgress)
prgInd.isIndeterminate = true prgInd.isIndeterminate = true
prgInd.visibility = View.GONE prgInd.visibility = View.GONE

@ -73,7 +73,6 @@ enum class Http {;
* can help make the app to work later when the current DNS system * can help make the app to work later when the current DNS system
* isn't functional or available. * isn't functional or available.
* *
*
* Note: DNS Cache is stored in user data. * Note: DNS Cache is stored in user data.
*/ */
private class FallBackDNS(context: Context, parent: Dns, vararg fallbacks: String?) : Dns { private class FallBackDNS(context: Context, parent: Dns, vararg fallbacks: String?) : Dns {
@ -429,8 +428,7 @@ enum class Http {;
} }
private fun followRedirects( private fun followRedirects(
builder: OkHttpClient.Builder, builder: OkHttpClient.Builder, followRedirects: Boolean
followRedirects: Boolean
): OkHttpClient.Builder { ): OkHttpClient.Builder {
return builder.followRedirects(followRedirects).followSslRedirects(followRedirects) return builder.followRedirects(followRedirects).followSslRedirects(followRedirects)
} }
@ -464,14 +462,11 @@ enum class Http {;
needCaptchaAndroidacyHost = null needCaptchaAndroidacyHost = null
} }
@Suppress("unused")
@JvmStatic @JvmStatic
@SuppressLint("RestrictedApi") @SuppressLint("RestrictedApi")
@Throws(IOException::class) @Throws(IOException::class)
fun doHttpGet(url: String, allowCache: Boolean): ByteArray { fun doHttpGet(url: String, allowCache: Boolean): ByteArray {
if (BuildConfig.DEBUG_HTTP) {
// Log, but set all query parameters values to "****" while keeping the keys
Timber.d("doHttpGet: %s", url.replace("=[^&]*".toRegex(), "=****"))
}
var response: Response? var response: Response?
response = try { response = try {
(if (allowCache) getHttpClientWithCache() else getHttpClient())!!.newCall( (if (allowCache) getHttpClientWithCache() else getHttpClient())!!.newCall(
@ -480,7 +475,16 @@ enum class Http {;
).get().build() ).get().build()
).execute() ).execute()
} catch (e: IOException) { } catch (e: IOException) {
Timber.e(e, "Failed to fetch %s", url.replace("=[^&]*".toRegex(), "=****")) Timber.e(e, "Failed to post %s", url)
// detect ssl errors, i.e., cert authority invalid by looking at the message
if (e.message != null && e.message!!.contains("_CERT_")) {
MainActivity.getFoxActivity(MainApplication.INSTANCE!!).runOnUiThread {
// show toast
Toast.makeText(
MainApplication.INSTANCE, R.string.ssl_error, Toast.LENGTH_LONG
).show()
}
}
throw HttpException(e.message, 0) throw HttpException(e.message, 0)
} }
if (BuildConfig.DEBUG_HTTP) { if (BuildConfig.DEBUG_HTTP) {
@ -550,6 +554,7 @@ enum class Http {;
return responseBody?.bytes() ?: ByteArray(0) return responseBody?.bytes() ?: ByteArray(0)
} }
@Suppress("unused")
@JvmStatic @JvmStatic
@Throws(IOException::class) @Throws(IOException::class)
fun doHttpPost(url: String, data: String, allowCache: Boolean): ByteArray { fun doHttpPost(url: String, data: String, allowCache: Boolean): ByteArray {
@ -560,11 +565,26 @@ enum class Http {;
private fun doHttpPostRaw(url: String, data: String, allowCache: Boolean): Any { private fun doHttpPostRaw(url: String, data: String, allowCache: Boolean): Any {
Timber.d("POST %s", url) Timber.d("POST %s", url)
var response: Response? var response: Response?
response = (if (allowCache) getHttpClientWithCache() else getHttpClient())!!.newCall( try {
Request.Builder().url(url).post( response =
JsonRequestBody.from(data) (if (allowCache) getHttpClientWithCache() else getHttpClient())!!.newCall(
).header("Content-Type", "application/json").build() Request.Builder().url(url).post(
).execute() JsonRequestBody.from(data)
).header("Content-Type", "application/json").build()
).execute()
} catch (e: IOException) {
Timber.e(e, "Failed to post %s", url)
// detect ssl errors, i.e., cert authority invalid by looking at the message
if (e.message != null && e.message!!.contains("_CERT_")) {
MainActivity.getFoxActivity(MainApplication.INSTANCE!!).runOnUiThread {
// show toast
Toast.makeText(
MainApplication.INSTANCE, R.string.ssl_error, Toast.LENGTH_LONG
).show()
}
}
throw HttpException(e.message, 0)
}
if (response.isRedirect) { if (response.isRedirect) {
// follow redirect with same method // follow redirect with same method
Timber.d("doHttpPostRaw: following redirect: %s", response.header("Location")) Timber.d("doHttpPostRaw: following redirect: %s", response.header("Location"))
@ -623,8 +643,23 @@ enum class Http {;
@JvmStatic @JvmStatic
@Throws(IOException::class) @Throws(IOException::class)
fun doHttpGet(url: String, progressListener: ProgressListener): ByteArray { fun doHttpGet(url: String, progressListener: ProgressListener): ByteArray {
val response = val response: Response
getHttpClient()!!.newCall(Request.Builder().url(url).get().build()).execute() try {
response =
getHttpClient()!!.newCall(Request.Builder().url(url).get().build()).execute()
} catch (e: IOException) {
Timber.e(e, "Failed to post %s", url)
// detect ssl errors, i.e., cert authority invalid by looking at the message
if (e.message != null && e.message!!.contains("_CERT_")) {
MainActivity.getFoxActivity(MainApplication.INSTANCE!!).runOnUiThread {
// show toast
Toast.makeText(
MainApplication.INSTANCE, R.string.ssl_error, Toast.LENGTH_LONG
).show()
}
}
throw HttpException(e.message, 0)
}
if (response.code != 200 && response.code != 204) { if (response.code != 200 && response.code != 204) {
Timber.e("Failed to fetch " + url + ", code: " + response.code) Timber.e("Failed to fetch " + url + ", code: " + response.code)
checkNeedCaptchaAndroidacy(url, response.code) checkNeedCaptchaAndroidacy(url, response.code)
@ -733,7 +768,7 @@ enum class Http {;
// are we connected to a network with internet capabilities? // are we connected to a network with internet capabilities?
val networkCapabilities = val networkCapabilities =
connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork) connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
val systemSaysYes = networkCapabilities != null && networkCapabilities.hasCapability( val systemSaysYes = networkCapabilities != null && networkCapabilities.hasCapability(
NetworkCapabilities.NET_CAPABILITY_INTERNET NetworkCapabilities.NET_CAPABILITY_INTERNET
) )
Timber.d("System says we have internet: $systemSaysYes") Timber.d("System says we have internet: $systemSaysYes")
@ -757,17 +792,20 @@ enum class Http {;
if (!systemSaysYes) return false if (!systemSaysYes) return false
// check ourselves // check ourselves
val hasInternet = try { val hasInternet = try {
val resp = doHttpGet("https://production-api.androidacy.com/ping", false) val resp = doHttpGet("https://production-api.androidacy.com/cdn-cgi/trace", false)
val respString = String(resp) val respString = String(resp)
Timber.d("Ping response: $respString") Timber.d("Ping response: $respString")
true // resp should include that scheme is https and h is production-api.androidacy.com
respString.contains("scheme=https") && respString.contains("h=production-api.androidacy.com")
} catch (e: HttpException) { } catch (e: HttpException) {
Timber.e(e, "Failed to check internet connection") Timber.e(e, "Failed to check internet connection")
false false
} }
Timber.d("We say we have internet: $hasInternet") Timber.d("We say we have internet: $hasInternet")
lastConnectivityCheck = System.currentTimeMillis() lastConnectivityCheck = System.currentTimeMillis()
lastConnectivityResult = systemSaysYes && hasInternet @Suppress("KotlinConstantConditions")
lastConnectivityResult =
systemSaysYes && hasInternet
return lastConnectivityResult return lastConnectivityResult
} }
} }

@ -386,4 +386,5 @@
<string name="logs_saved">Saved logs successfully</string> <string name="logs_saved">Saved logs successfully</string>
<string name="error_opening_notes">Error in opening module notes. Logs may have the reason.</string> <string name="error_opening_notes">Error in opening module notes. Logs may have the reason.</string>
<string name="submit_feedback">Submit feedback</string> <string name="submit_feedback">Submit feedback</string>
<string name="ssl_error">Potential SSL interception detected.</string>
</resources> </resources>

Loading…
Cancel
Save