diff --git a/app/src/main/java/org/mozilla/focus/Components.kt b/app/src/main/java/org/mozilla/focus/Components.kt index 608a85d81f7..ea7793af345 100644 --- a/app/src/main/java/org/mozilla/focus/Components.kt +++ b/app/src/main/java/org/mozilla/focus/Components.kt @@ -27,6 +27,7 @@ import mozilla.components.feature.tabs.CustomTabsUseCases import mozilla.components.feature.tabs.TabsUseCases import org.mozilla.focus.components.EngineProvider import org.mozilla.focus.downloads.DownloadService +import org.mozilla.focus.engine.ClientWrapper import org.mozilla.focus.engine.LocalizedContentInterceptor import org.mozilla.focus.engine.SanityCheckMiddleware import org.mozilla.focus.notification.PrivateNotificationMiddleware @@ -62,8 +63,8 @@ class Components( } } - val client: Client by lazy { - clientOverride ?: EngineProvider.createClient(context) + val client: ClientWrapper by lazy { + ClientWrapper(clientOverride ?: EngineProvider.createClient(context)) } val trackingProtectionUseCases by lazy { TrackingProtectionUseCases(store, engine) } diff --git a/app/src/main/java/org/mozilla/focus/engine/ClientWrapper.kt b/app/src/main/java/org/mozilla/focus/engine/ClientWrapper.kt new file mode 100644 index 00000000000..fbdb92837ba --- /dev/null +++ b/app/src/main/java/org/mozilla/focus/engine/ClientWrapper.kt @@ -0,0 +1,29 @@ +/* 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.focus.engine + +import mozilla.components.concept.fetch.Client +import mozilla.components.concept.fetch.Request +import mozilla.components.concept.fetch.Response + +/** + * A wrapper around [Client] preventing [Request]s without the private flag set. + */ +class ClientWrapper( + private val actual: Client +) : Client() { + override fun fetch(request: Request): Response { + if (!request.private) { + throw IllegalStateException("Non-private request") + } + + return actual.fetch(request) + } + + @Deprecated("Non-private Client usage should be prevented") + fun unwrap(): Client { + return actual + } +} diff --git a/app/src/main/java/org/mozilla/focus/searchsuggestions/SearchSuggestionsFetcher.kt b/app/src/main/java/org/mozilla/focus/searchsuggestions/SearchSuggestionsFetcher.kt index d74b7962c97..a0b1a9448fd 100644 --- a/app/src/main/java/org/mozilla/focus/searchsuggestions/SearchSuggestionsFetcher.kt +++ b/app/src/main/java/org/mozilla/focus/searchsuggestions/SearchSuggestionsFetcher.kt @@ -81,7 +81,8 @@ class SearchSuggestionsFetcher( val request = FetchRequest( url = url.sanitizeURL(), readTimeout = Pair(READ_TIMEOUT_IN_MS, TimeUnit.MILLISECONDS), - connectTimeout = Pair(CONNECT_TIMEOUT_IN_MS, TimeUnit.MILLISECONDS) + connectTimeout = Pair(CONNECT_TIMEOUT_IN_MS, TimeUnit.MILLISECONDS), + private = true ) return fetchClient.fetch(request).body.string() } diff --git a/app/src/main/java/org/mozilla/focus/settings/ManualAddSearchEngineSettingsFragment.kt b/app/src/main/java/org/mozilla/focus/settings/ManualAddSearchEngineSettingsFragment.kt index 6d8141ffd71..032d6eb41b2 100644 --- a/app/src/main/java/org/mozilla/focus/settings/ManualAddSearchEngineSettingsFragment.kt +++ b/app/src/main/java/org/mozilla/focus/settings/ManualAddSearchEngineSettingsFragment.kt @@ -196,7 +196,8 @@ class ManualAddSearchEngineSettingsFragment : BaseSettingsFragment() { url = searchURLStr, connectTimeout = SEARCH_QUERY_VALIDATION_TIMEOUT_MILLIS.toLong() to TimeUnit.MILLISECONDS, readTimeout = SEARCH_QUERY_VALIDATION_TIMEOUT_MILLIS.toLong() to TimeUnit.MILLISECONDS, - redirect = FOLLOW + redirect = FOLLOW, + private = true ) return try { diff --git a/app/src/main/java/org/mozilla/focus/telemetry/TelemetryWrapper.kt b/app/src/main/java/org/mozilla/focus/telemetry/TelemetryWrapper.kt index 8c25b199ffa..7589d03d026 100644 --- a/app/src/main/java/org/mozilla/focus/telemetry/TelemetryWrapper.kt +++ b/app/src/main/java/org/mozilla/focus/telemetry/TelemetryWrapper.kt @@ -264,7 +264,7 @@ object TelemetryWrapper { val serializer = JSONPingSerializer() val storage = FileTelemetryStorage(configuration, serializer) - val client = TelemetryClient(context.components.client) + val client = TelemetryClient(context.components.client.unwrap()) val scheduler = JobSchedulerTelemetryScheduler() TelemetryHolder.set(Telemetry(configuration, storage, client, scheduler) diff --git a/app/src/test/java/org/mozilla/focus/settings/SearchEngineValidationTest.kt b/app/src/test/java/org/mozilla/focus/settings/SearchEngineValidationTest.kt index 784b0b5441c..90ab7c40103 100644 --- a/app/src/test/java/org/mozilla/focus/settings/SearchEngineValidationTest.kt +++ b/app/src/test/java/org/mozilla/focus/settings/SearchEngineValidationTest.kt @@ -5,6 +5,8 @@ package org.mozilla.focus.settings import mozilla.components.concept.fetch.Client +import mozilla.components.concept.fetch.Request +import mozilla.components.concept.fetch.Response import mozilla.components.lib.fetch.okhttp.OkHttpClient import okhttp3.mockwebserver.MockResponse import okhttp3.mockwebserver.MockWebServer @@ -25,7 +27,7 @@ class SearchEngineValidationTest { @Before fun setup() { - client = OkHttpClient() + client = OkHttpWrapper() } @Test @@ -78,4 +80,15 @@ private fun MockWebServer.rootUrl(): String = url("/").toString() private fun responseWithStatus(status: Int) = MockResponse() .setResponseCode(status) - .setBody("") \ No newline at end of file + .setBody("") + +private class OkHttpWrapper: Client() { + private val actual = OkHttpClient() + + override fun fetch(request: Request): Response { + // OkHttpClient does not support private requests. Therefore we make them non-private for + // testing purposes + val nonPrivate = request.copy(private = false) + return actual.fetch(nonPrivate) + } +} \ No newline at end of file