You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
119 lines
5.1 KiB
Kotlin
119 lines
5.1 KiB
Kotlin
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
package org.mozilla.fenix
|
|
|
|
import android.content.Context
|
|
import mozilla.components.browser.errorpages.ErrorPages
|
|
import mozilla.components.browser.errorpages.ErrorType
|
|
import mozilla.components.concept.engine.EngineSession
|
|
import mozilla.components.concept.engine.request.RequestInterceptor
|
|
import org.mozilla.fenix.components.metrics.Event
|
|
import org.mozilla.fenix.exceptions.ExceptionDomains
|
|
import org.mozilla.fenix.ext.components
|
|
import org.mozilla.fenix.ext.settings
|
|
import org.mozilla.fenix.ext.tryGetHostFromUrl
|
|
|
|
class AppRequestInterceptor(private val context: Context) : RequestInterceptor {
|
|
override fun onLoadRequest(session: EngineSession, uri: String): RequestInterceptor.InterceptionResponse? {
|
|
val host = uri.tryGetHostFromUrl()
|
|
|
|
adjustTrackingProtection(host, context, session)
|
|
|
|
// WebChannel-driven authentication does not require a separate redirect interceptor.
|
|
return if (context.isInExperiment(Experiments.asFeatureWebChannelsDisabled)) {
|
|
context.components.services.accountsAuthFeature.interceptor.onLoadRequest(session, uri)
|
|
} else {
|
|
null
|
|
}
|
|
}
|
|
|
|
private fun adjustTrackingProtection(host: String, context: Context, session: EngineSession) {
|
|
val trackingProtectionException = ExceptionDomains(context).load().contains(host)
|
|
val trackingProtectionEnabled = context.settings().shouldUseTrackingProtection
|
|
if (trackingProtectionException || !trackingProtectionEnabled) {
|
|
session.disableTrackingProtection()
|
|
} else {
|
|
val core = context.components.core
|
|
val policy = core.createTrackingProtectionPolicy(normalMode = true)
|
|
core.engine.settings.trackingProtectionPolicy = policy
|
|
session.enableTrackingProtection(policy)
|
|
}
|
|
}
|
|
|
|
override fun onErrorRequest(
|
|
session: EngineSession,
|
|
errorType: ErrorType,
|
|
uri: String?
|
|
): RequestInterceptor.ErrorResponse? {
|
|
val riskLevel = getRiskLevel(errorType)
|
|
val htmlResource = getPageForRiskLevel(riskLevel)
|
|
val cssResource = getStyleForRiskLevel(riskLevel)
|
|
|
|
context.components.analytics.metrics.track(Event.ErrorPageVisited(errorType))
|
|
return RequestInterceptor.ErrorResponse(
|
|
ErrorPages
|
|
.createErrorPage(context, errorType, uri = uri, htmlResource = htmlResource, cssResource = cssResource)
|
|
)
|
|
}
|
|
|
|
private fun getPageForRiskLevel(riskLevel: RiskLevel): Int {
|
|
return when (riskLevel) {
|
|
RiskLevel.Low -> R.raw.low_risk_error_pages
|
|
RiskLevel.Medium -> R.raw.medium_and_high_risk_error_pages
|
|
RiskLevel.High -> R.raw.medium_and_high_risk_error_pages
|
|
}
|
|
}
|
|
|
|
private fun getStyleForRiskLevel(riskLevel: RiskLevel): Int {
|
|
return when (riskLevel) {
|
|
RiskLevel.Low -> R.raw.low_and_medium_risk_error_style
|
|
RiskLevel.Medium -> R.raw.low_and_medium_risk_error_style
|
|
RiskLevel.High -> R.raw.high_risk_error_style
|
|
}
|
|
}
|
|
|
|
private fun getRiskLevel(errorType: ErrorType): RiskLevel {
|
|
return when (errorType) {
|
|
// Low risk errors
|
|
ErrorType.UNKNOWN -> RiskLevel.Low
|
|
ErrorType.ERROR_NET_INTERRUPT -> RiskLevel.Low
|
|
ErrorType.ERROR_NET_TIMEOUT -> RiskLevel.Low
|
|
ErrorType.ERROR_CONNECTION_REFUSED -> RiskLevel.Low
|
|
ErrorType.ERROR_UNKNOWN_SOCKET_TYPE -> RiskLevel.Low
|
|
ErrorType.ERROR_REDIRECT_LOOP -> RiskLevel.Low
|
|
ErrorType.ERROR_OFFLINE -> RiskLevel.Low
|
|
ErrorType.ERROR_NET_RESET -> RiskLevel.Low
|
|
ErrorType.ERROR_UNSAFE_CONTENT_TYPE -> RiskLevel.Low
|
|
ErrorType.ERROR_CORRUPTED_CONTENT -> RiskLevel.Low
|
|
ErrorType.ERROR_CONTENT_CRASHED -> RiskLevel.Low
|
|
ErrorType.ERROR_INVALID_CONTENT_ENCODING -> RiskLevel.Low
|
|
ErrorType.ERROR_UNKNOWN_HOST -> RiskLevel.Low
|
|
ErrorType.ERROR_MALFORMED_URI -> RiskLevel.Low
|
|
ErrorType.ERROR_FILE_NOT_FOUND -> RiskLevel.Low
|
|
ErrorType.ERROR_FILE_ACCESS_DENIED -> RiskLevel.Low
|
|
ErrorType.ERROR_PROXY_CONNECTION_REFUSED -> RiskLevel.Low
|
|
ErrorType.ERROR_UNKNOWN_PROXY_HOST -> RiskLevel.Low
|
|
ErrorType.ERROR_UNKNOWN_PROTOCOL -> RiskLevel.Low
|
|
|
|
// Medium risk errors
|
|
ErrorType.ERROR_SECURITY_BAD_CERT -> RiskLevel.Medium
|
|
ErrorType.ERROR_SECURITY_SSL -> RiskLevel.Medium
|
|
ErrorType.ERROR_PORT_BLOCKED -> RiskLevel.Medium
|
|
|
|
// High risk errors
|
|
ErrorType.ERROR_SAFEBROWSING_HARMFUL_URI -> RiskLevel.High
|
|
ErrorType.ERROR_SAFEBROWSING_MALWARE_URI -> RiskLevel.High
|
|
ErrorType.ERROR_SAFEBROWSING_PHISHING_URI -> RiskLevel.High
|
|
ErrorType.ERROR_SAFEBROWSING_UNWANTED_URI -> RiskLevel.High
|
|
}
|
|
}
|
|
|
|
sealed class RiskLevel {
|
|
object Low : RiskLevel()
|
|
object Medium : RiskLevel()
|
|
object High : RiskLevel()
|
|
}
|
|
}
|