summaryrefslogtreecommitdiffstats
path: root/mobile/android/android-components/components/lib/fetch-okhttp
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-15 03:35:49 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-15 03:35:49 +0000
commitd8bbc7858622b6d9c278469aab701ca0b609cddf (patch)
treeeff41dc61d9f714852212739e6b3738b82a2af87 /mobile/android/android-components/components/lib/fetch-okhttp
parentReleasing progress-linux version 125.0.3-1~progress7.99u1. (diff)
downloadfirefox-d8bbc7858622b6d9c278469aab701ca0b609cddf.tar.xz
firefox-d8bbc7858622b6d9c278469aab701ca0b609cddf.zip
Merging upstream version 126.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'mobile/android/android-components/components/lib/fetch-okhttp')
-rw-r--r--mobile/android/android-components/components/lib/fetch-okhttp/README.md25
-rw-r--r--mobile/android/android-components/components/lib/fetch-okhttp/build.gradle43
-rw-r--r--mobile/android/android-components/components/lib/fetch-okhttp/proguard-rules.pro21
-rw-r--r--mobile/android/android-components/components/lib/fetch-okhttp/src/main/AndroidManifest.xml4
-rw-r--r--mobile/android/android-components/components/lib/fetch-okhttp/src/main/java/mozilla/components/lib/fetch/okhttp/OkHttpClient.kt149
-rw-r--r--mobile/android/android-components/components/lib/fetch-okhttp/src/test/java/mozilla/components/lib/fetch/okhttp/OkHttpFetchTestCases.kt27
-rw-r--r--mobile/android/android-components/components/lib/fetch-okhttp/src/test/resources/robolectric.properties1
7 files changed, 270 insertions, 0 deletions
diff --git a/mobile/android/android-components/components/lib/fetch-okhttp/README.md b/mobile/android/android-components/components/lib/fetch-okhttp/README.md
new file mode 100644
index 0000000000..d1cd0a3d2f
--- /dev/null
+++ b/mobile/android/android-components/components/lib/fetch-okhttp/README.md
@@ -0,0 +1,25 @@
+# [Android Components](../../../README.md) > Libraries > Fetch-OkHttp
+
+A [concept-fetch](../../concept/fetch/README.md) implementation using [OkHttp](https://github.com/square/okhttp).
+
+This implementation of `concept-fetch` uses [OkHttp](https://github.com/square/okhttp) - a third-party library from Square. It is intended for apps that already use OkHttp and want components to use the same client.
+
+## Usage
+
+### Setting up the dependency
+
+Use Gradle to download the library from [maven.mozilla.org](https://maven.mozilla.org/) ([Setup repository](../../../README.md#maven-repository)):
+
+```Groovy
+implementation "org.mozilla.components:lib-fetch-okhttp:{latest-version}"
+```
+
+### Performing requests
+
+See the [concept-fetch documentation](../../concept/fetch/README.md) for generic examples of using the API of components implementing `concept-fetch`.
+
+## License
+
+ 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/
diff --git a/mobile/android/android-components/components/lib/fetch-okhttp/build.gradle b/mobile/android/android-components/components/lib/fetch-okhttp/build.gradle
new file mode 100644
index 0000000000..c7f1dd9495
--- /dev/null
+++ b/mobile/android/android-components/components/lib/fetch-okhttp/build.gradle
@@ -0,0 +1,43 @@
+/* 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/. */
+
+apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
+
+android {
+ defaultConfig {
+ minSdkVersion config.minSdkVersion
+ compileSdk config.compileSdkVersion
+ targetSdkVersion config.targetSdkVersion
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+
+ namespace 'mozilla.components.lib.fetch.okhttp'
+
+}
+
+dependencies {
+ implementation ComponentsDependencies.kotlin_coroutines
+
+ implementation ComponentsDependencies.thirdparty_okhttp
+ implementation ComponentsDependencies.thirdparty_okhttp_urlconnection
+
+ implementation project(':concept-fetch')
+
+ testImplementation project(':support-test')
+
+ testImplementation ComponentsDependencies.androidx_test_junit
+ testImplementation ComponentsDependencies.testing_robolectric
+ testImplementation project(':tooling-fetch-tests')
+}
+
+apply from: '../../../android-lint.gradle'
+apply from: '../../../publish.gradle'
+ext.configurePublish(config.componentsGroupId, archivesBaseName, project.ext.description)
diff --git a/mobile/android/android-components/components/lib/fetch-okhttp/proguard-rules.pro b/mobile/android/android-components/components/lib/fetch-okhttp/proguard-rules.pro
new file mode 100644
index 0000000000..f1b424510d
--- /dev/null
+++ b/mobile/android/android-components/components/lib/fetch-okhttp/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/mobile/android/android-components/components/lib/fetch-okhttp/src/main/AndroidManifest.xml b/mobile/android/android-components/components/lib/fetch-okhttp/src/main/AndroidManifest.xml
new file mode 100644
index 0000000000..e16cda1d34
--- /dev/null
+++ b/mobile/android/android-components/components/lib/fetch-okhttp/src/main/AndroidManifest.xml
@@ -0,0 +1,4 @@
+<!-- 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/. -->
+<manifest />
diff --git a/mobile/android/android-components/components/lib/fetch-okhttp/src/main/java/mozilla/components/lib/fetch/okhttp/OkHttpClient.kt b/mobile/android/android-components/components/lib/fetch-okhttp/src/main/java/mozilla/components/lib/fetch/okhttp/OkHttpClient.kt
new file mode 100644
index 0000000000..0b885eee44
--- /dev/null
+++ b/mobile/android/android-components/components/lib/fetch-okhttp/src/main/java/mozilla/components/lib/fetch/okhttp/OkHttpClient.kt
@@ -0,0 +1,149 @@
+/* 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 mozilla.components.lib.fetch.okhttp
+
+import android.content.Context
+import mozilla.components.concept.fetch.BuildConfig
+import mozilla.components.concept.fetch.Client
+import mozilla.components.concept.fetch.Headers
+import mozilla.components.concept.fetch.MutableHeaders
+import mozilla.components.concept.fetch.Request
+import mozilla.components.concept.fetch.Response
+import mozilla.components.concept.fetch.isDataUri
+import mozilla.components.lib.fetch.okhttp.OkHttpClient.Companion.CACHE_MAX_SIZE
+import mozilla.components.lib.fetch.okhttp.OkHttpClient.Companion.getOrCreateCookieManager
+import okhttp3.Cache
+import okhttp3.CacheControl
+import okhttp3.JavaNetCookieJar
+import okhttp3.OkHttpClient
+import okhttp3.RequestBody.Companion.toRequestBody
+import java.net.CookieHandler
+import java.net.CookieManager
+
+typealias RequestBuilder = okhttp3.Request.Builder
+
+/**
+ * [Client] implementation using OkHttp.
+ */
+class OkHttpClient(
+ private val client: OkHttpClient = OkHttpClient(),
+ private val context: Context? = null,
+) : Client() {
+ private val defaultHeaders: Headers = MutableHeaders(
+ "User-Agent" to "MozacFetch/${BuildConfig.LIBRARY_VERSION}",
+ "Accept-Encoding" to "gzip",
+ )
+
+ override fun fetch(request: Request): Response {
+ if (request.private) {
+ throw IllegalArgumentException("Client doesn't support private request")
+ }
+
+ if (request.isDataUri()) {
+ return fetchDataUri(request)
+ }
+
+ val requestClient = client.rebuildFor(request, context)
+
+ val requestBuilder = createRequestBuilderWithBody(request)
+ requestBuilder.addHeadersFrom(request, defaultHeaders = defaultHeaders)
+
+ if (!request.useCaches) {
+ requestBuilder.cacheControl(CacheControl.FORCE_NETWORK)
+ }
+
+ val actualResponse = requestClient.newCall(
+ requestBuilder.build(),
+ ).execute()
+
+ return actualResponse.toResponse()
+ }
+
+ companion object {
+ internal const val CACHE_MAX_SIZE: Long = 10L * 1024L * 1024L
+
+ fun getOrCreateCookieManager(): CookieManager {
+ if (CookieHandler.getDefault() == null) {
+ CookieHandler.setDefault(CookieManager())
+ }
+ return CookieHandler.getDefault() as CookieManager
+ }
+ }
+}
+
+private fun OkHttpClient.rebuildFor(request: Request, context: Context?): OkHttpClient {
+ @Suppress("ComplexCondition")
+ if (request.connectTimeout != null ||
+ request.readTimeout != null ||
+ request.redirect != Request.Redirect.FOLLOW ||
+ request.cookiePolicy != Request.CookiePolicy.OMIT
+ ) {
+ val clientBuilder = newBuilder()
+
+ request.connectTimeout?.let { (timeout, unit) -> clientBuilder.connectTimeout(timeout, unit) }
+ request.readTimeout?.let { (timeout, unit) -> clientBuilder.readTimeout(timeout, unit) }
+
+ if (request.redirect == Request.Redirect.MANUAL) {
+ clientBuilder.followRedirects(false)
+ }
+
+ if (request.cookiePolicy == Request.CookiePolicy.INCLUDE) {
+ clientBuilder.cookieJar(JavaNetCookieJar(getOrCreateCookieManager()))
+ }
+
+ context?.let {
+ clientBuilder.cache(Cache(context.cacheDir, CACHE_MAX_SIZE))
+ }
+
+ return clientBuilder.build()
+ }
+
+ return this
+}
+
+private fun okhttp3.Response.toResponse(): Response {
+ val body = body
+ val headers = translateHeaders(headers)
+
+ return Response(
+ url = request.url.toString(),
+ headers = headers,
+ status = code,
+ body = if (body != null) Response.Body(body.byteStream(), headers["Content-Type"]) else Response.Body.empty(),
+ )
+}
+
+private fun createRequestBuilderWithBody(request: Request): RequestBuilder {
+ val requestBody = request.body?.useStream { it.readBytes() }?.let {
+ it.toRequestBody(null, 0, it.size)
+ }
+
+ return RequestBuilder()
+ .url(request.url)
+ .method(request.method.name, requestBody)
+}
+
+private fun RequestBuilder.addHeadersFrom(request: Request, defaultHeaders: Headers) {
+ defaultHeaders
+ .filter { header ->
+ request.headers?.contains(header.name) != true
+ }.filter { header ->
+ header.name != "Accept-Encoding" && header.value != "gzip"
+ }.forEach { header ->
+ addHeader(header.name, header.value)
+ }
+
+ request.headers?.forEach { header -> addHeader(header.name, header.value) }
+}
+
+private fun translateHeaders(actualHeaders: okhttp3.Headers): Headers {
+ val headers = MutableHeaders()
+
+ for (i in 0 until actualHeaders.size) {
+ headers.append(actualHeaders.name(i), actualHeaders.value(i))
+ }
+
+ return headers
+}
diff --git a/mobile/android/android-components/components/lib/fetch-okhttp/src/test/java/mozilla/components/lib/fetch/okhttp/OkHttpFetchTestCases.kt b/mobile/android/android-components/components/lib/fetch-okhttp/src/test/java/mozilla/components/lib/fetch/okhttp/OkHttpFetchTestCases.kt
new file mode 100644
index 0000000000..50610409c3
--- /dev/null
+++ b/mobile/android/android-components/components/lib/fetch-okhttp/src/test/java/mozilla/components/lib/fetch/okhttp/OkHttpFetchTestCases.kt
@@ -0,0 +1,27 @@
+/* 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 mozilla.components.lib.fetch.okhttp
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import mozilla.components.concept.fetch.Client
+import mozilla.components.support.test.robolectric.testContext
+import mozilla.components.tooling.fetch.tests.FetchTestCases
+import org.junit.Assert.assertTrue
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class OkHttpFetchTestCases : FetchTestCases() {
+
+ override fun createNewClient(): Client = OkHttpClient(okhttp3.OkHttpClient(), testContext)
+
+ // Inherits test methods from generic test suite base class
+
+ @Test
+ fun `Client instance`() {
+ // We need at least one test case defined here so that this is recognized as test class.
+ assertTrue(createNewClient() is OkHttpClient)
+ }
+}
diff --git a/mobile/android/android-components/components/lib/fetch-okhttp/src/test/resources/robolectric.properties b/mobile/android/android-components/components/lib/fetch-okhttp/src/test/resources/robolectric.properties
new file mode 100644
index 0000000000..932b01b9eb
--- /dev/null
+++ b/mobile/android/android-components/components/lib/fetch-okhttp/src/test/resources/robolectric.properties
@@ -0,0 +1 @@
+sdk=28