Skip to content

Commit 73ec30a

Browse files
authored
Merge branch 'main' into zibet27/fix-netty-engine-stop
2 parents 4f415e1 + c68f4ee commit 73ec30a

File tree

267 files changed

+9136
-885
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

267 files changed

+9136
-885
lines changed

CHANGELOG.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,25 @@
1+
# 3.3.2
2+
> Published 5 November 2025
3+
4+
### Improvements
5+
* WebRTC Client. Remove redundant targets ([KTOR-9062](https://youtrack.jetbrains.com/issue/KTOR-9062))
6+
* Add Socks proxy support to Darwin engine ([KTOR-8968](https://youtrack.jetbrains.com/issue/KTOR-8968))
7+
* Java: Improve error message when SOCKS proxy is used ([KTOR-2908](https://youtrack.jetbrains.com/issue/KTOR-2908))
8+
9+
### Bugfixes
10+
* HttpRequestRetry: SendCountExceedException when max retries is more than maxSendCount of HttpSend ([KTOR-5850](https://youtrack.jetbrains.com/issue/KTOR-5850))
11+
* Darwin: The `maxFrameSize` option has no effect ([KTOR-6963](https://youtrack.jetbrains.com/issue/KTOR-6963))
12+
* OpenAPI: StackOverflowError when a response object has property with @Contextual serializer ([KTOR-8878](https://youtrack.jetbrains.com/issue/KTOR-8878))
13+
* OpenAPI gen: missing KDoc fields ([KTOR-9021](https://youtrack.jetbrains.com/issue/KTOR-9021))
14+
* Server call.request.path() returns routing selectors in path ([KTOR-7639](https://youtrack.jetbrains.com/issue/KTOR-7639))
15+
* StaticContent doesn't allow siblings ([KTOR-9012](https://youtrack.jetbrains.com/issue/KTOR-9012))
16+
* HttpCache: FileStorage doesn't use given dispatcher for all file operations ([KTOR-8832](https://youtrack.jetbrains.com/issue/KTOR-8832))
17+
* Curl: SOCKS proxy doesn't work ([KTOR-9008](https://youtrack.jetbrains.com/issue/KTOR-9008))
18+
* Netty: java.lang.VerifyError is thrown on Android since 3.3.0 ([KTOR-8916](https://youtrack.jetbrains.com/issue/KTOR-8916))
19+
* Response body channel is canceled while the body is being saved when having HttpRequestRetry and onDownload ([KTOR-8975](https://youtrack.jetbrains.com/issue/KTOR-8975))
20+
* HttpCache: InvalidCacheStateException when varyKeys stored in files contain uppercase letters since 3.3.0 ([KTOR-8970](https://youtrack.jetbrains.com/issue/KTOR-8970))
21+
22+
123
# 3.3.1
224
> Published 8 October 2025
325

CONTRIBUTING.md

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,17 +41,8 @@ Up to 12 GB of free RAM is required to build the project.
4141
This amount can be reduced by decreasing the `Xmx` value in `gradle.properties`.
4242
Read the comments in `gradle.properties` for more details.
4343

44-
The path to the android sdk should be defined in the ANDROID_HOME environment variable or `sdk.dir` in the `local.properties` file, like:
45-
```properties
46-
sdk.dir=/Users/USER_NAME/Library/Android/sdk
47-
```
48-
49-
If you target macOS and/or iOS, install `Xcode`, `Xcode command line tools`, `CocoaPods` and `Ruby` on macOS.
50-
An outdated Ruby version 2 is installed by default, but you should manually install a new version of it.
51-
We recommend using Ruby `3.3.x` or newer with [rbenv](https://github.com/rbenv/rbenv):
52-
- `rbenv install 3.3.x`
53-
- `rbenv global 3.3.x`
54-
- `sudo gem install -n /usr/local/bin cocoapods`
44+
On macOS, install [Xcode and Xcode Command line tools](https://developer.apple.com/download/) to build Apple targets.
45+
Launch it and accept the license terms first.
5546

5647
<details>
5748
<summary>Requirements for Ktor before 3.1.0</summary>
@@ -85,6 +76,32 @@ libraries such as `libncurses`.
8576

8677
</details>
8778

79+
#### Optional: Android SDK
80+
81+
The Android SDK is optional for building Ktor.
82+
If the Android SDK is not available, Android targets will be automatically excluded from the build.
83+
84+
To install the Android SDK, use [Android Studio](https://developer.android.com/studio) or [sdkmanager](https://developer.android.com/tools/sdkmanager).
85+
86+
To enable Android targets,
87+
define the path to the Android SDK in the `ANDROID_HOME` environment variable or `sdk.dir` in the `local.properties` file:
88+
```properties
89+
sdk.dir=/path/to/android/sdk
90+
```
91+
92+
#### Optional: CocoaPods for Apple targets
93+
94+
CocoaPods is optional for building Ktor.
95+
If CocoaPods is not available on macOS, Apple targets will be automatically excluded from modules that require CocoaPods dependencies (e.g., `ktor-client-webrtc`).
96+
Other modules will continue to build Apple targets normally.
97+
98+
To install CocoaPods, follow the [Kotlin Multiplatform CocoaPods setup guide](https://www.jetbrains.com/help/kotlin-multiplatform-dev/multiplatform-cocoapods-overview.html).
99+
100+
You can also specify the path to the `pod` executable using the `kotlin.native.cocoapods.bin` property in `local.properties`:
101+
```properties
102+
kotlin.native.cocoapods.bin=/path/to/pod/binary
103+
```
104+
88105
#### Referencing artifacts locally
89106

90107
There are two ways to reference artifacts from the development Ktor locally in another project, which is usually

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
[![Official JetBrains project](http://jb.gg/badges/official.svg)](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub)
1111
[![Maven Central](https://img.shields.io/maven-central/v/io.ktor/ktor-server)](https://central.sonatype.com/search?namespace=io.ktor)
12-
[![Kotlin](https://img.shields.io/badge/kotlin-2.2.20-blue.svg?logo=kotlin)](http://kotlinlang.org)
12+
[![Kotlin](https://img.shields.io/badge/kotlin-2.2.21-blue.svg?logo=kotlin)](http://kotlinlang.org)
1313
[![Slack channel](https://img.shields.io/badge/chat-slack-green.svg?logo=slack)](https://kotlinlang.slack.com/messages/ktor/)
1414
[![GitHub License](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg?style=flat)](http://www.apache.org/licenses/LICENSE-2.0)
1515
[![Contribute with Gitpod](https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod)](https://gitpod.io/#https://github.com/ktorio/ktor)

build-logic/build.gradle.kts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ dependencies {
1515
implementation(libs.gradleDoctor)
1616
implementation(libs.kotlinter)
1717
implementation(libs.mavenPublishing)
18-
implementation(libs.android.kmp.library)
18+
implementation(libs.android.gradlePlugin)
1919

2020
// Needed for patches/DokkaVersioningPluginParameters
2121
// TODO: Remove when the PR fixing this file will be merged and released. Probably in Dokka 2.2.0
@@ -33,5 +33,6 @@ kotlin {
3333

3434
compilerOptions {
3535
allWarningsAsErrors = true
36+
freeCompilerArgs.add("-Xcontext-parameters")
3637
}
3738
}

build-logic/src/main/kotlin/ktorbuild.kmp.gradle.kts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,9 @@ configureCommon()
4747
if (targets.hasJvm) configureJvm()
4848
if (targets.hasJs) configureJs()
4949
if (targets.hasWasmJs) configureWasmJs()
50+
if (targets.hasWeb) configureWeb()
5051
if (targets.hasAndroidJvm && project.hasAndroidPlugin()) configureAndroidJvm()
5152

52-
if (targets.hasJsOrWasmJs) {
53-
configureNodeJs()
54-
55-
tasks.configureEach {
56-
if (name == "compileJsAndWasmSharedMainKotlinMetadata") enabled = false
57-
}
58-
}
59-
6053
// Run native tests only on matching host.
6154
// There is no need to configure `onlyIf` for Darwin targets as they're configured by KGP.
6255
@Suppress("UnstableApiUsage")
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright 2014-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
import ktorbuild.internal.*
6+
import ktorbuild.internal.gradle.localProperty
7+
import org.gradle.kotlin.dsl.support.serviceOf
8+
9+
if (isAndroidSdkAvailable()) {
10+
apply(plugin = "com.android.kotlin.multiplatform.library")
11+
} else @Suppress("UnstableApiUsage") {
12+
val problemReporter = project.serviceOf<Problems>().reporter
13+
problemReporter.reportVisible(
14+
KtorBuildProblems.missingAndroidSdk,
15+
details = "Android SDK not found.",
16+
contextualLabel = "Android target won't be added to the project ${project.path}.",
17+
) {
18+
solution("Download Android SDK from Android Studio or sdkmanager: https://developer.android.com/tools/sdkmanager")
19+
solution("Set ANDROID_HOME environment variable to your Android SDK path")
20+
solution("Create local.properties file with: sdk.dir=/path/to/your/android/sdk")
21+
buildFileLocation()
22+
documentedAt("https://github.com/ktorio/ktor/blob/main/CONTRIBUTING.md#building-the-project")
23+
}
24+
}
25+
26+
private fun Project.isAndroidSdkAvailable(): Boolean =
27+
providers.environmentVariable("ANDROID_HOME")
28+
.orElse(localProperty("sdk.dir"))
29+
.isPresent
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright 2014-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
import ktorbuild.internal.*
6+
import ktorbuild.internal.gradle.localProperty
7+
import ktorbuild.targets.*
8+
import org.gradle.kotlin.dsl.support.serviceOf
9+
import org.jetbrains.kotlin.konan.target.HostManager
10+
import java.io.OutputStream
11+
12+
pluginManager.withPlugin("org.jetbrains.kotlin.multiplatform") {
13+
val cocoaPodsAvailable = localProperty(COCOAPODS_BIN_PROPERTY).map { true }
14+
.orElse(providers.gradleProperty(COCOAPODS_BIN_PROPERTY).map { true })
15+
.orElse(providers.of(CocoaPodsAvailableValueSource::class) {})
16+
17+
if (!HostManager.hostIsMac || cocoaPodsAvailable.get()) {
18+
apply(plugin = COCOAPODS_PLUGIN_ID)
19+
} else @Suppress("UnstableApiUsage") {
20+
// Disable Darwin targets if CocoaPods is not available
21+
ktorBuild.targets["darwin"] = false
22+
23+
val problemReporter = project.serviceOf<Problems>().reporter
24+
problemReporter.reportVisible(
25+
KtorBuildProblems.missingCocoaPods,
26+
details = "CocoaPods not found.",
27+
contextualLabel = "Apple targets won't be added in the project.",
28+
) {
29+
solution("Install CocoaPods")
30+
solution("Ensure 'pod' command is available in PATH")
31+
buildFileLocation()
32+
documentedAt("https://github.com/ktorio/ktor/blob/main/CONTRIBUTING.md#building-the-project")
33+
}
34+
}
35+
}
36+
37+
internal abstract class CocoaPodsAvailableValueSource @Inject constructor(
38+
val execOperations: ExecOperations,
39+
) : ValueSource<Boolean, ValueSourceParameters.None> {
40+
41+
override fun obtain(): Boolean {
42+
val result = execOperations.exec {
43+
commandLine("which", "pod")
44+
isIgnoreExitValue = true
45+
standardOutput = OutputStream.nullOutputStream()
46+
errorOutput = OutputStream.nullOutputStream()
47+
}
48+
49+
return result.exitValue == 0
50+
}
51+
}

build-logic/src/main/kotlin/ktorbuild/CInterop.kt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,14 @@ fun KotlinMultiplatformExtension.disableNativeCompileConfigurationCache() {
2121
project.tasks.withType<KotlinNativeCompile>()
2222
.named { it.endsWith("MainKotlinMetadata") }
2323
.configureEach { notCompatibleWithConfigurationCache("Workaround for KT-76147") }
24+
25+
// The problem with compile*MainKotlinMetadata tasks also affects Dokka tasks
26+
project.tasks.withType<DokkaGeneratePublicationTask>()
27+
.named { it == "dokkaGeneratePublicationHtml" }
28+
.configureEach { notCompatibleWithConfigurationCache("Workaround for KT-76147") }
29+
project.tasks.withType<DokkaGenerateModuleTask>()
30+
.named { it == "dokkaGenerateModuleHtml" }
31+
.configureEach { notCompatibleWithConfigurationCache("Workaround for KT-76147") }
2432
}
2533

2634
/**
@@ -75,12 +83,4 @@ fun KotlinMultiplatformExtension.createCInterop(
7583
}
7684

7785
disableNativeCompileConfigurationCache()
78-
79-
// The problem with compile*MainKotlinMetadata tasks also affects Dokka tasks
80-
project.tasks.withType<DokkaGeneratePublicationTask>()
81-
.named { it == "dokkaGeneratePublicationHtml" }
82-
.configureEach { notCompatibleWithConfigurationCache("Workaround for KT-76147") }
83-
project.tasks.withType<DokkaGenerateModuleTask>()
84-
.named { it == "dokkaGenerateModuleHtml" }
85-
.configureEach { notCompatibleWithConfigurationCache("Workaround for KT-76147") }
8686
}

build-logic/src/main/kotlin/ktorbuild/dsl/KotlinSourceSets.kt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,15 @@
66

77
import org.gradle.api.NamedDomainObjectContainer
88
import org.gradle.api.NamedDomainObjectProvider
9+
import org.gradle.api.NamedDomainObjectSet
910
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
1011
import org.jetbrains.kotlin.gradle.dsl.KotlinSourceSetConvention
12+
import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler
1113
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
1214

1315
private typealias KotlinSourceSets = NamedDomainObjectContainer<KotlinSourceSet>
1416
private typealias KotlinSourceSetProvider = NamedDomainObjectProvider<KotlinSourceSet>
17+
private typealias OptionalKotlinSourceSetProvider = NamedDomainObjectSet<KotlinSourceSet>
1518

1619
// Additional accessors to the ones declared in KotlinMultiplatformSourceSetConventions
1720

@@ -22,3 +25,18 @@ val KotlinSourceSets.desktopMain: KotlinSourceSetProvider by KotlinSourceSetConv
2225
val KotlinSourceSets.desktopTest: KotlinSourceSetProvider by KotlinSourceSetConvention
2326
val KotlinSourceSets.windowsMain: KotlinSourceSetProvider by KotlinSourceSetConvention
2427
val KotlinSourceSets.windowsTest: KotlinSourceSetProvider by KotlinSourceSetConvention
28+
29+
val KotlinSourceSets.optional: OptionalSourceSets get() = OptionalSourceSets(this)
30+
31+
@JvmInline
32+
value class OptionalSourceSets(private val sourceSets: KotlinSourceSets) {
33+
val androidMain: OptionalKotlinSourceSetProvider get() = optional("androidMain")
34+
val androidTest: OptionalKotlinSourceSetProvider get() = optional("androidTest")
35+
val androidDeviceTest: OptionalKotlinSourceSetProvider get() = optional("androidDeviceTest")
36+
37+
private fun optional(name: String): OptionalKotlinSourceSetProvider = sourceSets.named { it == name }
38+
}
39+
40+
fun OptionalKotlinSourceSetProvider.dependencies(handler: KotlinDependencyHandler.() -> Unit) {
41+
configureEach { dependencies(handler) }
42+
}

build-logic/src/main/kotlin/ktorbuild/internal/Accessors.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ internal val Project.ktorBuild: KtorBuildExtension get() = extensions.getByType(
2121

2222
internal val Project.java: JavaPluginExtension get() = extensions.getByType()
2323

24+
internal val Project.kotlin: KotlinMultiplatformExtension get() = extensions.getByType()
25+
2426
internal fun Project.kotlin(configure: KotlinMultiplatformExtension.() -> Unit) =
2527
extensions.configure("kotlin", configure)
2628

0 commit comments

Comments
 (0)