Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KTOR-6501 Add client KDocs for config and ObservableContent #4476

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,48 @@ package io.ktor.client
import io.ktor.client.engine.*
import io.ktor.client.plugins.*
import io.ktor.util.*
import io.ktor.util.collections.*
import io.ktor.utils.io.*
import kotlin.collections.set

/**
* A mutable [HttpClient] configuration.
* A mutable [HttpClient] configuration used to adjust settings, install plugins and interceptors.
*
* This class is available as block in [HttpClient] constructor or [HttpClient.config] builder:
* ```kotlin
* val client = HttpClient { // HttpClientConfig<Engine>()
* // Configure engine settings
* engine { // HttpClientEngineConfig
* threadsCount = 4
* pipelining = true
* }
*
* // Install and configure plugins
* install(ContentNegotiation) {
* json()
* }
*
* // Configure default request parameters
* defaultRequest {
* url("https://api.example.com")
* header("X-Custom-Header", "value")
* }
*
* // Configure client-wide settings
* expectSuccess = true
* followRedirects = true
* }
* ```
* ## Configuring [HttpClientEngine]
*
* If the engine is specified explicitly, engine specific properties will be available in the engine block:
* ```kotlin
* val client = HttpClient(CIO) { // HttpClientConfig<CIOEngineConfig>.() -> Unit
* engine { // CIOEngineConfig.() -> Unit
* // engine specific properties
* }
* }
* ```
*
* Learn more about the client's configuration from
* [Creating and configuring a client](https://ktor.io/docs/create-client.html).
*/
Expand All @@ -25,7 +61,15 @@ public class HttpClientConfig<T : HttpClientEngineConfig> {
internal var engineConfig: T.() -> Unit = {}

/**
* Allows you to configure engine parameters.
* Builder for configuring engine-specific settings in [HttpClientEngineConfig]
* (like dispatcher, threads count, proxy, etc.)
*
* ```kotlin
* val client = HttpClient(CIO) { // HttpClientConfig<CIOEngineConfig>
* engine { // CIOEngineConfig.() -> Unit
* proxy = ProxyBuilder.http("proxy.example.com", 8080)
* }
* ```
*
* You can learn more from [Engines](https://ktor.io/docs/http-client-engines.html).
*/
Expand All @@ -40,17 +84,34 @@ public class HttpClientConfig<T : HttpClientEngineConfig> {
/**
* Specifies whether the client redirects to URLs provided in the `Location` header.
* You can disable redirections by setting this property to `false`.
*
* For the advanced redirection configuration, use [HttpRedirect] plugin.
*/
public var followRedirects: Boolean = true

/**
* Uses [defaultTransformers] to automatically handle simple [ContentType].
* Enable body transformations for many common types like [String], [ByteArray], [ByteReadChannel], etc.
* These transformations are applied to the request and response bodies.
*
* The transformers will be used when the response body is received with a type:
* ```kotlin
* val client = HttpClient()
* val bytes = client.get("https://ktor.io")
* .body<ByteArray>()
* ```
*
* The flag is enabled by default.
* You might want to disable it if you want to write your own transformers or handle body manually.
*
* Check [defaultTransformers] documentation for more details.
*/
public var useDefaultTransformers: Boolean = true

/**
* Terminates [HttpClient.receivePipeline] if the status code is not successful (>=300).
* Learn more from [Response validation](https://ktor.io/docs/response-validation.html).
*
* Please check [HttpCallValidator] documentation to learn more details.
*/
public var expectSuccess: Boolean = false

Expand All @@ -66,6 +127,18 @@ public class HttpClientConfig<T : HttpClientEngineConfig> {

/**
* Installs the specified [plugin] and optionally configures it using the [configure] block.
*
* ```kotlin
* val client = HttpClient {
* install(ContentNegotiation) {
* // configuration block
* json()
* }
* }
* ```
*
* If the plugin is already installed
*
* Learn more from [Plugins](https://ktor.io/docs/http-client-plugins.html).
*/
public fun <TBuilder : Any, TPlugin : Any> install(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ import kotlin.coroutines.*

/**
* Callback that can be registered to listen for upload/download progress.
*
* This class is used for callbacks in [HttpRequestBuilder.onDownload] and [HttpRequestBuilder.onUpload].
*
* @param bytesSentTotal number of transmitted bytes.
* @param contentLength body size. Can be null if the size is unknown.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import kotlinx.coroutines.*
import kotlin.coroutines.*

/**
* Default user agent to use in ktor client.
* Default user agent to use in a ktor client.
*/
@InternalAPI
public val KTOR_DEFAULT_USER_AGENT: String = "ktor-client"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ private val LOGGER = KtorSimpleLogger("io.ktor.client.plugins.defaultTransformer
* Usually installed by default so there is no need to use it
* unless you have disabled it via [HttpClientConfig.useDefaultTransformers].
*/
@OptIn(InternalAPI::class)
public fun HttpClient.defaultTransformers() {
requestPipeline.intercept(HttpRequestPipeline.Render) { body ->
if (context.headers[HttpHeaders.Accept] == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,9 @@ public typealias CallExceptionHandler = suspend (cause: Throwable) -> Unit
public typealias CallRequestExceptionHandler = suspend (cause: Throwable, request: HttpRequest) -> Unit

/**
* Response validator plugin is used for validate response and handle response exceptions.
* Response validator plugin is used for validating [HttpClient] response and handle response exceptions.
*
* See also [Config] for additional details.
* See also [HttpCallValidatorConfig] for additional details.
*/
public val HttpCallValidator: ClientPlugin<HttpCallValidatorConfig> = createClientPlugin(
"HttpResponseValidator",
Expand Down
48 changes: 48 additions & 0 deletions ktor-client/ktor-client-core/common/test/HttpClientConfigTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import io.ktor.client.HttpClient
import io.ktor.client.HttpClientConfig
import io.ktor.client.engine.HttpClientEngineConfig
import io.ktor.client.plugins.api.createClientPlugin
import kotlin.test.Test
import kotlin.test.assertEquals

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

class HttpClientConfigTest {

@Test
fun testPluginInstalledTwice() {
var configuration = 0
var installation = 0
var first = 0
var second = 0

class Config {
var firstConfig = 0
var secondConfig = 0
init {
configuration++
}
}

val plugin = createClientPlugin("hey", ::Config) {
installation++
}

val client = HttpClient {
install(plugin) {
first += 1
}

install(plugin) {
second += 1
}
}

assertEquals(1, configuration)
assertEquals(1, installation)
assertEquals(1, first)
assertEquals(1, second)
}
}