Bug 1881128 - Add additional headers for Google requests
[gecko.git] / mobile / android / fenix / app / src / main / java / org / mozilla / fenix / components / UrlRequestInterceptor.kt
blob74e270f70d5a670ff0f2e38e41728550cd0f227d
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 package org.mozilla.fenix.components
7 import androidx.annotation.VisibleForTesting
8 import mozilla.components.concept.engine.EngineSession
9 import mozilla.components.concept.engine.EngineSession.LoadUrlFlags
10 import mozilla.components.concept.engine.EngineSession.LoadUrlFlags.Companion.ALLOW_ADDITIONAL_HEADERS
11 import mozilla.components.concept.engine.EngineSession.LoadUrlFlags.Companion.LOAD_FLAGS_BYPASS_LOAD_URI_DELEGATE
12 import mozilla.components.concept.engine.request.RequestInterceptor
14 /**
15  * [RequestInterceptor] implementation for intercepting URL load requests to allow custom
16  * behaviour.
17  *
18  * @param isDeviceRamAboveThreshold Whether or not the device ram is above a threshold.
19  */
20 class UrlRequestInterceptor(private val isDeviceRamAboveThreshold: Boolean) : RequestInterceptor {
22     private val isGoogleRequest by lazy {
23         Regex("^https://www\\.google\\..+")
24     }
26     @VisibleForTesting
27     internal fun getAdditionalHeaders(isDeviceRamAboveThreshold: Boolean): Map<String, String> {
28         val value = if (isDeviceRamAboveThreshold) {
29             "1"
30         } else {
31             "0"
32         }
34         return mapOf(
35             "X-Search-Subdivision" to value,
36         )
37     }
39     @VisibleForTesting
40     internal fun shouldInterceptRequest(
41         uri: String,
42         isSubframeRequest: Boolean,
43     ): Boolean {
44         return !isSubframeRequest && isGoogleRequest.containsMatchIn(uri)
45     }
47     override fun onLoadRequest(
48         engineSession: EngineSession,
49         uri: String,
50         lastUri: String?,
51         hasUserGesture: Boolean,
52         isSameDomain: Boolean,
53         isRedirect: Boolean,
54         isDirectNavigation: Boolean,
55         isSubframeRequest: Boolean,
56     ): RequestInterceptor.InterceptionResponse? {
57         if (!shouldInterceptRequest(uri = uri, isSubframeRequest = isSubframeRequest)) {
58             return null
59         }
61         return RequestInterceptor.InterceptionResponse.Url(
62             url = uri,
63             flags = LoadUrlFlags.select(
64                 LOAD_FLAGS_BYPASS_LOAD_URI_DELEGATE,
65                 ALLOW_ADDITIONAL_HEADERS,
66             ),
67             additionalHeaders = getAdditionalHeaders(isDeviceRamAboveThreshold),
68         )
69     }