Skip to content

Conversation

@osipxd
Copy link
Member

@osipxd osipxd commented Nov 18, 2025

No description provided.

bjhham and others added 8 commits November 18, 2025 17:55
* KTOR-9054 Fix application call coroutine context

* KTOR-9054 Fixup Jetty engine coroutines

* Update ktor-server/ktor-server-test-suites/jvm/src/io/ktor/server/testing/suites/SustainabilityTestSuite.kt

Co-authored-by: Osip Fatkullin <[email protected]>

* Disable tomcat coroutine hierarchy check

---------

Co-authored-by: Osip Fatkullin <[email protected]>
* Use ktor-version-catalog in ktor-test-server
* Add an HTTP/2 test server
* Add Http2Test class and implement it for all client engines
* Gradle 9.2.1
* Fix configuring the libs version catalog
* Update develocity to 4.0.3
* Update develocity-commonCustomUserData to 2.4.0
@osipxd osipxd self-assigned this Nov 18, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 18, 2025

Walkthrough

This pull request introduces comprehensive HTTP/2 testing infrastructure across Ktor's client engines, updates build configuration and dependency versions, refactors server routing to expose explicit coroutineContext parameters, and adds new test server endpoints. Multiple engine-specific HTTP/2 test classes are added alongside a shared Http2Test base class.

Changes

Cohort / File(s) Summary
Build & Gradle Configuration
build-settings-logic/build.gradle.kts, build-settings-logic/settings.gradle.kts, gradle/libs.versions.toml, gradle/wrapper/gradle-wrapper.properties, ktor-test-server/settings.gradle.kts
Gradle wrapper updated from 9.1.0 to 9.2.1, develocity plugin bumped 3.19.2→4.0.3, commonCustomUserData 2.3→2.4.0, removed test-server Ktor entries and multiple ktor-* dependencies from version catalog, added ktorLibs version catalog configuration.
HTTP/2 Test Infrastructure Foundation
ktor-client/ktor-client-tests/common/src/io/ktor/client/tests/Http2Test.kt
New abstract Http2Test base class providing HTTP/2 test harness with configurable client setup, protocol version verification, and pseudo-header assertion tests.
HTTP/2 Test Implementations - Client Engines
ktor-client/ktor-client-apache5/.../Apache5Http2Test.kt, ktor-client/ktor-client-java/.../JavaHttp2Test.kt, ktor-client/ktor-client-curl/.../CurlHttp2Test.kt, ktor-client/ktor-client-jetty-jakarta/.../JettyHttp2Test.kt
Engine-specific HTTP/2 test classes extending Http2Test with respective engine configurations. Apache5 and Java enable HTTP/2 via configuration, Curl marked @Ignore for KTOR-9100, Jetty marked @Ignore for KTOR-9094.
Darwin & OkHttp HTTP/2 Tests
ktor-client/ktor-client-darwin/.../DarwinHttp2Test.kt, ktor-client/ktor-client-okhttp/.../OkHttpHttp2Test.kt
Darwin adds HTTP/2 test with certificate validation override, OkHttp significantly refactored from server-based to client-based Http2Test pattern with duplex streaming support.
Darwin Engine Certificate Handling
ktor-client/ktor-client-darwin/.../utils/Certificates.kt, ktor-client/ktor-client-darwin/.../DarwinEngineTest.kt
Added trustAnyCertificate utility function for NSURLAuthenticationChallenge, refactored DarwinEngineTest to centralize challenge handling.
Client Engine Core Updates
ktor-client/ktor-client-java/.../JavaHttpResponseBodyHandler.kt, ktor-client/ktor-client-curl/.../CurlMultiApiHandler.kt
Java engine now filters pseudo-headers for HTTP/2 responses and tracks protocol version explicitly; Curl engine adjusted PUT/POST field size options for proper upload handling.
Client Engine Dependency Updates
ktor-client/ktor-client-curl/build.gradle.kts, ktor-client/ktor-client-tests/build.gradle.kts
Curl test dependency changed from ktorClientTestBase to ktorClientTests; test commonTest dependencies consolidated.
Client Test Utilities
ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/utils/HttpClient.kt, ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/HttpMethodTest.kt, ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/ClientHeadersTest.kt
Added engine-specific HTTP method filtering utilities; moved supportedMethods() function; added Transfer-Encoding/Content-Length test.
Logger Singleton Refactoring
ktor-client/ktor-client-plugins/ktor-client-logging/common/src/io/ktor/client/plugins/logging/Logger.kt
Logger.SIMPLE and Logger.EMPTY now return singleton objects instead of new instances.
Server Routing Coroutine Context
ktor-server/ktor-server-core/.../RoutingPipelineCall.kt, ktor-server/ktor-server-core/.../RoutingRoot.kt
RoutingPipelineCall refactored to expose explicit coroutineContext parameter in primary constructor; RoutingRoot updated to pass context.coroutineContext during construction.
Server Engine Coroutine Context Handling
ktor-server/ktor-server-jetty-jakarta/.../JettyKtorHandler.kt
Replaced per-request coroutine scope with unified handlerContext composed of dispatcher and exception handler.
Sustainability Test Validation
ktor-server/ktor-server-test-suites/.../SustainabilityTestSuite.kt
Added validateCallCoroutineContext() test method verifying call coroutine context hierarchy preservation.
Sustainability Test Overrides
ktor-server/ktor-server-cio/.../CIOEngineTestJvm.kt, ktor-server/ktor-server-jetty/.../Jetty*Test.kt, ktor-server/ktor-server-jetty-jakarta/.../Jetty*.kt, ktor-server/ktor-server-tomcat*/.../TomcatEngineTest.kt
Multiple test classes override validateCallCoroutineContext() with @Ignore annotation to skip coroutine context validation tests.
Test Server Infrastructure
ktor-test-server/src/main/kotlin/test/server/TestServer.kt, ktor-test-server/src/main/kotlin/test/server/tests/Echo.kt, ktor-test-server/build.gradle.kts
Added setupHttp2Server function, refactored lifecycle management with CloseableGroup, added /echo/headers and /echo/stream endpoints, updated dependencies to use new ktorLibs catalog.
Build Settings & Dependency Resolution
build-settings-logic/src/main/kotlin/ktorsettings.dependency-resolution-management.settings.gradle.kts
Refined local vs. parent version catalog precedence logic for gradle/libs.versions.toml.
Copyright & Formatting Updates
ktor-client/ktor-client-apache5/.../Apache5HttpClientTest.kt, ktor-client/ktor-client-java/.../JavaClientTest.kt, ktor-server/ktor-server-netty/.../NettyHttp2Handler.kt
Copyright year updated 2014-2022/2021 → 2014-2025; NettyHttp2Handler imports refactored and AttributeKey initialization updated.
Curl & Proxy Test Updates
ktor-client/ktor-client-curl/.../CurlProxyTest.kt
Content-Type header assertion updated for spacing/casing normalization.
File Cache Storage
ktor-client/ktor-client-core/.../FileCacheStorage.kt
Refined writeCacheUnsafe to manage channel writes within coroutineScope with CancellationException handling and improved resource lifecycle in finally block.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45–75 minutes

Areas requiring extra attention:

  • Http2Test base class abstraction: Verify the design supports all engine variations and test hooks are appropriate for receiver-style configuration
  • Coroutine context propagation chain: RoutingPipelineCall → RoutingRoot → engine-specific handlers (Jetty, etc.) must maintain consistent context flow
  • Multiple validateCallCoroutineContext overrides: Confirm @Ignore rationale is consistent across Jetty, Jetty-Jakarta, Tomcat, CIO engine test suites
  • OkHttpHttp2Test refactoring: High-impact change from server-based to client-based testing pattern; verify endpoint compatibility and duplex streaming logic
  • Engine-specific HTTP/2 configurations: Apache5, Java, Darwin, Curl implementations must correctly enable/configure H2C or HTTP/2 protocols per engine capability
  • Version catalog consolidation: Verify both local and parent version catalogs resolve correctly with new precedence logic

Possibly related PRs

Suggested labels

👍 ship!

Suggested reviewers

  • bjhham
  • zibet27
  • e5l

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description check ⚠️ Warning The pull request description is entirely missing; no content was provided to describe motivation, solution, or affected subsystems despite the template requiring these sections. Add a comprehensive description following the template: specify affected subsystems (Client/Server modules), explain the motivation for the merge (e.g., releasing new features/fixes), and summarize the key changes in the solution section.
Docstring Coverage ⚠️ Warning Docstring coverage is 4.08% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the primary objective: merging a release branch into main, which aligns with the changeset's comprehensive updates across multiple modules.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch osipxd/merge-release-into-main

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.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

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-tests/build.gradle.kts (1)

19-31: Remove duplicate dependencies in the consolidated commonTest.dependencies block.

The consolidation introduces redundant declarations: api(projects.ktorClientJson) appears on both lines 21 and 27, and api(projects.ktorClientSerialization) appears on both lines 22 and 28. These duplicates should be removed to keep the build script clean and maintainable.

Apply this diff to remove duplicates:

         commonTest.dependencies {
             api(projects.ktorClientCio)
             api(projects.ktorClientJson)
             api(projects.ktorClientSerialization)
             api(projects.ktorClientLogging)
             api(projects.ktorClientAuth)
             api(projects.ktorClientEncoding)
             api(projects.ktorClientContentNegotiation)
-            api(projects.ktorClientJson)
-            api(projects.ktorClientSerialization)
             api(projects.ktorSerializationKotlinx)
             api(projects.ktorSerializationKotlinxJson)
         }
🧹 Nitpick comments (16)
ktor-client/ktor-client-curl/desktop/test/io/ktor/client/engine/curl/test/CurlProxyTest.kt (1)

74-80: Header expectation update looks correct; consider parsing Content-Type instead of raw string.

The new "text/plain; charset=UTF-8" expectation matches typical formatting and is fine as-is. To make the test less fragile to minor formatting/casing changes, you might optionally assert on the parsed ContentType and charset instead of the raw header string, e.g. by using ContentType.parse(response.headers[HttpHeaders.ContentType]!!) (or an equivalent helper) and comparing it with ContentType.Text.Plain.withCharset(Charsets.UTF_8).

ktor-server/ktor-server-jetty-jakarta/ktor-server-jetty-test-http2-jakarta/jvm/test/io/ktor/tests/server/jetty/http2/jakarta/JettyHttp2ServletBlockingTest.kt (1)

47-49: Consider documenting and suppressing the intentionally empty override

The empty, @Ignored validateCallCoroutineContext override makes sense here to opt out of that check for this engine, but it triggers detekt’s EmptyFunctionBlock warning.

To make the intent explicit and keep static analysis clean, consider:

    @Ignore
    @Suppress("EmptyFunctionBlock")
    override fun validateCallCoroutineContext() {
        // Jetty HTTP/2 blocking servlet variant does not support this coroutine context validation yet.
    }

This preserves behavior while documenting why the test is disabled and silencing the warning in a controlled way.

ktor-client/ktor-client-darwin/darwin/test/DarwinEngineTest.kt (1)

218-227: Good reuse of centralized certificate‑trust helper in WebSocket test

Delegating the custom challenge handler to trustAnyCertificate(challenge, completionHandler) keeps the test logic clean and ensures server‑trust handling is consistent with other Darwin tests. This also makes future adjustments to trust behavior local to Certificates.kt only.

If you later add more tests with similar challenge handling, consider a tiny local helper (e.g., configureTrustAllChallenges()) that wires handleChallenge to trustAnyCertificate to reduce repetition across test files.

ktor-client/ktor-client-darwin/darwin/test/utils/Certificates.kt (1)

5-23: Centralized test helper for server‑trust handling looks correct and well‑scoped

trustAnyCertificate correctly restricts the “trust any cert” behavior to NSURLAuthenticationMethodServerTrust challenges and falls back to default handling otherwise. Keeping it internal in the test utils package is a good way to avoid accidental reuse outside tests while letting multiple Darwin tests share the logic.

If you ever need to differentiate between test servers (e.g., only trust specific hosts), you could add an optional predicate parameter (like hostPredicate) rather than inlining host checks at each call site.

ktor-client/ktor-client-darwin/darwin/test/DarwinHttp2Test.kt (1)

7-21: Darwin HTTP/2 test wiring and trust handling look sound

Extending Http2Test with DarwinClientEngineConfig and useH2c = false matches Darwin’s HTTP/2 capabilities, and delegating disableCertificateValidation() to trustAnyCertificate keeps certificate handling consistent with the rest of the Darwin tests. Marking the protocol‑version assertion as @Ignore with a clear KTOR‑9095 reference is also a good way to document the current platform limitation without breaking the suite.

The @OptIn(UnsafeNumber::class) on disableCertificateValidation may be redundant because trustAnyCertificate already opts into the experimental APIs; if the compiler doesn’t warn without it, you can safely drop the annotation here to reduce noise.

ktor-client/ktor-client-java/jvm/src/io/ktor/client/engine/java/JavaHttpResponseBodyHandler.kt (2)

45-49: Version mapping is correct; consider avoiding variable shadowing and clarifying unknown-version handling

The mapping from HttpClient.Version to HttpProtocolVersion looks correct and provides a clear failure mode for unexpected versions. Two small readability/robustness nits:

  • The when (val version = response.version()) introduces a local version that shadows the outer val version; renaming the inner one (e.g., to javaVersion) would avoid subtle confusion.
  • The else branch will throw if JDK adds a new HttpClient.Version; if a more graceful fallback is desired (e.g., treating future HTTP/2.x as HTTP/2.0), this is the place to adjust it.

50-56: HTTP/2 pseudo-header filtering looks appropriate; could be made slightly more defensive

Filtering out keys starting with ":" for HTTP/2 before constructing HeadersImpl is a good way to prevent HTTP/2 pseudo-headers from leaking into Ktor’s header model, and the let keeps the logic localized.

If you want to be extra defensive, you could consider:

  • Applying the filterKeys unconditionally (pseudo-headers shouldn't appear for HTTP/1.x either), or
  • Extracting the predicate into a small helper for reuse/testing.

Functionally this looks solid for the h2/h2c usage in the Java engine tests. Based on learnings.

Also applies to: 58-58

ktor-server/ktor-server-jetty-jakarta/jvm/test/io/ktor/tests/server/jetty/jakarta/JettyAsyncServletContainerTest.kt (1)

44-50: Consistent with broader test pattern, consider adding documentation.

The override to skip validateCallCoroutineContext() in sustainability tests follows the same pattern applied across multiple server engine test suites. The implementation is correct.

Optionally, consider adding a brief comment explaining why coroutine context validation is skipped for sustainability tests, e.g.:

 class JettyAsyncServletContainerSustainabilityTest :
     SustainabilityTestSuite<JettyApplicationEngineBase, JettyApplicationEngineBase.Configuration>(
         Servlet(async = true)
     ) {
+    // Coroutine context validation is not applicable for servlet-based sustainability tests
     @Ignore
     override fun validateCallCoroutineContext() {}
 }
ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RoutingPipelineCall.kt (1)

31-45: Consider upgrading deprecation level to ERROR for stronger migration signal.

The deprecated constructor uses DeprecationLevel.WARNING, which allows compilation with warnings. Since this is a planned breaking change in a release branch, consider whether DeprecationLevel.ERROR would better communicate the urgency of migration before the next major release.

Additionally, the deprecation message could be more specific:

@Deprecated(
    level = DeprecationLevel.WARNING, 
    message = "Use explicit coroutineContext instead.",
    replaceWith = ReplaceWith(
        "RoutingPipelineCall(engineCall, route, engineCall.coroutineContext, receivePipeline, responsePipeline, pathParameters)"
    )
)
ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http2/NettyHttp2Handler.kt (1)

13-22: Good refactor: Explicit imports improve clarity.

Replacing wildcard imports with explicit imports makes dependencies clearer and reduces the risk of naming conflicts. All imported classes are used in the implementation.

ktor-test-server/src/main/kotlin/test/server/tests/Echo.kt (1)

26-33: Consider handling multi-value headers explicitly.

The current implementation formats header values directly, but headers.entries() returns List<String> for each header. When a header has multiple values, this will produce output like "header-name: [value1, value2]" instead of a more typical format.

Consider whether you want to:

  • Join multiple values: value.joinToString(", ")
  • Take only the first value: value.first()
  • Format each value on a separate line

Example with joined values:

 route("/headers") {
     handle {
-        val headers = call.request.headers.entries().joinToString("\n") { (name, value) ->
-            "${name.lowercase()}: $value"
+        val headers = call.request.headers.entries().joinToString("\n") { (name, values) ->
+            "${name.lowercase()}: ${values.joinToString(", ")}"
         }
         call.respondText(headers)
     }
 }
ktor-test-server/src/main/kotlin/test/server/TestServer.kt (2)

30-33: CloseableGroup use(EmbeddedServer) helper: good pattern, consider registering stop callback before start()

The inline CloseableGroup.use(server: EmbeddedServer<*, *>) plus the try/catch around all scope.use(...) calls gives the test server a much cleaner and safer lifecycle: everything that started successfully is now guaranteed to be stopped if startup later fails and scope.close() is invoked.

One small refinement: today you call server.start() before registering the server.stop(...) callback with the CloseableGroup. If start() were ever to fail after partially starting, the server wouldn’t be in the group and thus wouldn’t be stopped on scope.close().

You could register the stop callback first, then start the server, so the group always “owns” the server once constructed:

fun CloseableGroup.use(server: EmbeddedServer<*, *>) {
    use { server.stop(gracePeriodMillis = 0, timeoutMillis = 0) }
    server.start()
}

This is a minor robustness tweak; the current implementation is acceptable for tests if you prefer to keep it as is.

Also applies to: 35-48


53-56: TLS server setup: parameterization looks good; consider temp keystore file cleanup

Parameterizing setupTLSServer with port and module: suspend Application.() -> Unit is a nice improvement — it keeps the TLS server wiring consistent with the other servers, and the Jetty sslConnector configuration looks standard for a generated test keystore.

One thing to consider: File.createTempFile("server", "certificate") will leave temp files behind for every test process run. In long-running or repeatedly executed test environments this can accumulate.

If feasible, you might:

  • Mark the file for deletion on JVM exit:
val file = File.createTempFile("server", "certificate").apply { deleteOnExit() }
  • Or, if CloseableGroup is the central lifecycle, add a Closeable that deletes this file when the group is closed.

Not critical for test infrastructure, but it tightens resource hygiene.

Please double‑check Jetty’s sslConnector expectations for keyStore + keyStorePath against the Ktor version used in this repo to ensure this combination is still supported and recommended.

Also applies to: 59-73

ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/utils/HttpClient.kt (1)

10-10: Consider explicit null handling for engineName.

The simpleName property can return null for anonymous or local classes, resulting in engineName being nullable. While the when expression on line 14 will fall through to the else branch when engineName is null, this behavior may be unintended.

Consider making the null case explicit for clarity:

-internal val HttpClient.engineName get() = engine::class.simpleName?.removeSuffix("ClientEngine")
+internal val HttpClient.engineName: String 
+    get() = engine::class.simpleName?.removeSuffix("ClientEngine") ?: "Unknown"

Or handle it in supportedMethods():

 internal fun HttpClient.supportedMethods(): List<HttpMethod> = when (engineName) {
+    null -> allMethods
     // PATCH is not supported by HttpURLConnection
ktor-client/ktor-client-tests/common/src/io/ktor/client/tests/Http2Test.kt (1)

17-29: Clarify disableCertificateValidation default to avoid TODO at runtime

Using TODO() in disableCertificateValidation means any subclass that opts into TLS (useH2c = false) but forgets to override this will fail with a NotImplementedError at runtime. That’s a reasonable guard, but it also reads like unfinished implementation.

Consider replacing TODO() with an explicit failure such as:

protected open fun T.disableCertificateValidation() {
    error("disableCertificateValidation() must be overridden when useH2c is false in ${this@Http2Test::class.simpleName}")
}

or making this function abstract and only calling it when useH2c == false. This preserves the fail-fast behaviour but makes the intent clearer and avoids leaving a TODO in shared test infrastructure.

ktor-client/ktor-client-okhttp/jvm/test/io/ktor/client/engine/okhttp/OkHttpHttp2Test.kt (1)

25-57: Explicitly close the request channel in testDuplexStreaming

The duplex streaming test exercises true bidirectional HTTP/2 behaviour with OkHttp well. Add an explicit close to inputChannel after writing the last message so the server and engine see a clean end-of-stream:

(0..2).forEach {
    inputChannel.writeStringUtf8("client: $it\n")
    inputChannel.flush()
    acc += outputChannel.readUTF8Line()
    acc += "\n"
}
inputChannel.close()

ByteChannel's close() method flushes pending writes and is the intended way to finish a channel, and Ktor's HTTP/2 support expects streams to be closed to mark end of the request body. This tightens the lifecycle and aligns with recommended patterns for streaming bodies in duplex tests.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 81438ba and c68f4ee.

⛔ Files ignored due to path filters (1)
  • gradle/wrapper/gradle-wrapper.jar is excluded by !**/*.jar
📒 Files selected for processing (49)
  • build-settings-logic/build.gradle.kts (1 hunks)
  • build-settings-logic/settings.gradle.kts (1 hunks)
  • build-settings-logic/src/main/kotlin/ktorsettings.dependency-resolution-management.settings.gradle.kts (1 hunks)
  • gradle/libs.versions.toml (1 hunks)
  • gradle/wrapper/gradle-wrapper.properties (1 hunks)
  • ktor-client/ktor-client-apache5/jvm/test/io/ktor/client/engine/apache5/Apache5Http2Test.kt (1 hunks)
  • ktor-client/ktor-client-apache5/jvm/test/io/ktor/client/engine/apache5/Apache5HttpClientTest.kt (1 hunks)
  • ktor-client/ktor-client-core/jvm/src/io/ktor/client/plugins/cache/storage/FileCacheStorage.kt (2 hunks)
  • ktor-client/ktor-client-curl/build.gradle.kts (1 hunks)
  • ktor-client/ktor-client-curl/desktop/src/io/ktor/client/engine/curl/internal/CurlMultiApiHandler.kt (1 hunks)
  • ktor-client/ktor-client-curl/desktop/test/io/ktor/client/engine/curl/test/CurlHttp2Test.kt (1 hunks)
  • ktor-client/ktor-client-curl/desktop/test/io/ktor/client/engine/curl/test/CurlProxyTest.kt (1 hunks)
  • ktor-client/ktor-client-darwin/darwin/test/DarwinEngineTest.kt (3 hunks)
  • ktor-client/ktor-client-darwin/darwin/test/DarwinHttp2Test.kt (1 hunks)
  • ktor-client/ktor-client-darwin/darwin/test/utils/Certificates.kt (1 hunks)
  • ktor-client/ktor-client-java/jvm/src/io/ktor/client/engine/java/JavaHttpResponseBodyHandler.kt (2 hunks)
  • ktor-client/ktor-client-java/jvm/test/io/ktor/client/engine/java/JavaClientTest.kt (1 hunks)
  • ktor-client/ktor-client-java/jvm/test/io/ktor/client/engine/java/JavaHttp2Test.kt (1 hunks)
  • ktor-client/ktor-client-jetty-jakarta/build.gradle.kts (1 hunks)
  • ktor-client/ktor-client-jetty-jakarta/jvm/test/io/ktor/client/engine/jetty/jakarta/JettyHttp2Test.kt (1 hunks)
  • ktor-client/ktor-client-okhttp/jvm/test/io/ktor/client/engine/okhttp/OkHttpHttp2Test.kt (4 hunks)
  • ktor-client/ktor-client-plugins/ktor-client-logging/common/src/io/ktor/client/plugins/logging/Logger.kt (2 hunks)
  • ktor-client/ktor-client-tests/build.gradle.kts (2 hunks)
  • ktor-client/ktor-client-tests/common/src/io/ktor/client/tests/Http2Test.kt (1 hunks)
  • ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/ClientHeadersTest.kt (2 hunks)
  • ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/HttpMethodTest.kt (1 hunks)
  • ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/utils/HttpClient.kt (1 hunks)
  • ktor-server/ktor-server-cio/jvm/test/io/ktor/tests/server/cio/CIOEngineTestJvm.kt (1 hunks)
  • ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RoutingPipelineCall.kt (1 hunks)
  • ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RoutingRoot.kt (1 hunks)
  • ktor-server/ktor-server-jetty-jakarta/jvm/src/io/ktor/server/jetty/jakarta/JettyKtorHandler.kt (3 hunks)
  • ktor-server/ktor-server-jetty-jakarta/jvm/test/io/ktor/tests/server/jetty/jakarta/JettyAsyncServletContainerTest.kt (1 hunks)
  • ktor-server/ktor-server-jetty-jakarta/jvm/test/io/ktor/tests/server/jetty/jakarta/JettyBlockingServletContainerTest.kt (1 hunks)
  • ktor-server/ktor-server-jetty-jakarta/ktor-server-jetty-test-http2-jakarta/jvm/test/io/ktor/tests/server/jetty/http2/jakarta/JettyHttp2ServletAsyncTest.kt (1 hunks)
  • ktor-server/ktor-server-jetty-jakarta/ktor-server-jetty-test-http2-jakarta/jvm/test/io/ktor/tests/server/jetty/http2/jakarta/JettyHttp2ServletBlockingTest.kt (1 hunks)
  • ktor-server/ktor-server-jetty/jvm/test/io/ktor/tests/server/jetty/JettyAsyncServletContainerTest.kt (1 hunks)
  • ktor-server/ktor-server-jetty/jvm/test/io/ktor/tests/server/jetty/JettyBlockingServletContainerTest.kt (1 hunks)
  • ktor-server/ktor-server-jetty/jvm/test/io/ktor/tests/server/jetty/JettyEngineTest.kt (1 hunks)
  • ktor-server/ktor-server-jetty/ktor-server-jetty-test-http2/jvm/test/io/ktor/tests/server/jetty/http2/JettyEngineTest.kt (1 hunks)
  • ktor-server/ktor-server-jetty/ktor-server-jetty-test-http2/jvm/test/io/ktor/tests/server/jetty/http2/JettyHttp2ServletAsyncTest.kt (1 hunks)
  • ktor-server/ktor-server-jetty/ktor-server-jetty-test-http2/jvm/test/io/ktor/tests/server/jetty/http2/JettyHttp2ServletBlockingTest.kt (1 hunks)
  • ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http2/NettyHttp2Handler.kt (3 hunks)
  • ktor-server/ktor-server-test-suites/jvm/src/io/ktor/server/testing/suites/SustainabilityTestSuite.kt (1 hunks)
  • ktor-server/ktor-server-tomcat-jakarta/jvm/test/io/ktor/tests/server/tomcat/jakarta/TomcatEngineTest.kt (1 hunks)
  • ktor-server/ktor-server-tomcat/jvm/test/io/ktor/tests/server/tomcat/TomcatEngineTest.kt (1 hunks)
  • ktor-test-server/build.gradle.kts (1 hunks)
  • ktor-test-server/settings.gradle.kts (2 hunks)
  • ktor-test-server/src/main/kotlin/test/server/TestServer.kt (1 hunks)
  • ktor-test-server/src/main/kotlin/test/server/tests/Echo.kt (2 hunks)
🧰 Additional context used
🧠 Learnings (25)
📓 Common learnings
Learnt from: osipxd
Repo: ktorio/ktor PR: 5195
File: ktor-client/ktor-client-java/jvm/test/io/ktor/client/engine/java/JavaHttp2Test.kt:13-15
Timestamp: 2025-11-14T14:11:30.292Z
Learning: In ktor-client-java tests, Java's HttpClient does support h2c (HTTP/2 cleartext) when configured with `protocolVersion = HttpClient.Version.HTTP_2` on Java 11+. The JavaHttp2Test successfully passes with the default useH2c=true setting, connecting to http://localhost:8084.
📚 Learning: 2025-05-30T06:45:52.309Z
Learnt from: rururux
Repo: ktorio/ktor PR: 4896
File: ktor-client/ktor-client-core/jvm/test/FileStorageTest.kt:1-12
Timestamp: 2025-05-30T06:45:52.309Z
Learning: In Ktor test files, particularly in the ktor-client/ktor-client-core/jvm/test/ directory, test files follow the convention of not including explicit package declarations. This is consistent across test files like CachingCacheStorageTest.kt and should be maintained for consistency.

Applied to files:

  • ktor-client/ktor-client-apache5/jvm/test/io/ktor/client/engine/apache5/Apache5HttpClientTest.kt
  • ktor-client/ktor-client-java/jvm/test/io/ktor/client/engine/java/JavaClientTest.kt
  • ktor-server/ktor-server-tomcat-jakarta/jvm/test/io/ktor/tests/server/tomcat/jakarta/TomcatEngineTest.kt
  • ktor-server/ktor-server-test-suites/jvm/src/io/ktor/server/testing/suites/SustainabilityTestSuite.kt
  • ktor-server/ktor-server-cio/jvm/test/io/ktor/tests/server/cio/CIOEngineTestJvm.kt
  • ktor-server/ktor-server-jetty-jakarta/jvm/test/io/ktor/tests/server/jetty/jakarta/JettyAsyncServletContainerTest.kt
  • ktor-client/ktor-client-core/jvm/src/io/ktor/client/plugins/cache/storage/FileCacheStorage.kt
  • ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/ClientHeadersTest.kt
  • ktor-server/ktor-server-jetty/ktor-server-jetty-test-http2/jvm/test/io/ktor/tests/server/jetty/http2/JettyHttp2ServletAsyncTest.kt
  • ktor-client/ktor-client-curl/build.gradle.kts
  • ktor-server/ktor-server-tomcat/jvm/test/io/ktor/tests/server/tomcat/TomcatEngineTest.kt
  • ktor-client/ktor-client-curl/desktop/test/io/ktor/client/engine/curl/test/CurlHttp2Test.kt
  • ktor-client/ktor-client-tests/common/src/io/ktor/client/tests/Http2Test.kt
  • ktor-server/ktor-server-jetty/ktor-server-jetty-test-http2/jvm/test/io/ktor/tests/server/jetty/http2/JettyEngineTest.kt
  • ktor-client/ktor-client-okhttp/jvm/test/io/ktor/client/engine/okhttp/OkHttpHttp2Test.kt
  • ktor-client/ktor-client-jetty-jakarta/jvm/test/io/ktor/client/engine/jetty/jakarta/JettyHttp2Test.kt
  • ktor-client/ktor-client-darwin/darwin/test/DarwinEngineTest.kt
  • ktor-client/ktor-client-java/jvm/test/io/ktor/client/engine/java/JavaHttp2Test.kt
  • ktor-server/ktor-server-jetty-jakarta/jvm/test/io/ktor/tests/server/jetty/jakarta/JettyBlockingServletContainerTest.kt
  • ktor-client/ktor-client-curl/desktop/test/io/ktor/client/engine/curl/test/CurlProxyTest.kt
  • ktor-server/ktor-server-jetty/jvm/test/io/ktor/tests/server/jetty/JettyAsyncServletContainerTest.kt
  • ktor-server/ktor-server-jetty/ktor-server-jetty-test-http2/jvm/test/io/ktor/tests/server/jetty/http2/JettyHttp2ServletBlockingTest.kt
  • ktor-server/ktor-server-jetty/jvm/test/io/ktor/tests/server/jetty/JettyEngineTest.kt
  • ktor-client/ktor-client-tests/build.gradle.kts
  • ktor-server/ktor-server-jetty-jakarta/ktor-server-jetty-test-http2-jakarta/jvm/test/io/ktor/tests/server/jetty/http2/jakarta/JettyHttp2ServletAsyncTest.kt
  • ktor-test-server/build.gradle.kts
  • gradle/libs.versions.toml
  • ktor-server/ktor-server-jetty/jvm/test/io/ktor/tests/server/jetty/JettyBlockingServletContainerTest.kt
  • ktor-server/ktor-server-jetty-jakarta/ktor-server-jetty-test-http2-jakarta/jvm/test/io/ktor/tests/server/jetty/http2/jakarta/JettyHttp2ServletBlockingTest.kt
  • ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/HttpMethodTest.kt
📚 Learning: 2025-09-30T07:52:14.769Z
Learnt from: yschimke
Repo: ktorio/ktor PR: 4013
File: ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/Android14URLConnectionFactory.kt:24-26
Timestamp: 2025-09-30T07:52:14.769Z
Learning: In the Ktor Android HTTP client engine (ktor-client-android), prefer using `URI.create(urlString).toURL()` over the `URL(urlString)` constructor when opening connections with Android's HttpEngine, as it avoids deprecated APIs and the different exception behavior (IllegalArgumentException vs MalformedURLException) is acceptable.

Applied to files:

  • ktor-client/ktor-client-apache5/jvm/test/io/ktor/client/engine/apache5/Apache5HttpClientTest.kt
  • ktor-client/ktor-client-java/jvm/test/io/ktor/client/engine/java/JavaClientTest.kt
  • ktor-client/ktor-client-okhttp/jvm/test/io/ktor/client/engine/okhttp/OkHttpHttp2Test.kt
📚 Learning: 2025-06-23T12:49:56.883Z
Learnt from: CR
Repo: ktorio/ktor PR: 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-apache5/jvm/test/io/ktor/client/engine/apache5/Apache5HttpClientTest.kt
  • ktor-client/ktor-client-java/jvm/test/io/ktor/client/engine/java/JavaClientTest.kt
  • ktor-client/ktor-client-okhttp/jvm/test/io/ktor/client/engine/okhttp/OkHttpHttp2Test.kt
  • ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http2/NettyHttp2Handler.kt
  • ktor-test-server/src/main/kotlin/test/server/tests/Echo.kt
  • ktor-server/ktor-server-jetty-jakarta/jvm/src/io/ktor/server/jetty/jakarta/JettyKtorHandler.kt
  • ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/HttpMethodTest.kt
📚 Learning: 2025-11-14T14:11:30.292Z
Learnt from: osipxd
Repo: ktorio/ktor PR: 5195
File: ktor-client/ktor-client-java/jvm/test/io/ktor/client/engine/java/JavaHttp2Test.kt:13-15
Timestamp: 2025-11-14T14:11:30.292Z
Learning: In ktor-client-java tests, Java's HttpClient does support h2c (HTTP/2 cleartext) when configured with `protocolVersion = HttpClient.Version.HTTP_2` on Java 11+. The JavaHttp2Test successfully passes with the default useH2c=true setting, connecting to http://localhost:8084.

Applied to files:

  • ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/utils/HttpClient.kt
  • ktor-client/ktor-client-java/jvm/test/io/ktor/client/engine/java/JavaClientTest.kt
  • ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/ClientHeadersTest.kt
  • ktor-client/ktor-client-apache5/jvm/test/io/ktor/client/engine/apache5/Apache5Http2Test.kt
  • ktor-client/ktor-client-curl/desktop/test/io/ktor/client/engine/curl/test/CurlHttp2Test.kt
  • ktor-client/ktor-client-tests/common/src/io/ktor/client/tests/Http2Test.kt
  • ktor-client/ktor-client-okhttp/jvm/test/io/ktor/client/engine/okhttp/OkHttpHttp2Test.kt
  • ktor-client/ktor-client-jetty-jakarta/jvm/test/io/ktor/client/engine/jetty/jakarta/JettyHttp2Test.kt
  • ktor-client/ktor-client-java/jvm/test/io/ktor/client/engine/java/JavaHttp2Test.kt
  • ktor-client/ktor-client-curl/desktop/test/io/ktor/client/engine/curl/test/CurlProxyTest.kt
  • ktor-client/ktor-client-darwin/darwin/test/DarwinHttp2Test.kt
  • ktor-client/ktor-client-java/jvm/src/io/ktor/client/engine/java/JavaHttpResponseBodyHandler.kt
  • ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/HttpMethodTest.kt
📚 Learning: 2025-05-14T18:05:02.321Z
Learnt from: bjhham
Repo: ktorio/ktor PR: 4855
File: ktor-server/ktor-server-plugins/ktor-server-di/api/ktor-server-di.klib.api:334-336
Timestamp: 2025-05-14T18:05:02.321Z
Learning: Breaking changes in constructor parameter order are acceptable for the ktor-server-di module when the code hasn't been released yet, as confirmed by the development team.

Applied to files:

  • ktor-client/ktor-client-java/jvm/test/io/ktor/client/engine/java/JavaClientTest.kt
  • ktor-client/ktor-client-jetty-jakarta/build.gradle.kts
  • ktor-server/ktor-server-jetty/ktor-server-jetty-test-http2/jvm/test/io/ktor/tests/server/jetty/http2/JettyHttp2ServletAsyncTest.kt
  • ktor-client/ktor-client-curl/build.gradle.kts
  • ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RoutingRoot.kt
  • ktor-server/ktor-server-jetty/ktor-server-jetty-test-http2/jvm/test/io/ktor/tests/server/jetty/http2/JettyEngineTest.kt
  • ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RoutingPipelineCall.kt
  • ktor-client/ktor-client-okhttp/jvm/test/io/ktor/client/engine/okhttp/OkHttpHttp2Test.kt
  • ktor-server/ktor-server-jetty-jakarta/jvm/test/io/ktor/tests/server/jetty/jakarta/JettyBlockingServletContainerTest.kt
  • ktor-server/ktor-server-jetty/jvm/test/io/ktor/tests/server/jetty/JettyAsyncServletContainerTest.kt
  • ktor-test-server/src/main/kotlin/test/server/tests/Echo.kt
  • ktor-client/ktor-client-tests/build.gradle.kts
  • ktor-test-server/settings.gradle.kts
  • ktor-server/ktor-server-jetty-jakarta/ktor-server-jetty-test-http2-jakarta/jvm/test/io/ktor/tests/server/jetty/http2/jakarta/JettyHttp2ServletAsyncTest.kt
  • ktor-test-server/build.gradle.kts
  • gradle/libs.versions.toml
  • ktor-test-server/src/main/kotlin/test/server/TestServer.kt
📚 Learning: 2025-06-09T07:08:35.085Z
Learnt from: bjhham
Repo: ktorio/ktor PR: 4916
File: ktor-server/ktor-server-core/api/ktor-server-core.api:151-151
Timestamp: 2025-06-09T07:08:35.085Z
Learning: Breaking changes are acceptable in Ktor codebase when the code hasn't been released yet, as confirmed by bjhham from the development team.

Applied to files:

  • ktor-client/ktor-client-java/jvm/test/io/ktor/client/engine/java/JavaClientTest.kt
  • ktor-client/ktor-client-curl/build.gradle.kts
  • ktor-client/ktor-client-okhttp/jvm/test/io/ktor/client/engine/okhttp/OkHttpHttp2Test.kt
  • ktor-client/ktor-client-tests/build.gradle.kts
  • ktor-test-server/build.gradle.kts
  • gradle/libs.versions.toml
📚 Learning: 2025-09-05T12:47:49.016Z
Learnt from: bjhham
Repo: ktorio/ktor PR: 4887
File: ktor-server/ktor-server-jetty-jakarta/jvm/src/io/ktor/server/jetty/jakarta/JettyWebsocketConnection.kt:35-52
Timestamp: 2025-09-05T12:47:49.016Z
Learning: JettyWebsocketConnection in ktor-server-jetty-jakarta implements Closeable interface (has close() method), so connection.use { } is valid Kotlin syntax and will compile correctly.

Applied to files:

  • ktor-client/ktor-client-java/jvm/test/io/ktor/client/engine/java/JavaClientTest.kt
  • ktor-client/ktor-client-jetty-jakarta/jvm/test/io/ktor/client/engine/jetty/jakarta/JettyHttp2Test.kt
  • ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http2/NettyHttp2Handler.kt
  • ktor-server/ktor-server-jetty/jvm/test/io/ktor/tests/server/jetty/JettyBlockingServletContainerTest.kt
  • ktor-server/ktor-server-jetty-jakarta/jvm/src/io/ktor/server/jetty/jakarta/JettyKtorHandler.kt
📚 Learning: 2025-06-16T17:03:45.729Z
Learnt from: tre3p
Repo: ktorio/ktor PR: 4936
File: ktor-utils/jvm/src/io/ktor/util/ZstdEncoding.kt:28-35
Timestamp: 2025-06-16T17:03:45.729Z
Learning: In the Ktor codebase, encoder implementations consistently use GlobalScope.writer and GlobalScope.reader patterns for compression/decompression operations. This is the established architectural pattern used throughout the codebase for byte channel transformations.

Applied to files:

  • ktor-client/ktor-client-java/jvm/test/io/ktor/client/engine/java/JavaClientTest.kt
  • ktor-client/ktor-client-okhttp/jvm/test/io/ktor/client/engine/okhttp/OkHttpHttp2Test.kt
  • ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http2/NettyHttp2Handler.kt
📚 Learning: 2025-09-05T12:47:49.016Z
Learnt from: bjhham
Repo: ktorio/ktor PR: 4887
File: ktor-server/ktor-server-jetty-jakarta/jvm/src/io/ktor/server/jetty/jakarta/JettyWebsocketConnection.kt:35-52
Timestamp: 2025-09-05T12:47:49.016Z
Learning: Jetty's AbstractConnection class implements Closeable interface, so any class extending AbstractConnection (like JettyWebsocketConnection) can be used with Kotlin's use { } extension function for resource management.

Applied to files:

  • ktor-client/ktor-client-java/jvm/test/io/ktor/client/engine/java/JavaClientTest.kt
  • ktor-server/ktor-server-jetty-jakarta/jvm/src/io/ktor/server/jetty/jakarta/JettyKtorHandler.kt
📚 Learning: 2025-05-16T13:11:28.416Z
Learnt from: osipxd
Repo: ktorio/ktor PR: 4860
File: ktor-server/ktor-server-plugins/ktor-server-di/api/ktor-server-di.api:24-26
Timestamp: 2025-05-16T13:11:28.416Z
Learning: Binary incompatible changes (such as constructor signature changes) are acceptable in the ktor-server-di module when the version is not yet released, as confirmed by the development team.

Applied to files:

  • ktor-client/ktor-client-jetty-jakarta/build.gradle.kts
  • ktor-client/ktor-client-curl/build.gradle.kts
  • ktor-client/ktor-client-okhttp/jvm/test/io/ktor/client/engine/okhttp/OkHttpHttp2Test.kt
  • ktor-client/ktor-client-tests/build.gradle.kts
  • ktor-test-server/settings.gradle.kts
  • ktor-test-server/build.gradle.kts
  • gradle/libs.versions.toml
  • ktor-test-server/src/main/kotlin/test/server/TestServer.kt
📚 Learning: 2025-08-14T15:17:11.466Z
Learnt from: zibet27
Repo: ktorio/ktor PR: 5044
File: ktor-client/ktor-client-webrtc/ktor-client-webrtc-rs/build.gradle.kts:12-12
Timestamp: 2025-08-14T15:17:11.466Z
Learning: The Cargo plugin (dev.gobley.cargo) used in the Ktor WebRTC RS module depends on the kotlin("plugin.atomicfu") plugin, so atomicfu should not be removed even if there are no direct kotlinx.atomicfu imports in the module's source code.

Applied to files:

  • ktor-client/ktor-client-jetty-jakarta/build.gradle.kts
  • ktor-client/ktor-client-curl/build.gradle.kts
  • build-settings-logic/settings.gradle.kts
  • ktor-client/ktor-client-tests/build.gradle.kts
  • ktor-test-server/settings.gradle.kts
  • ktor-test-server/build.gradle.kts
  • gradle/libs.versions.toml
📚 Learning: 2025-08-14T15:17:11.466Z
Learnt from: zibet27
Repo: ktorio/ktor PR: 5044
File: ktor-client/ktor-client-webrtc/ktor-client-webrtc-rs/build.gradle.kts:12-12
Timestamp: 2025-08-14T15:17:11.466Z
Learning: The Gobley Cargo plugin (dev.gobley.cargo) used in the Ktor WebRTC RS module requires the kotlin("plugin.atomicfu") plugin as a dependency, so the atomicfu plugin should not be removed even if there are no direct kotlinx.atomicfu imports in the module's source code.

Applied to files:

  • ktor-client/ktor-client-jetty-jakarta/build.gradle.kts
  • build-settings-logic/settings.gradle.kts
  • ktor-client/ktor-client-tests/build.gradle.kts
  • ktor-test-server/build.gradle.kts
  • gradle/libs.versions.toml
📚 Learning: 2025-05-08T09:52:11.723Z
Learnt from: osipxd
Repo: ktorio/ktor PR: 4836
File: build-logic/src/main/kotlin/ktorbuild.project.server-plugin.gradle.kts:12-12
Timestamp: 2025-05-08T09:52:11.723Z
Learning: In the Ktor project's flattened Gradle structure, projects are declared using a custom DSL with the unary plus operator inside specialized blocks. For example, server projects are declared with `+"project-name"` inside a `server {}` block within the main `projects {}` block. When verifying project declarations, search for `+"project-name"` rather than traditional `include(":project-name")` statements.

Applied to files:

  • ktor-client/ktor-client-jetty-jakarta/build.gradle.kts
  • ktor-test-server/settings.gradle.kts
📚 Learning: 2025-05-07T13:42:29.388Z
Learnt from: osipxd
Repo: ktorio/ktor PR: 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-jetty-jakarta/build.gradle.kts
  • ktor-client/ktor-client-curl/build.gradle.kts
  • build-settings-logic/settings.gradle.kts
  • build-settings-logic/src/main/kotlin/ktorsettings.dependency-resolution-management.settings.gradle.kts
  • ktor-client/ktor-client-tests/build.gradle.kts
  • ktor-test-server/settings.gradle.kts
  • ktor-test-server/build.gradle.kts
  • gradle/libs.versions.toml
📚 Learning: 2025-05-07T09:12:14.293Z
Learnt from: osipxd
Repo: ktorio/ktor PR: 4836
File: ktor-utils/build.gradle.kts:35-35
Timestamp: 2025-05-07T09:12:14.293Z
Learning: The Ktor project maintains a flat Gradle project structure (where projects are referenced without nested paths like `:ktor-test-base`) while keeping a hierarchical directory organization on disk.

Applied to files:

  • ktor-client/ktor-client-jetty-jakarta/build.gradle.kts
  • ktor-client/ktor-client-curl/build.gradle.kts
  • ktor-client/ktor-client-tests/build.gradle.kts
  • ktor-test-server/settings.gradle.kts
  • ktor-test-server/build.gradle.kts
  • gradle/libs.versions.toml
📚 Learning: 2025-08-14T15:17:11.466Z
Learnt from: zibet27
Repo: ktorio/ktor PR: 5044
File: ktor-client/ktor-client-webrtc/ktor-client-webrtc-rs/build.gradle.kts:12-12
Timestamp: 2025-08-14T15:17:11.466Z
Learning: The Gobley Gradle plugin (dev.gobley.cargo and dev.gobley.uniffi) requires the kotlin("plugin.atomicfu") plugin for atomic types support in Rust-Kotlin bindings generated by UniFFI. The atomicfu plugin should not be removed even if there are no direct kotlinx.atomicfu imports in the Kotlin source code, as it's essential for proper Rust-Kotlin interoperability.

Applied to files:

  • ktor-client/ktor-client-jetty-jakarta/build.gradle.kts
  • build-settings-logic/settings.gradle.kts
  • ktor-test-server/settings.gradle.kts
  • gradle/libs.versions.toml
📚 Learning: 2025-05-14T18:17:03.059Z
Learnt from: bjhham
Repo: ktorio/ktor PR: 4855
File: ktor-server/ktor-server-plugins/ktor-server-di/common/src/io/ktor/server/plugins/di/DependencyRegistry.kt:37-38
Timestamp: 2025-05-14T18:17:03.059Z
Learning: When implementing CoroutineScope in Ktor components like DependencyRegistry, always ensure the scope is properly cancelled during application shutdown to prevent memory leaks and resource issues. In the DI plugin, this is handled by calling registry.cancel() in the ApplicationStopped event handler after all dependency cleanup is complete.

Applied to files:

  • ktor-server/ktor-server-test-suites/jvm/src/io/ktor/server/testing/suites/SustainabilityTestSuite.kt
  • ktor-server/ktor-server-jetty-jakarta/jvm/src/io/ktor/server/jetty/jakarta/JettyKtorHandler.kt
📚 Learning: 2025-05-14T18:17:03.059Z
Learnt from: bjhham
Repo: ktorio/ktor PR: 4855
File: ktor-server/ktor-server-plugins/ktor-server-di/common/src/io/ktor/server/plugins/di/DependencyRegistry.kt:37-38
Timestamp: 2025-05-14T18:17:03.059Z
Learning: In the Ktor DI plugin, when a DependencyRegistry implements CoroutineScope, it should be properly cancelled during application shutdown to prevent memory leaks and resource issues. This is handled by calling registry.cancel() in the ApplicationStopped event.

Applied to files:

  • ktor-server/ktor-server-test-suites/jvm/src/io/ktor/server/testing/suites/SustainabilityTestSuite.kt
  • ktor-server/ktor-server-jetty-jakarta/jvm/src/io/ktor/server/jetty/jakarta/JettyKtorHandler.kt
📚 Learning: 2025-07-01T10:54:53.751Z
Learnt from: osipxd
Repo: ktorio/ktor PR: 4970
File: build-logic/src/main/kotlin/ktorbuild.kmp.gradle.kts:67-72
Timestamp: 2025-07-01T10:54:53.751Z
Learning: In build-logic/src/main/kotlin/ktorbuild.kmp.gradle.kts, the KT-70915 and KT-77609 workarounds that limit parallelism for KotlinNativeLink and CInteropCommonizerTask should remain unconditional (not gated behind CI flag) as these limits are beneficial for both local and CI builds.

Applied to files:

  • ktor-server/ktor-server-cio/jvm/test/io/ktor/tests/server/cio/CIOEngineTestJvm.kt
  • ktor-client/ktor-client-curl/build.gradle.kts
  • build-settings-logic/src/main/kotlin/ktorsettings.dependency-resolution-management.settings.gradle.kts
  • ktor-client/ktor-client-tests/build.gradle.kts
  • gradle/libs.versions.toml
📚 Learning: 2025-05-30T06:45:52.309Z
Learnt from: rururux
Repo: ktorio/ktor PR: 4896
File: ktor-client/ktor-client-core/jvm/test/FileStorageTest.kt:1-12
Timestamp: 2025-05-30T06:45:52.309Z
Learning: The headersOf() function from io.ktor.http package is available through wildcard imports like `import io.ktor.http.*`, so no explicit import statement is needed when using wildcard imports from that package.

Applied to files:

  • ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/ClientHeadersTest.kt
  • ktor-client/ktor-client-okhttp/jvm/test/io/ktor/client/engine/okhttp/OkHttpHttp2Test.kt
  • ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http2/NettyHttp2Handler.kt
  • ktor-test-server/build.gradle.kts
📚 Learning: 2025-05-30T17:54:31.724Z
Learnt from: osipxd
Repo: ktorio/ktor PR: 4896
File: ktor-client/ktor-client-core/jvm/src/io/ktor/client/plugins/cache/storage/FileCacheStorage.kt:167-167
Timestamp: 2025-05-30T17:54:31.724Z
Learning: In Ktor codebase, prefer using `Logger.trace { "message" }` and `Logger.debug { "message" }` with lazy message evaluation instead of `Logger.trace("message")` and `Logger.debug("message")` to avoid unnecessary string interpolation and allocations when logging is disabled. This is especially important when the log message includes expensive operations like `stackTraceToString()`.

Applied to files:

  • ktor-client/ktor-client-plugins/ktor-client-logging/common/src/io/ktor/client/plugins/logging/Logger.kt
📚 Learning: 2025-05-21T11:36:39.111Z
Learnt from: osipxd
Repo: ktorio/ktor PR: 4875
File: ktor-version-catalog/build.gradle.kts:52-79
Timestamp: 2025-05-21T11:36:39.111Z
Learning: In the Ktor project's version catalog, library alias naming has different patterns: some aliases should maintain hierarchical structure (e.g., "server-metrics-micrometer" should preserve the "server-metrics-" prefix since "server-metrics" exists as a separate module), while others should convert hyphens to camelCase (e.g., "server-caching-headers" → "server-cachingHeaders").

Applied to files:

  • ktor-test-server/settings.gradle.kts
  • ktor-test-server/build.gradle.kts
  • gradle/libs.versions.toml
📚 Learning: 2025-04-23T11:48:32.634Z
Learnt from: osipxd
Repo: ktorio/ktor PR: 4767
File: build-settings-logic/src/main/kotlin/ktorsettings.kotlin-user-project.settings.gradle.kts:136-146
Timestamp: 2025-04-23T11:48:32.634Z
Learning: For Kotlin Train builds in the Ktor project, the properties `atomicfu_version`, `coroutines_version`, and `serialization_version` are expected to be defined in the TeamCity CI environment, so using `.get()` without custom error handling is sufficient.

Applied to files:

  • ktor-test-server/settings.gradle.kts
  • gradle/libs.versions.toml
📚 Learning: 2025-06-18T12:04:14.597Z
Learnt from: osipxd
Repo: ktorio/ktor PR: 4942
File: build-logic/src/main/kotlin/ktorbuild/internal/publish/PublishTasks.kt:69-74
Timestamp: 2025-06-18T12:04:14.597Z
Learning: In build-logic/src/main/kotlin/ktorbuild/internal/publish/PublishTasks.kt, the team intentionally uses singleOrNull for repository name selection to enforce explicit failure when more than one non-default repository is configured. This is preferred over firstOrNull to avoid ambiguity and ensure that multiple repository scenarios are handled explicitly when they arise, rather than relying on implicit ordering.

Applied to files:

  • ktor-test-server/settings.gradle.kts
🧬 Code graph analysis (11)
ktor-server/ktor-server-test-suites/jvm/src/io/ktor/server/testing/suites/SustainabilityTestSuite.kt (2)
ktor-server/ktor-server-test-base/jvm/src/io/ktor/server/test/base/EngineTestBaseJvm.kt (3)
  • createAndStartServer (166-198)
  • withUrl (247-261)
  • withUrl (273-285)
ktor-server/ktor-server-test-base/posix/src/io/ktor/server/test/base/EngineTestBaseNix.kt (3)
  • createAndStartServer (65-86)
  • withUrl (146-152)
  • withUrl (154-175)
ktor-client/ktor-client-curl/desktop/src/io/ktor/client/engine/curl/internal/CurlMultiApiHandler.kt (1)
ktor-client/ktor-client-curl/desktop/src/io/ktor/client/engine/curl/internal/CurlAdapters.kt (5)
  • option (88-91)
  • option (93-96)
  • option (98-101)
  • option (103-106)
  • option (108-111)
ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/ClientHeadersTest.kt (1)
ktor-client/ktor-client-test-base/common/src/io/ktor/client/test/base/ClientLoader.kt (1)
  • clientTests (33-57)
ktor-server/ktor-server-jetty/ktor-server-jetty-test-http2/jvm/test/io/ktor/tests/server/jetty/http2/JettyHttp2ServletAsyncTest.kt (2)
ktor-server/ktor-server-jetty/jvm/test/io/ktor/tests/server/jetty/JettyAsyncServletContainerTest.kt (7)
  • Servlet (11-12)
  • Servlet (14-15)
  • Servlet (17-24)
  • Servlet (26-37)
  • Servlet (39-45)
  • Servlet (47-55)
  • Servlet (57-58)
ktor-server/ktor-server-jetty/jvm/test/io/ktor/tests/server/jetty/JettyBlockingServletContainerTest.kt (6)
  • Servlet (11-12)
  • Servlet (14-15)
  • Servlet (17-24)
  • Servlet (26-42)
  • Servlet (44-50)
  • Servlet (52-60)
ktor-client/ktor-client-tests/common/src/io/ktor/client/tests/Http2Test.kt (4)
ktor-client/ktor-client-java/jvm/test/io/ktor/client/engine/java/JavaHttp2Test.kt (1)
  • enableHttp2 (13-15)
ktor-client/ktor-client-apache5/jvm/test/io/ktor/client/engine/apache5/Apache5Http2Test.kt (1)
  • enableHttp2 (13-26)
ktor-client/ktor-client-okhttp/jvm/test/io/ktor/client/engine/okhttp/OkHttpHttp2Test.kt (1)
  • enableHttp2 (21-23)
ktor-client/ktor-client-darwin/darwin/test/DarwinHttp2Test.kt (1)
  • disableCertificateValidation (14-17)
ktor-client/ktor-client-okhttp/jvm/test/io/ktor/client/engine/okhttp/OkHttpHttp2Test.kt (3)
ktor-client/ktor-client-okhttp/jvm/src/io/ktor/client/engine/okhttp/OkHttpConfig.kt (2)
  • config (15-92)
  • config (63-69)
ktor-client/ktor-client-okhttp/jvm/src/io/ktor/client/engine/okhttp/OkHttpEngine.kt (1)
  • config (28-156)
ktor-client/ktor-client-tests/common/src/io/ktor/client/tests/Http2Test.kt (1)
  • configureClient (52-61)
ktor-client/ktor-client-darwin/darwin/test/DarwinEngineTest.kt (1)
ktor-client/ktor-client-darwin/darwin/test/utils/Certificates.kt (1)
  • trustAnyCertificate (11-23)
ktor-server/ktor-server-jetty/jvm/test/io/ktor/tests/server/jetty/JettyAsyncServletContainerTest.kt (2)
ktor-server/ktor-server-jetty/jvm/test/io/ktor/tests/server/jetty/JettyBlockingServletContainerTest.kt (6)
  • Servlet (11-12)
  • Servlet (14-15)
  • Servlet (17-24)
  • Servlet (26-42)
  • Servlet (44-50)
  • Servlet (52-60)
ktor-server/ktor-server-jetty/ktor-server-jetty-test-http2/jvm/test/io/ktor/tests/server/jetty/http2/JettyHttp2ServletAsyncTest.kt (5)
  • Servlet (11-12)
  • Servlet (14-15)
  • Servlet (17-24)
  • Servlet (26-37)
  • Servlet (39-45)
ktor-server/ktor-server-jetty-jakarta/ktor-server-jetty-test-http2-jakarta/jvm/test/io/ktor/tests/server/jetty/http2/jakarta/JettyHttp2ServletAsyncTest.kt (2)
ktor-server/ktor-server-jetty-jakarta/jvm/test/io/ktor/tests/server/jetty/jakarta/JettyAsyncServletContainerTest.kt (6)
  • Servlet (11-12)
  • Servlet (14-15)
  • Servlet (17-24)
  • Servlet (26-42)
  • Servlet (44-50)
  • Servlet (52-60)
ktor-server/ktor-server-jetty-jakarta/jvm/test/io/ktor/tests/server/jetty/jakarta/JettyBlockingServletContainerTest.kt (6)
  • Servlet (12-13)
  • Servlet (15-16)
  • Servlet (18-25)
  • Servlet (27-43)
  • Servlet (45-51)
  • Servlet (53-61)
ktor-test-server/src/main/kotlin/test/server/TestServer.kt (2)
ktor-test-server/src/main/kotlin/test/server/tests/CloseableGroup.kt (1)
  • use (12-14)
ktor-server/ktor-server-core/common/src/io/ktor/server/engine/EngineConnectorConfig.kt (1)
  • connector (74-76)
ktor-client/ktor-client-darwin/darwin/test/DarwinHttp2Test.kt (1)
ktor-client/ktor-client-darwin/darwin/test/utils/Certificates.kt (1)
  • trustAnyCertificate (11-23)
🪛 detekt (1.23.8)
ktor-server/ktor-server-tomcat-jakarta/jvm/test/io/ktor/tests/server/tomcat/jakarta/TomcatEngineTest.kt

[warning] 176-176: This empty block of code can be removed.

(detekt.empty-blocks.EmptyFunctionBlock)

ktor-server/ktor-server-cio/jvm/test/io/ktor/tests/server/cio/CIOEngineTestJvm.kt

[warning] 51-51: This empty block of code can be removed.

(detekt.empty-blocks.EmptyFunctionBlock)

ktor-server/ktor-server-jetty/ktor-server-jetty-test-http2/jvm/test/io/ktor/tests/server/jetty/http2/JettyHttp2ServletAsyncTest.kt

[warning] 40-41: This empty block of code can be removed.

(detekt.empty-blocks.EmptyFunctionBlock)

ktor-server/ktor-server-tomcat/jvm/test/io/ktor/tests/server/tomcat/TomcatEngineTest.kt

[warning] 176-176: This empty block of code can be removed.

(detekt.empty-blocks.EmptyFunctionBlock)

ktor-server/ktor-server-jetty/ktor-server-jetty-test-http2/jvm/test/io/ktor/tests/server/jetty/http2/JettyEngineTest.kt

[warning] 38-38: This empty block of code can be removed.

(detekt.empty-blocks.EmptyFunctionBlock)

ktor-server/ktor-server-jetty/jvm/test/io/ktor/tests/server/jetty/JettyAsyncServletContainerTest.kt

[warning] 44-44: This empty block of code can be removed.

(detekt.empty-blocks.EmptyFunctionBlock)

ktor-server/ktor-server-jetty/ktor-server-jetty-test-http2/jvm/test/io/ktor/tests/server/jetty/http2/JettyHttp2ServletBlockingTest.kt

[warning] 49-49: This empty block of code can be removed.

(detekt.empty-blocks.EmptyFunctionBlock)

ktor-client/ktor-client-plugins/ktor-client-logging/common/src/io/ktor/client/plugins/logging/Logger.kt

[warning] 51-51: This empty block of code can be removed.

(detekt.empty-blocks.EmptyFunctionBlock)

ktor-server/ktor-server-jetty-jakarta/ktor-server-jetty-test-http2-jakarta/jvm/test/io/ktor/tests/server/jetty/http2/jakarta/JettyHttp2ServletBlockingTest.kt

[warning] 49-49: This empty block of code can be removed.

(detekt.empty-blocks.EmptyFunctionBlock)

@osipxd osipxd merged commit c68f4ee into main Nov 19, 2025
18 of 21 checks passed
@osipxd osipxd deleted the osipxd/merge-release-into-main branch November 19, 2025 08:53
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.

5 participants