Skip to content

KTOR-6886: Android Http Client using Android's HttpEngine on API 34+ - #4013

Open
Yuri Schimke (yschimke) wants to merge 1 commit into
ktorio:mainfrom
yschimke:android14
Open

Yuri Schimke (yschimke) wants to merge 1 commit into
ktorio:mainfrom
yschimke:android14

Conversation

@yschimke

@yschimke Yuri Schimke (yschimke) commented Mar 31, 2024 •

Copy link
Copy Markdown

Subsystem
Client

Motivation
On Android UrlConnection by default doesn't support HTTP/2, and is an old stack.

HttpEngine is now part of the Android 14 APIs (API 34+), and supports HTTP/2, HTTP/3 and much more advanced features.

Apps can install this as the process singleton URL handler, but this could have other impacts.

Solution

Rather than switching to the very different API HttpEngine, this change minimises the differences by using HttpEngine.openConnection(URL) and otherwise working the same as the existing UrlConnection code.

TODO

  • Cleanup
  • Work out how to run the included but non functional instrumentation test

@yschimke Yuri Schimke (yschimke) changed the title [For discussion] Android use HttpEngine UrlFactory on API 14+ [For discussion] Android Http Client using Android's HttpEngine on API 14+ Mar 31, 2024
@yschimke Yuri Schimke (yschimke) changed the title [For discussion] Android Http Client using Android's HttpEngine on API 14+ [For discussion] Android Http Client using Android's HttpEngine on API 34+ Apr 1, 2024
@yschimke Yuri Schimke (yschimke) changed the title [For discussion] Android Http Client using Android's HttpEngine on API 34+ [KTOR-6886] Android Http Client using Android's HttpEngine on API 34+ Apr 1, 2024
@yschimke

Copy link
Copy Markdown
Author

Leonid Stashevsky (@e5l) Osip Fatkullin (@osipxd) let me know if I should rebase my change, or if you want to take over the PR?

@coderabbitai

coderabbitai Bot commented Mar 22, 2025 •

Copy link
Copy Markdown
Contributor

Walkthrough

Adds Robolectric to the version catalog, exposes context and httpEngineConfig on AndroidEngineConfig, introduces URLConnectionFactory and AndroidNetHttpEngineFactory, switches AndroidClientEngine to a pluggable URLConnection factory, and adds Android-specific tests and build deps.

Changes

Cohort / File(s) Summary of changes
Version catalog
gradle/libs.versions.toml
Added robolectric-android version alias and robolectric-android library (org.robolectric:android-all).
Android engine public API
ktor-client/ktor-client-android/api/ktor-client-android.api
Added accessors for context and httpEngineConfig on AndroidEngineConfig (getContext/setContext, getHttpEngineConfig/setHttpEngineConfig).
Build configuration
ktor-client/ktor-client-android/build.gradle.kts
Added compileOnly(libs.robolectric.android) to jvmMain and implementation(libs.robolectric.android) to jvmTest.
Engine config & utilities
.../AndroidEngineConfig.kt, .../AndroidURLConnectionUtils.kt
Added public httpEngineConfig: HttpEngine.Builder.() -> Unit, public nullable context property, internal httpEngineDisabled flag; added isAndroid and isHttpEngineAvailable() runtime checks.
URLConnection factories
.../URLConnectionFactory.kt, .../Android14URLConnectionFactory.kt
Introduced internal URLConnectionFactory and StandardURLConnectionFactory; added AndroidNetHttpEngineFactory that builds and uses Android HttpEngine to open connections.
Engine runtime logic
ktor-client/ktor-client-android/jvm/src/.../AndroidClientEngine.kt
Replaced direct HttpURLConnection creation with urlFactory(url) selection (standard vs Android engine), removed proxy helper, and adjusted protocol detection to use factory.
Android instrumented tests
ktor-client/ktor-client-android/jvm/androidTest/.../AndroidEngineTest.kt
Added AndroidEngineTest with testHttpEngine, testHttpEngineConfig, and testUrlConnection exercising Android engine and fallback paths.
JVM HTTPS tests
ktor-client/ktor-client-android/jvm/test/.../AndroidSpecificHttpsTest.kt
Added withAndroid14Customisations() test using httpEngineConfig, sslManager, and Android-specific options; asserts HTTPS response.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

Possibly related PRs

Suggested reviewers

  • osipxd
  • bjhham
  • e5l

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding Android HttpEngine support for API 34+, which aligns with the comprehensive modifications across build configuration, engine factory logic, and test coverage.
Description check ✅ Passed The description covers all required template sections (Subsystem, Motivation, Solution) with substantive content explaining the problem, rationale, and implementation approach, though the instrumentation test remains incomplete.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 718191a and 03a10b2.

📒 Files selected for processing (1)
  • ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/Android14URLConnectionFactory.kt
🚧 Files skipped from review as they are similar to previous changes (1)
  • ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/Android14URLConnectionFactory.kt

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@yschimke
Yuri Schimke (yschimke) marked this pull request as ready for review September 18, 2025 11:03
@yschimke

Yuri Schimke (yschimke) commented Sep 18, 2025 •

Copy link
Copy Markdown
Author

Osip Fatkullin (@osipxd) Bruce Hamilton (@bjhham) I'm assuming there will be some directional changes requested, so any chance at a review?

Any opinions on instrumentation tests?

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidClientEngine.kt (1)

57-67: sslManager won’t apply on Android 14 HttpEngine path.

HttpEngine’s URLConnection for HTTPS does not implement HttpsURLConnection; the docs explicitly say “we don't provide support for the HttpsURLConnection API,” so this block won’t run when the engine path is active. We should document this and advise using httpEngineConfig for TLS customization. (developer.android.com)

Apply this comment tweak to make it explicit:

-            // TODO document not active on Android 14
+            // Note: On Android 14+ HttpEngine path this is not invoked,
+            // because the connection is not an HttpsURLConnection. Use
+            // AndroidEngineConfig.httpEngineConfig for TLS customization.
             if (this is HttpsURLConnection) {
                 config.sslManager(this)
             }

Follow‑up: if feasible, consider mapping a subset of sslManager (e.g., custom SSLSocketFactory) into httpEngineConfig to ease migration.

🧹 Nitpick comments (14)
ktor-client/ktor-client-android/jvm/test/io/ktor/client/engine/android/AndroidSpecificHttpsTest.kt (3)

7-7: Avoid wildcard import for non-ktor packages.

Ktor guideline is to use star imports for io.ktor.* only. Prefer explicit imports for android.net.http symbols here.


49-54: Remove unused trust manager.

x509TrustManager is initialized but never used; drop the field and its assignment to keep the test minimal.

Apply this diff:

-        private lateinit var x509TrustManager: X509TrustManager
+        // trust manager not used in these tests

@@
-            x509TrustManager = tmf.trustManagers.first { it is X509TrustManager } as X509TrustManager
+            // no-op: we only use sslContext.socketFactory

Also applies to: 86-91


108-151: Test name vs. behavior.

This config block demonstrates Android 14 HttpEngine options, but since context is null the legacy URLConnection path is used. Consider adding a brief assertion/comment stating that the test intentionally exercises the no‑engine path, or gate an actual engine test behind a runtime check that isHttpEngineAvailable() and context are set.

ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidURLConnectionUtils.kt (1)

95-95: Make Android runtime detection more robust.

Checking only "Dalvik" can be brittle. Consider broadening detection to cover ART and vendor strings.

Apply this diff:

-internal val isAndroid: Boolean = "Dalvik" == System.getProperty("java.vm.name")
+internal val isAndroid: Boolean =
+    System.getProperty("java.runtime.name") == "Android Runtime" ||
+    System.getProperty("java.vm.vendor") == "The Android Project" ||
+    System.getProperty("java.vm.name") == "Dalvik"
ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/URLConnectionFactory.kt (1)

17-23: Guard against non-HTTP schemes.

Fail fast if a non-HTTP(S) URL slips through; prevents ClassCastException on unexpected protocols.

Apply this diff:

         override operator fun invoke(urlString: String): HttpURLConnection {
             val url = URL(urlString)
-            val connection: URLConnection = config.proxy?.let { url.openConnection(it) } ?: url.openConnection()
+            require(url.protocol == "http" || url.protocol == "https") {
+                "Unsupported protocol: ${url.protocol}"
+            }
+            val connection: URLConnection = config.proxy?.let { url.openConnection(it) } ?: url.openConnection()
             return connection as HttpURLConnection
         }
ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/Android14URLConnectionFactory.kt (4)

12-12: Defer engine creation; avoid eager init.

Build the engine on first use to reduce startup cost and avoid unnecessary class resolution.

Apply:

-    private val engine = buildEngine()
+    private val engine by lazy { buildEngine() }

20-22: Safer scheme guard and cast check.

Be explicit about supported schemes and provide a clearer error than ClassCastException if a non‑HTTP URL slips through.

Apply:

-    override operator fun invoke(urlString: String): HttpURLConnection {
-        return engine.openConnection(URI.create(urlString).toURL()) as HttpURLConnection
-    }
+    override operator fun invoke(urlString: String): HttpURLConnection {
+        val url = URI.create(urlString).toURL()
+        check(url.protocol == "http" || url.protocol == "https") {
+            "Unsupported URL scheme: ${url.protocol}"
+        }
+        val conn = engine.openConnection(url)
+        check(conn is HttpURLConnection) {
+            "Expected HttpURLConnection, got ${conn::class.java.name}"
+        }
+        return conn as HttpURLConnection
+    }

7-8: Narrow imports to used types.

Project guidelines only require star imports for io.ktor.*; prefer explicit imports here to avoid name pollution.

Apply:

-import android.net.http.*
-import java.net.*
+import android.net.http.HttpEngine
+import java.net.HttpURLConnection
+import java.net.URI

11-11: File/class naming mismatch.

File is Android14URLConnectionFactory.kt but class is AndroidNetHttpEngineFactory. Please align for discoverability.

Do you want to rename the file to AndroidNetHttpEngineFactory.kt or the class to Android14URLConnectionFactory?

ktor-client/ktor-client-android/jvm/androidTest/io/ktor/client/engine/android/AndroidEngineTest.kt (5)

1-3: Update header year.

Keep the header consistent with 2014–2024 used elsewhere.

Apply:

-/* 
-* Copyright 2014-2021 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
-*/
+/*
+* Copyright 2014-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
+*/

10-13: Align with project import style for Ktor packages.

Use star imports for io.ktor.* per guidelines.

Apply:

-import io.ktor.client.HttpClient
-import io.ktor.client.request.get
-import io.ktor.client.statement.bodyAsText
+import io.ktor.client.*
+import io.ktor.client.request.*
+import io.ktor.client.statement.*

Also add:

+import androidx.test.filters.SdkSuppress

29-54: Same here: close client; gate to API 34+.

Also avoids leaking threads/executors in CI.

Apply:

-    @Test
-    fun testHttpEngineConfig() = runTest {
+    @SdkSuppress(minSdkVersion = 34)
+    @Test
+    fun testHttpEngineConfig() = runTest {
         val client = HttpClient(Android.create {
             httpEngineDisabled = false
             context = InstrumentationRegistry.getInstrumentation().targetContext
-
             httpEngineConfig = {
                 setUserAgent("Xyz")
-
                 setEnableBrotli(true)
                 setEnableHttpCache(HttpEngine.Builder.HTTP_CACHE_IN_MEMORY, 10_000_000)
                 setConnectionMigrationOptions(
                     ConnectionMigrationOptions.Builder()
                         .setDefaultNetworkMigration(ConnectionMigrationOptions.MIGRATION_OPTION_ENABLED)
                         .setPathDegradationMigration(ConnectionMigrationOptions.MIGRATION_OPTION_ENABLED)
                         .setAllowNonDefaultNetworkUsage(ConnectionMigrationOptions.MIGRATION_OPTION_ENABLED)
                         .build(),
                 )
                 addQuicHint("github.com", 443, 443)
             }
         })
-
-        val response = client.get("https://github.com/robots.txt")
-
-        assertContains(response.bodyAsText(), "Disallow")
+        try {
+            val response = client.get("https://github.com/robots.txt")
+            assertContains(response.bodyAsText(), "Disallow")
+        } finally {
+            client.close()
+        }
     }

56-66: Remove println and close client.

Avoid noisy logs and ensure cleanup.

Apply:

     @Test
     fun testUrlConnection() = runTest {
         val client = HttpClient(Android.create {
             httpEngineDisabled = true
         })
-
-        val response = client.get("https://github.com/robots.txt")
-
-        println(response.bodyAsText())
-        assertContains(response.bodyAsText(), "Disallow")
+        try {
+            val response = client.get("https://github.com/robots.txt")
+            assertContains(response.bodyAsText(), "Disallow")
+        } finally {
+            client.close()
+        }
     }

25-27: Network flakiness risk.

Hitting github.com in tests can be flaky or blocked in CI. Consider a local test server, mock engine, or mark as Flaky/Large and skip in CI.

Do you want me to convert these to use Ktor’s MockEngine or spin up an embedded server for instrumentation?

Also applies to: 51-53, 62-65

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between af24a5a and 23a0d6b.

📒 Files selected for processing (10)
  • gradle/libs.versions.toml (2 hunks)
  • ktor-client/ktor-client-android/api/ktor-client-android.api (1 hunks)
  • ktor-client/ktor-client-android/build.gradle.kts (1 hunks)
  • ktor-client/ktor-client-android/jvm/androidTest/io/ktor/client/engine/android/AndroidEngineTest.kt (1 hunks)
  • ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/Android14URLConnectionFactory.kt (1 hunks)
  • ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidClientEngine.kt (3 hunks)
  • ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidEngineConfig.kt (2 hunks)
  • ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidURLConnectionUtils.kt (2 hunks)
  • ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/URLConnectionFactory.kt (1 hunks)
  • ktor-client/ktor-client-android/jvm/test/io/ktor/client/engine/android/AndroidSpecificHttpsTest.kt (2 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{kt,kts}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{kt,kts}: Follow Kotlin official style guide for all Kotlin source and build scripts
Use star imports for io.ktor.* packages
Max line length is 120 characters
Indent with 4 spaces in Kotlin code
Include a copyright header in new Kotlin files

Files:

  • ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidURLConnectionUtils.kt
  • ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/URLConnectionFactory.kt
  • ktor-client/ktor-client-android/jvm/test/io/ktor/client/engine/android/AndroidSpecificHttpsTest.kt
  • ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidClientEngine.kt
  • ktor-client/ktor-client-android/build.gradle.kts
  • ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidEngineConfig.kt
  • ktor-client/ktor-client-android/jvm/androidTest/io/ktor/client/engine/android/AndroidEngineTest.kt
  • ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/Android14URLConnectionFactory.kt
**/*.kt

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.kt: Document all public Kotlin APIs, including parameters, return types, and exceptions
Annotate internal APIs with internalapi
Follow Kotlin error-handling conventions and use specific Ktor exceptions

Files:

  • ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidURLConnectionUtils.kt
  • ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/URLConnectionFactory.kt
  • ktor-client/ktor-client-android/jvm/test/io/ktor/client/engine/android/AndroidSpecificHttpsTest.kt
  • ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidClientEngine.kt
  • ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidEngineConfig.kt
  • ktor-client/ktor-client-android/jvm/androidTest/io/ktor/client/engine/android/AndroidEngineTest.kt
  • ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/Android14URLConnectionFactory.kt
**/api/**

📄 CodeRabbit inference engine (CLAUDE.md)

Track all public API changes in the /api/ directories

Files:

  • ktor-client/ktor-client-android/api/ktor-client-android.api
🧠 Learnings (2)
📚 Learning: 2025-06-23T12:49:56.883Z
Learnt from: CR
PR: ktorio/ktor#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-23T12:49:56.883Z
Learning: Error handling should follow Kotlin conventions and use specific Ktor exceptions.

Applied to files:

  • ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidURLConnectionUtils.kt
  • ktor-client/ktor-client-android/jvm/test/io/ktor/client/engine/android/AndroidSpecificHttpsTest.kt
📚 Learning: 2025-05-07T13:42:29.388Z
Learnt from: osipxd
PR: ktorio/ktor#4822
File: ktor-server/ktor-server-plugins/ktor-server-i18n/build.gradle.kts:13-17
Timestamp: 2025-05-07T13:42:29.388Z
Learning: In Kotlin build scripts (build.gradle.kts), the preferred syntax for declaring dependencies is using the dot notation like `jvmTest.dependencies { ... }` rather than the nested version `jvmTest { dependencies { ... } }` as it reduces the nesting level by one and improves readability.

Applied to files:

  • ktor-client/ktor-client-android/build.gradle.kts
🧬 Code graph analysis (1)
ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidClientEngine.kt (1)
ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidURLConnectionUtils.kt (2)
  • isHttpEngineAvailable (97-99)
  • setupTimeoutAttributes (26-32)
🔇 Additional comments (8)
gradle/libs.versions.toml (2)

253-254: Scoped correctly for compilation/tests.

Keeping android-all in the version catalog and using it as compileOnly (main) and implementation (tests) is the right way to avoid leaking this heavy jar to consumers.


91-92: Confirmed: android.net.http.HttpEngine present in org.robolectric:android-all:16-robolectric-13921718
android/net/http/HttpEngine.class and android/net/http/HttpEngine$Builder.class found in the JAR.

ktor-client/ktor-client-android/build.gradle.kts (1)

16-18: Good dependency scoping.

  • compileOnly(libs.robolectric.android) in jvmMain avoids shipping android-all.
  • implementation(libs.robolectric.android) in jvmTest enables tests.
    Matches our prior preference for jvmTest.dependencies { ... } style.

Also applies to: 23-23

ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidClientEngine.kt (2)

37-46: Engine selection logic looks sound.

Gating on: disabled flag, availability, proxy presence, and null context matches the Android HttpEngine contract. Note: HttpEngine APIs are “Added in API level 34; also in S Extensions 7,” so the isHttpEngineAvailable() premise is correct. (developer.android.com)

Please confirm our availability check stays in sync with Android docs if the required Extension level changes in future releases.


100-107: HTTP version derivation via factory is a clean seam.

Returning HTTP/1.1 for the standard path is acceptable; Android HttpEngine can override to expose negotiated versions when available.

ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidURLConnectionUtils.kt (1)

97-99: Availability check matches platform docs.

Requiring S Extensions ≥ 7 (and SDK ≥ 30) aligns with where HttpEngine openConnection is introduced. Keep this centralized and referenced from KDoc. (developer.android.com)

ktor-client/ktor-client-android/api/ktor-client-android.api (1)

20-28: API surface change acknowledged; add migration note.

New accessors for context and httpEngineConfig are now part of the public API. Please add a brief migration/release note clarifying:

  • context is required to enable the Android HttpEngine path.
  • sslManager doesn’t apply on that path; use httpEngineConfig instead.
ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/Android14URLConnectionFactory.kt (1)

10-12: Guard AndroidNetHttpEngineFactory from being class‑loaded on devices without HttpEngine

  • Android14URLConnectionFactory.kt (ktor-client-android/jvm/src/.../Android14URLConnectionFactory.kt:11) imports android.net.http.* and constructs HttpEngine — this will trigger class resolution for android.net.http.HttpEngine (API 34 / S‑extensions 7).
  • AndroidClientEngine.kt instantiates AndroidNetHttpEngineFactory (line ~44); AndroidURLConnectionUtils.isHttpEngineAvailable() checks Build.VERSION.SDK_INT >= 30 && SdkExtensions.getExtensionVersion(Build.VERSION_CODES.S) >= 7. Confirm the factory/class is never referenced or loaded unless that gate is true. If not safely gated, delay loading (reflection/Class.forName), move the factory into a class annotated with @RequiresExtension(extension = Build.VERSION_CODES.S, version = 7), or wrap instantiation in a guarded try/catch fallback to avoid VerifyError/NoClassDefFoundError.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 23a0d6b and a872ff0.

📒 Files selected for processing (3)
  • ktor-client/ktor-client-android/jvm/androidTest/io/ktor/client/engine/android/AndroidEngineTest.kt (1 hunks)
  • ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/Android14URLConnectionFactory.kt (1 hunks)
  • ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidEngineConfig.kt (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidEngineConfig.kt
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{kt,kts}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{kt,kts}: Follow Kotlin official style guide for all Kotlin source and build scripts
Use star imports for io.ktor.* packages
Max line length is 120 characters
Indent with 4 spaces in Kotlin code
Include a copyright header in new Kotlin files

Files:

  • ktor-client/ktor-client-android/jvm/androidTest/io/ktor/client/engine/android/AndroidEngineTest.kt
  • ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/Android14URLConnectionFactory.kt
**/*.kt

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.kt: Document all public Kotlin APIs, including parameters, return types, and exceptions
Annotate internal APIs with internalapi
Follow Kotlin error-handling conventions and use specific Ktor exceptions

Files:

  • ktor-client/ktor-client-android/jvm/androidTest/io/ktor/client/engine/android/AndroidEngineTest.kt
  • ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/Android14URLConnectionFactory.kt

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a872ff0 and 416c842.

📒 Files selected for processing (3)
  • ktor-client/ktor-client-android/jvm/androidTest/io/ktor/client/engine/android/AndroidEngineTest.kt (1 hunks)
  • ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/Android14URLConnectionFactory.kt (1 hunks)
  • ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/URLConnectionFactory.kt (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/Android14URLConnectionFactory.kt
  • ktor-client/ktor-client-android/jvm/androidTest/io/ktor/client/engine/android/AndroidEngineTest.kt
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{kt,kts}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{kt,kts}: Follow Kotlin official style guide for all Kotlin source and build scripts
Use star imports for io.ktor.* packages
Max line length is 120 characters
Indent with 4 spaces in Kotlin code
Include a copyright header in new Kotlin files

Files:

  • ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/URLConnectionFactory.kt
**/*.kt

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.kt: Document all public Kotlin APIs, including parameters, return types, and exceptions
Annotate internal APIs with internalapi
Follow Kotlin error-handling conventions and use specific Ktor exceptions

Files:

  • ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/URLConnectionFactory.kt

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/URLConnectionFactory.kt (1)

15-30: @InternalAPI annotations correctly applied.

The interface and nested class now have the required @InternalAPI annotations with the appropriate import. This addresses the previous review feedback.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 416c842 and 0f2c885.

📒 Files selected for processing (1)
  • ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/URLConnectionFactory.kt (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{kt,kts}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{kt,kts}: Follow Kotlin official style guide for all Kotlin source and build scripts
Use star imports for io.ktor.* packages
Max line length is 120 characters
Indent with 4 spaces in Kotlin code
Include a copyright header in new Kotlin files

Files:

  • ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/URLConnectionFactory.kt
**/*.kt

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.kt: Document all public Kotlin APIs, including parameters, return types, and exceptions
Annotate internal APIs with internalapi
Follow Kotlin error-handling conventions and use specific Ktor exceptions

Files:

  • ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/URLConnectionFactory.kt
🧠 Learnings (1)
📚 Learning: 2025-08-26T06:07:28.352Z
Learnt from: CR
PR: ktorio/ktor#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-26T06:07:28.352Z
Learning: Applies to **/*.kt : Annotate internal APIs with InternalAPI

Applied to files:

  • ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/URLConnectionFactory.kt

@yschimke

Copy link
Copy Markdown
Author

CodeRabbit (@coderabbitai) generate docstrings

@coderabbitai

coderabbitai Bot commented Sep 30, 2025

Copy link
Copy Markdown
Contributor
✅ Actions performed

Docstrings generation started.

coderabbitai Bot added a commit that referenced this pull request Sep 30, 2025
Docstrings generation was requested by @yschimke.

* #4013 (comment)

The following files were modified:

* `ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/Android14URLConnectionFactory.kt`
* `ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidClientEngine.kt`
* `ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidURLConnectionUtils.kt`
* `ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/URLConnectionFactory.kt`
@coderabbitai

coderabbitai Bot commented Sep 30, 2025

Copy link
Copy Markdown
Contributor

Note

Generated docstrings for this pull request at #5108

@MohammedKHC

Copy link
Copy Markdown

@Mr3zee

Alexander Sysoev (Mr3zee) commented Jul 15, 2026 •

Copy link
Copy Markdown
Member

We are looking at it, sorry for the delay
Did you figure out your issue with the instrumentation tests?

@yschimke

Copy link
Copy Markdown
Author

I'll take a look again this weekend.

@osipxd

Copy link
Copy Markdown
Member

Any opinions on instrumentation tests?

Do they fail to run with Robolectric? We don’t currently have infrastructure for running instrumented tests, but there is demand (for example in the WebRTC client), and this PR might be another good reason to spin up an emulator on CI.

@Mr3zee

Copy link
Copy Markdown
Member

Yuri Schimke (@yschimke) hey! Do you have any updates on this?

@yschimke

Copy link
Copy Markdown
Author

I took a go at a refresh and addressing Pr comments.

- Replace context/httpEngineConfig properties with useHttpEngine(context) { ... }
- Support HTTP proxy configuration on HttpEngine (SDK Extensions S 22+ / API 37+)
- Shut down HttpEngine when AndroidClientEngine closes
- Extract isHttpEngineAvailable(config) helper
- Avoid initializing android.os.Build in KtorSimpleLoggerJvm when checking for Android on classpath
- Follow-up stacked PR adds Robolectric shadow tests for AndroidNetHttpEngineFactory
@osipxd Osip Fatkullin (osipxd) changed the title [KTOR-6886] Android Http Client using Android's HttpEngine on API 34+ KTOR-6886: Android Http Client using Android's HttpEngine on API 34+ Oct 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants