diff --git a/ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/Android.kt b/ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/Android.kt index 5efb76b6651..910e7abcc02 100644 --- a/ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/Android.kt +++ b/ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/Android.kt @@ -25,6 +25,8 @@ import io.ktor.client.engine.* * ``` * * You can learn more about client engines from [Engines](https://ktor.io/docs/http-client-engines.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.android.Android) */ public data object Android : HttpClientEngineFactory { override fun create(block: AndroidEngineConfig.() -> Unit): HttpClientEngine = diff --git a/ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidClientEngine.kt b/ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidClientEngine.kt index ddde6819738..5fdd5b9f576 100644 --- a/ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidClientEngine.kt +++ b/ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidClientEngine.kt @@ -25,6 +25,8 @@ private val METHODS_WITHOUT_BODY = listOf(HttpMethod.Get, HttpMethod.Head) /** * An Android client engine. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.android.AndroidClientEngine) */ @OptIn(InternalAPI::class) public class AndroidClientEngine(override val config: AndroidEngineConfig) : HttpClientEngineBase("ktor-android") { diff --git a/ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidEngineConfig.kt b/ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidEngineConfig.kt index 1e07ff7a6b8..d9262d1c41c 100644 --- a/ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidEngineConfig.kt +++ b/ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidEngineConfig.kt @@ -10,12 +10,16 @@ import javax.net.ssl.* /** * A configuration for the [Android] client engine. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.android.AndroidEngineConfig) */ public class AndroidEngineConfig : HttpClientEngineConfig() { /** * Specifies a time period (in milliseconds) in which a client should establish a connection with a server. * * Set this value to `0` to use an infinite timeout. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.android.AndroidEngineConfig.connectTimeout) */ public var connectTimeout: Int = 100_000 @@ -23,16 +27,22 @@ public class AndroidEngineConfig : HttpClientEngineConfig() { * Specifies a maximum time (in milliseconds) of inactivity between two data packets when exchanging data with a server. * * Set this value to `0` to use an infinite timeout. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.android.AndroidEngineConfig.socketTimeout) */ public var socketTimeout: Int = 100_000 /** * Allows you to configure [HTTPS](https://ktor.io/docs/client-ssl.html) settings for this engine. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.android.AndroidEngineConfig.sslManager) */ public var sslManager: (HttpsURLConnection) -> Unit = {} /** * Allows you to set engine-specific request configuration. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.android.AndroidEngineConfig.requestConfig) */ public var requestConfig: HttpURLConnection.() -> Unit = {} } diff --git a/ktor-client/ktor-client-apache/jvm/src/io/ktor/client/engine/apache/Apache.kt b/ktor-client/ktor-client-apache/jvm/src/io/ktor/client/engine/apache/Apache.kt index 2df9167d90d..16606b7a515 100644 --- a/ktor-client/ktor-client-apache/jvm/src/io/ktor/client/engine/apache/Apache.kt +++ b/ktor-client/ktor-client-apache/jvm/src/io/ktor/client/engine/apache/Apache.kt @@ -24,6 +24,8 @@ import io.ktor.client.engine.* * ``` * * You can learn more about client engines from [Engines](https://ktor.io/docs/http-client-engines.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.apache.Apache) */ public data object Apache : HttpClientEngineFactory { override fun create(block: ApacheEngineConfig.() -> Unit): HttpClientEngine { diff --git a/ktor-client/ktor-client-apache/jvm/src/io/ktor/client/engine/apache/ApacheEngineConfig.kt b/ktor-client/ktor-client-apache/jvm/src/io/ktor/client/engine/apache/ApacheEngineConfig.kt index 4ebcd28216b..3887a9a9939 100644 --- a/ktor-client/ktor-client-apache/jvm/src/io/ktor/client/engine/apache/ApacheEngineConfig.kt +++ b/ktor-client/ktor-client-apache/jvm/src/io/ktor/client/engine/apache/ApacheEngineConfig.kt @@ -11,6 +11,8 @@ import javax.net.ssl.SSLContext /** * A configuration for the [Apache] client engine. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.apache.ApacheEngineConfig) */ public class ApacheEngineConfig : HttpClientEngineConfig() { /** @@ -18,6 +20,8 @@ public class ApacheEngineConfig : HttpClientEngineConfig() { * Disabled by default. * * _Note: By default, the Apache client allows `50` redirects._ + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.apache.ApacheEngineConfig.followRedirects) */ public var followRedirects: Boolean = false @@ -25,6 +29,8 @@ public class ApacheEngineConfig : HttpClientEngineConfig() { * Specifies a maximum time (in milliseconds) of inactivity between two data packets when exchanging data with a server. * * Set this value to `0` to use an infinite timeout. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.apache.ApacheEngineConfig.socketTimeout) */ public var socketTimeout: Int = 10_000 @@ -32,6 +38,8 @@ public class ApacheEngineConfig : HttpClientEngineConfig() { * Specifies a time period (in milliseconds) in which a client should establish a connection with a server. * * A `0` value represents an infinite timeout, while `-1` represents a system's default value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.apache.ApacheEngineConfig.connectTimeout) */ public var connectTimeout: Int = 10_000 @@ -39,28 +47,38 @@ public class ApacheEngineConfig : HttpClientEngineConfig() { * Specifies a time period (in milliseconds) in which a client should start a request. * * A `0` value represents an infinite timeout, while `-1` represents a system's default value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.apache.ApacheEngineConfig.connectionRequestTimeout) */ public var connectionRequestTimeout: Int = 20_000 /** * Allows you to configure [SSL](https://ktor.io/docs/client-ssl.html) settings for this engine. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.apache.ApacheEngineConfig.sslContext) */ public var sslContext: SSLContext? = null /** * Specifies a custom processor for [RequestConfig.Builder]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.apache.ApacheEngineConfig.customRequest) */ public var customRequest: (RequestConfig.Builder.() -> RequestConfig.Builder) = { this } private set /** * Specifies a custom processor for [HttpAsyncClientBuilder]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.apache.ApacheEngineConfig.customClient) */ public var customClient: (HttpAsyncClientBuilder.() -> HttpAsyncClientBuilder) = { this } private set /** * Customizes a [RequestConfig.Builder] in the specified [block]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.apache.ApacheEngineConfig.customizeRequest) */ public fun customizeRequest(block: RequestConfig.Builder.() -> Unit) { val current = customRequest @@ -69,6 +87,8 @@ public class ApacheEngineConfig : HttpClientEngineConfig() { /** * Customizes a [HttpAsyncClientBuilder] in the specified [block]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.apache.ApacheEngineConfig.customizeClient) */ public fun customizeClient(block: HttpAsyncClientBuilder.() -> Unit) { val current = customClient diff --git a/ktor-client/ktor-client-apache5/jvm/src/io/ktor/client/engine/apache5/Apache5.kt b/ktor-client/ktor-client-apache5/jvm/src/io/ktor/client/engine/apache5/Apache5.kt index 4d527129470..4e1c547b320 100644 --- a/ktor-client/ktor-client-apache5/jvm/src/io/ktor/client/engine/apache5/Apache5.kt +++ b/ktor-client/ktor-client-apache5/jvm/src/io/ktor/client/engine/apache5/Apache5.kt @@ -24,6 +24,8 @@ import io.ktor.client.engine.* * ``` * * You can learn more about client engines from [Engines](https://ktor.io/docs/http-client-engines.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.apache5.Apache5) */ public data object Apache5 : HttpClientEngineFactory { override fun create(block: Apache5EngineConfig.() -> Unit): HttpClientEngine { diff --git a/ktor-client/ktor-client-apache5/jvm/src/io/ktor/client/engine/apache5/Apache5EngineConfig.kt b/ktor-client/ktor-client-apache5/jvm/src/io/ktor/client/engine/apache5/Apache5EngineConfig.kt index 81ee8a4dbb8..11538f2fa5e 100644 --- a/ktor-client/ktor-client-apache5/jvm/src/io/ktor/client/engine/apache5/Apache5EngineConfig.kt +++ b/ktor-client/ktor-client-apache5/jvm/src/io/ktor/client/engine/apache5/Apache5EngineConfig.kt @@ -12,6 +12,8 @@ import javax.net.ssl.SSLContext /** * A configuration for the [Apache5] client engine. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.apache5.Apache5EngineConfig) */ public class Apache5EngineConfig : HttpClientEngineConfig() { /** @@ -19,6 +21,8 @@ public class Apache5EngineConfig : HttpClientEngineConfig() { * Disabled by default. * * _Note: By default, the Apache client allows `50` redirects._ + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.apache5.Apache5EngineConfig.followRedirects) */ public var followRedirects: Boolean = false @@ -26,6 +30,8 @@ public class Apache5EngineConfig : HttpClientEngineConfig() { * Specifies a maximum time (in milliseconds) of inactivity between two data packets when exchanging data with a server. * * Set this value to `0` to use an infinite timeout. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.apache5.Apache5EngineConfig.socketTimeout) */ public var socketTimeout: Int = 10_000 @@ -33,6 +39,8 @@ public class Apache5EngineConfig : HttpClientEngineConfig() { * Specifies a time period (in milliseconds) in which a client should establish a connection with a server. * * A `0` value represents an infinite timeout, while `-1` represents a system's default value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.apache5.Apache5EngineConfig.connectTimeout) */ public var connectTimeout: Long = 10_000 @@ -40,11 +48,15 @@ public class Apache5EngineConfig : HttpClientEngineConfig() { * Specifies a time period (in milliseconds) in which a client should start a request. * * A `0` value represents an infinite timeout, while `-1` represents a system's default value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.apache5.Apache5EngineConfig.connectionRequestTimeout) */ public var connectionRequestTimeout: Long = 20_000 /** * Allows you to configure [SSL](https://ktor.io/docs/client-ssl.html) settings for this engine. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.apache5.Apache5EngineConfig.sslContext) */ public var sslContext: SSLContext? = null @@ -59,6 +71,9 @@ public class Apache5EngineConfig : HttpClientEngineConfig() { * Default value is [HostnameVerificationPolicy.BOTH] which provides maximum security * by performing verification at both stages. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.apache5.Apache5EngineConfig.sslHostnameVerificationPolicy) + * * @see HostnameVerificationPolicy */ public var sslHostnameVerificationPolicy: HostnameVerificationPolicy = HostnameVerificationPolicy.BOTH @@ -69,6 +84,8 @@ public class Apache5EngineConfig : HttpClientEngineConfig() { /** * Customizes a [RequestConfig.Builder] in the specified [block]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.apache5.Apache5EngineConfig.customizeRequest) */ public fun customizeRequest(block: RequestConfig.Builder.() -> Unit) { val current = customRequest @@ -77,6 +94,8 @@ public class Apache5EngineConfig : HttpClientEngineConfig() { /** * Customizes a [HttpAsyncClientBuilder] in the specified [block]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.apache5.Apache5EngineConfig.customizeClient) */ public fun customizeClient(block: HttpAsyncClientBuilder.() -> Unit) { val current = customClient diff --git a/ktor-client/ktor-client-cio/common/src/io/ktor/client/engine/cio/CIOCommon.kt b/ktor-client/ktor-client-cio/common/src/io/ktor/client/engine/cio/CIOCommon.kt index 7715a2b93fd..47e90c20169 100644 --- a/ktor-client/ktor-client-cio/common/src/io/ktor/client/engine/cio/CIOCommon.kt +++ b/ktor-client/ktor-client-cio/common/src/io/ktor/client/engine/cio/CIOCommon.kt @@ -23,6 +23,8 @@ import io.ktor.client.engine.* * ``` * * You can learn more about client engines from [Engines](https://ktor.io/docs/http-client-engines.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.cio.CIO) */ public data object CIO : HttpClientEngineFactory { override fun create(block: CIOEngineConfig.() -> Unit): HttpClientEngine = diff --git a/ktor-client/ktor-client-cio/common/src/io/ktor/client/engine/cio/CIOEngineConfig.kt b/ktor-client/ktor-client-cio/common/src/io/ktor/client/engine/cio/CIOEngineConfig.kt index a495afd9d2a..81d0c1b6690 100644 --- a/ktor-client/ktor-client-cio/common/src/io/ktor/client/engine/cio/CIOEngineConfig.kt +++ b/ktor-client/ktor-client-cio/common/src/io/ktor/client/engine/cio/CIOEngineConfig.kt @@ -10,20 +10,28 @@ import io.ktor.network.tls.* /** * A configuration for the [CIO] client engine. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.cio.CIOEngineConfig) */ public class CIOEngineConfig : HttpClientEngineConfig() { /** * Provides access to [Endpoint] settings. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.cio.CIOEngineConfig.endpoint) */ public val endpoint: EndpointConfig = EndpointConfig() /** * Allows you to configure [HTTPS](https://ktor.io/docs/client-ssl.html) settings for this engine. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.cio.CIOEngineConfig.https) */ public val https: TLSConfigBuilder = TLSConfigBuilder() /** * Specifies the maximum number of connections used to make [requests](https://ktor.io/docs/request.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.cio.CIOEngineConfig.maxConnectionsCount) */ public var maxConnectionsCount: Int = 1000 @@ -33,59 +41,82 @@ public class CIOEngineConfig : HttpClientEngineConfig() { * from sending a request to receiving a response. * * To disable this timeout, set its value to `0`. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.cio.CIOEngineConfig.requestTimeout) */ public var requestTimeout: Long = 15000 /** * Allows you to configure [HTTPS](https://ktor.io/docs/client-ssl.html) settings for this engine. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.cio.CIOEngineConfig.https) */ public fun https(block: TLSConfigBuilder.() -> Unit): TLSConfigBuilder = https.apply(block) } /** * Provides access to [Endpoint] settings. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.cio.endpoint) */ public fun CIOEngineConfig.endpoint(block: EndpointConfig.() -> Unit): EndpointConfig = endpoint.apply(block) /** * Contains [Endpoint] settings. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.cio.EndpointConfig) */ public class EndpointConfig { /** * Specifies the maximum number of connections for each host. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.cio.EndpointConfig.maxConnectionsPerRoute) + * * @see [CIOEngineConfig.maxConnectionsCount] */ public var maxConnectionsPerRoute: Int = 100 /** * Specifies a connection keep-alive time (in milliseconds). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.cio.EndpointConfig.keepAliveTime) */ public var keepAliveTime: Long = 5000 /** * Specifies a maximum number of requests to be sent over a single connection without waiting for the corresponding responses (HTTP pipelining). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.cio.EndpointConfig.pipelineMaxSize) */ public var pipelineMaxSize: Int = 20 /** * Specifies a time period (in milliseconds) in which a client should establish a connection with a server. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.cio.EndpointConfig.connectTimeout) */ public var connectTimeout: Long = 5000 /** * Specifies a maximum time (in milliseconds) of inactivity between two data packets when exchanging data with a server. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.cio.EndpointConfig.socketTimeout) */ public var socketTimeout: Long = HttpTimeoutConfig.INFINITE_TIMEOUT_MS /** * Specifies a maximum number of connection attempts. * Note: this property affects only connection retries, but not request retries. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.cio.EndpointConfig.connectAttempts) */ public var connectAttempts: Int = 1 /** * Allows a socket to close an output channel immediately on writing completion (half-closed TCP connection). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.cio.EndpointConfig.allowHalfClose) */ public var allowHalfClose: Boolean = false @Deprecated("Half closed TCP connection is not supported by all servers, use it at your own risk.") diff --git a/ktor-client/ktor-client-cio/jvm/src/io/ktor/client/plugins/websocket/cio/buildersCio.kt b/ktor-client/ktor-client-cio/jvm/src/io/ktor/client/plugins/websocket/cio/buildersCio.kt index c3fd6d563ff..15f38876592 100644 --- a/ktor-client/ktor-client-cio/jvm/src/io/ktor/client/plugins/websocket/cio/buildersCio.kt +++ b/ktor-client/ktor-client-cio/jvm/src/io/ktor/client/plugins/websocket/cio/buildersCio.kt @@ -13,6 +13,8 @@ import kotlinx.coroutines.* /** * Creates a raw [ClientWebSocketSession]: no ping-pong and other service messages are used. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.cio.webSocketRawSession) */ public suspend fun HttpClient.webSocketRawSession( method: HttpMethod = HttpMethod.Get, @@ -53,6 +55,8 @@ public suspend fun HttpClient.webSocketRawSession( /** * Creates a raw [ClientWebSocketSession]: no ping-pong and other service messages are used. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.cio.webSocketRaw) */ public suspend fun HttpClient.webSocketRaw( method: HttpMethod = HttpMethod.Get, @@ -80,6 +84,8 @@ public suspend fun HttpClient.webSocketRaw( /** * Creates a raw [ClientWebSocketSession]: no ping-pong and other service messages are used. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.cio.wsRaw) */ public suspend fun HttpClient.wsRaw( method: HttpMethod = HttpMethod.Get, @@ -94,6 +100,8 @@ public suspend fun HttpClient.wsRaw( /** * Create secure raw [ClientWebSocketSession]: no ping-pong and other service messages are used. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.cio.wssRaw) */ public suspend fun HttpClient.wssRaw( method: HttpMethod = HttpMethod.Get, diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/HttpClient.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/HttpClient.kt index 75aabe09998..ed27f414658 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/HttpClient.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/HttpClient.kt @@ -323,6 +323,8 @@ import kotlin.coroutines.* * * By directly setting the engine (e.g., `Apache`, `OkHttp`), you can optimize startup performance * by preventing the default service loader mechanism. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.HttpClient) */ @KtorDsl public expect fun HttpClient( @@ -634,6 +636,8 @@ public expect fun HttpClient( * * By directly setting the engine (e.g., `Apache`, `OkHttp`), you can optimize startup performance * by preventing the default service loader mechanism. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.HttpClient) */ @KtorDsl public fun HttpClient( @@ -958,6 +962,8 @@ public fun HttpClient( * * By directly setting the engine (e.g., `Apache`, `OkHttp`), you can optimize startup performance * by preventing the default service loader mechanism. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.HttpClient) */ @KtorDsl public fun HttpClient( @@ -1270,6 +1276,8 @@ public fun HttpClient( * * By directly setting the engine (e.g., `Apache`, `OkHttp`), you can optimize startup performance * by preventing the default service loader mechanism. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.HttpClient) */ @OptIn(InternalAPI::class) public class HttpClient( @@ -1294,36 +1302,50 @@ public class HttpClient( /** * A pipeline used for processing all requests sent by this client. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.HttpClient.requestPipeline) */ public val requestPipeline: HttpRequestPipeline = HttpRequestPipeline() /** * A pipeline used for processing all responses sent by the server. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.HttpClient.responsePipeline) */ public val responsePipeline: HttpResponsePipeline = HttpResponsePipeline() /** * A pipeline used for sending a request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.HttpClient.sendPipeline) */ public val sendPipeline: HttpSendPipeline = HttpSendPipeline() /** * A pipeline used for receiving a request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.HttpClient.receivePipeline) */ public val receivePipeline: HttpReceivePipeline = HttpReceivePipeline() /** * Typed attributes used as a lightweight container for this client. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.HttpClient.attributes) */ public val attributes: Attributes = Attributes(concurrent = true) /** * Provides access to the client's engine configuration. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.HttpClient.engineConfig) */ public val engineConfig: HttpClientEngineConfig = engine.config /** * Provides access to the events of the client's lifecycle. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.HttpClient.monitor) */ public val monitor: Events = Events() @@ -1395,6 +1417,8 @@ public class HttpClient( /** * Checks if the specified [capability] is supported by this client. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.HttpClient.isSupported) */ public fun isSupported(capability: HttpClientEngineCapability<*>): Boolean { return engine.supportedCapabilities.contains(capability) @@ -1403,6 +1427,8 @@ public class HttpClient( /** * Returns a new [HttpClient] by copying this client's configuration * and additionally configured by the [block] parameter. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.HttpClient.config) */ public fun config(block: HttpClientConfig<*>.() -> Unit): HttpClient = HttpClient( engine, @@ -1439,6 +1465,8 @@ public class HttpClient( * client.close() * engine.close() // Ensure manually created engine is also closed * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.HttpClient.close) */ override fun close() { val success = closed.compareAndSet(false, true) diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/HttpClientConfig.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/HttpClientConfig.kt index ce38b9cc6ab..7a45768d536 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/HttpClientConfig.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/HttpClientConfig.kt @@ -50,6 +50,8 @@ import io.ktor.utils.io.* * * Learn more about the client's configuration from * [Creating and configuring a client](https://ktor.io/docs/create-client.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.HttpClientConfig) */ @KtorDsl public class HttpClientConfig { @@ -71,6 +73,8 @@ public class HttpClientConfig { * ``` * * You can learn more from [Engines](https://ktor.io/docs/http-client-engines.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.HttpClientConfig.engine) */ public fun engine(block: T.() -> Unit) { val oldConfig = engineConfig @@ -85,6 +89,8 @@ public class HttpClientConfig { * You can disable redirections by setting this property to `false`. * * For an advanced redirection configuration, use the [HttpRedirect] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.HttpClientConfig.followRedirects) */ public var followRedirects: Boolean = true @@ -103,6 +109,8 @@ public class HttpClientConfig { * You might want to disable it if you want to write your own transformers or handle body manually. * * For more details, see the [defaultTransformers] documentation. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.HttpClientConfig.useDefaultTransformers) */ public var useDefaultTransformers: Boolean = true @@ -111,11 +119,15 @@ public class HttpClientConfig { * Learn more from [Response validation](https://ktor.io/docs/response-validation.html). * * For more details, see the [HttpCallValidator] documentation. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.HttpClientConfig.expectSuccess) */ public var expectSuccess: Boolean = false /** * Development mode is no longer required all functionality is enabled by default. The property is safe to remove. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.HttpClientConfig.developmentMode) */ @Deprecated( "Development mode is no longer required. The property will be removed in the future.", @@ -139,6 +151,8 @@ public class HttpClientConfig { * If the plugin is already installed, the configuration block will be applied to the existing configuration class. * * Learn more from [Plugins](https://ktor.io/docs/http-client-plugins.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.HttpClientConfig.install) */ public fun install( plugin: HttpClientPlugin, @@ -169,6 +183,8 @@ public class HttpClientConfig { * The [key] parameter is used as a unique name, that also prevents installing duplicated interceptors. * * If the [key] is already used, the new interceptor will replace the old one. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.HttpClientConfig.install) */ public fun install(key: String, block: HttpClient.() -> Unit) { customInterceptors[key] = block @@ -177,6 +193,8 @@ public class HttpClientConfig { /** * Applies all the installed [plugins] and [customInterceptors] from this configuration * into the specified [client]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.HttpClientConfig.install) */ public fun install(client: HttpClient) { plugins.values.forEach { client.apply(it) } @@ -185,6 +203,8 @@ public class HttpClientConfig { /** * Clones this [HttpClientConfig] by duplicating all the [plugins] and [customInterceptors]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.HttpClientConfig.clone) */ public fun clone(): HttpClientConfig { val result = HttpClientConfig() @@ -194,6 +214,8 @@ public class HttpClientConfig { /** * Installs the plugin from the [other] client's configuration. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.HttpClientConfig.plusAssign) */ public operator fun plusAssign(other: HttpClientConfig) { followRedirects = other.followRedirects diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/call/HttpClientCall.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/call/HttpClientCall.kt index 22184f5f5c5..0dcc33229d3 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/call/HttpClientCall.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/call/HttpClientCall.kt @@ -21,6 +21,9 @@ import kotlin.reflect.* /** * A pair of a [request] and [response] for a specific [HttpClient]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.call.HttpClientCall) + * * @property client the client that executed the call. */ public open class HttpClientCall( @@ -32,17 +35,23 @@ public open class HttpClientCall( /** * Typed [Attributes] associated to this call serving as a lightweight container. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.call.HttpClientCall.attributes) */ public val attributes: Attributes get() = request.attributes /** * The [request] sent by the client. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.call.HttpClientCall.request) */ public lateinit var request: HttpRequest protected set /** * The [response] sent by the server. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.call.HttpClientCall.response) */ public lateinit var response: HttpResponse protected set @@ -70,6 +79,9 @@ public open class HttpClientCall( * Tries to receive the payload of the [response] as a specific expected type provided in [info]. * Returns [response] if [info] corresponds to [HttpResponse]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.call.HttpClientCall.bodyNullable) + * * @throws NoTransformationFoundException If no transformation is found for the type [info]. * @throws DoubleReceiveException If already called [body]. */ @@ -102,6 +114,9 @@ public open class HttpClientCall( * Tries to receive the payload of the [response] as a specific expected type provided in [info]. * Returns [response] if [info] corresponds to [HttpResponse]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.call.HttpClientCall.body) + * * @throws NoTransformationFoundException If no transformation is found for the type [info]. * @throws DoubleReceiveException If already called [body]. * @throws NullPointerException If content is `null`. @@ -126,6 +141,9 @@ public open class HttpClientCall( /** * Tries to receive the payload of the [response] as a specific type [T]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.call.body) + * * @throws NoTransformationFoundException If no transformation is found for the type [T]. * @throws DoubleReceiveException If already called [body]. */ @@ -134,6 +152,9 @@ public suspend inline fun HttpClientCall.body(): T = bodyNullable(ty /** * Tries to receive the payload of the [response] as a specific type [T]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.call.body) + * * @throws NoTransformationFoundException If no transformation is found for the type [T]. * @throws DoubleReceiveException If already called [body]. */ @@ -142,6 +163,9 @@ public suspend inline fun HttpResponse.body(): T = call.bodyNullable /** * Tries to receive the payload of the [response] as a specific type [T] described in [typeInfo]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.call.body) + * * @throws NoTransformationFoundException If no transformation is found for the type info [typeInfo]. * @throws DoubleReceiveException If already called [body]. */ @@ -150,6 +174,8 @@ public suspend fun HttpResponse.body(typeInfo: TypeInfo): T = call.bodyNulla /** * Exception representing that the response payload has already been received. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.call.DoubleReceiveException) */ public class DoubleReceiveException(call: HttpClientCall) : IllegalStateException() { @@ -159,6 +185,8 @@ public class DoubleReceiveException(call: HttpClientCall) : IllegalStateExceptio /** * Exception representing fail of the response pipeline * [cause] contains origin pipeline exception + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.call.ReceivePipelineException) */ @Suppress("KDocMissingDocumentation", "unused") public class ReceivePipelineException( @@ -172,6 +200,8 @@ public class ReceivePipelineException( * the resulted type to the expected by the client type. * * You can read how to resolve NoTransformationFoundException at [FAQ](https://ktor.io/docs/faq.html#no-transformation-found-exception) + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.call.NoTransformationFoundException) */ public class NoTransformationFoundException( response: HttpResponse, diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/call/SavedCall.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/call/SavedCall.kt index fffe1eaeab3..298eb94725e 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/call/SavedCall.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/call/SavedCall.kt @@ -26,6 +26,9 @@ import kotlin.coroutines.CoroutineContext * This behavior is automatically applied to non-streaming [HttpResponse] instances. * For streaming responses, this function allows you to convert them into a memory-based representation. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.call.save) + * * @return A new [HttpClientCall] instance with all its content stored in memory. */ @OptIn(InternalAPI::class) diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/call/utils.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/call/utils.kt index 3a65bc41b17..f4568b1b564 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/call/utils.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/call/utils.kt @@ -10,6 +10,8 @@ import io.ktor.http.content.* /** * Exception thrown when the engine does not support the content type of the HTTP request body. * For instance, some engines do not support upgrade requests. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.call.UnsupportedContentTypeException) */ public class UnsupportedContentTypeException(content: OutgoingContent) : IllegalStateException("Failed to write body: ${content::class}") diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/content/ObservableContent.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/content/ObservableContent.kt index f8ca3315787..c2489e9f67a 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/content/ObservableContent.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/content/ObservableContent.kt @@ -20,11 +20,16 @@ import kotlin.coroutines.CoroutineContext * Callback that can be registered to listen for upload/download progress. * * This class is used for callbacks in [HttpRequestBuilder.onDownload] and [HttpRequestBuilder.onUpload]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.content.ProgressListener) */ public fun interface ProgressListener { /** * Invokes every time some data is flushed through the [ByteReadChannel]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.content.ProgressListener.onProgress) + * * @param bytesSentTotal number of transmitted bytes. * @param contentLength body size. Can be null if the size is unknown. */ diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/engine/HttpClientEngine.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/engine/HttpClientEngine.kt index 644c7dd413e..d33cfa5f1df 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/engine/HttpClientEngine.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/engine/HttpClientEngine.kt @@ -30,6 +30,8 @@ internal val CLIENT_CONFIG = AttributeKey>("client-config") * contract for configuring, executing, and managing HTTP requests within the engine. * * For a base implementation that handles common engine functionality, see [HttpClientEngineBase]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.HttpClientEngine) */ public interface HttpClientEngine : CoroutineScope, Closeable { /** @@ -43,6 +45,8 @@ public interface HttpClientEngine : CoroutineScope, Closeable { * ```kotlin * override val dispatcher: CoroutineDispatcher = Dispatchers.IO * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.HttpClientEngine.dispatcher) */ public val dispatcher: CoroutineDispatcher @@ -57,6 +61,8 @@ public interface HttpClientEngine : CoroutineScope, Closeable { * ```kotlin * override val config: HttpClientEngineConfig = CustomEngineConfig() * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.HttpClientEngine.config) */ public val config: HttpClientEngineConfig @@ -92,6 +98,8 @@ public interface HttpClientEngine : CoroutineScope, Closeable { * * When implementing a custom engine, ensure this property accurately reflects * the engine's abilities to avoid unexpected plugin behavior or runtime errors. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.HttpClientEngine.supportedCapabilities) */ public val supportedCapabilities: Set> get() = emptySet() @@ -105,6 +113,9 @@ public interface HttpClientEngine : CoroutineScope, Closeable { * This function takes [HttpRequestData], which contains all details of the HTTP request, * and returns [HttpResponseData] with the server's response, including headers, status code, and body. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.HttpClientEngine.execute) + * * @param data The [HttpRequestData] representing the request to be executed. * @return An [HttpResponseData] object containing the server's response. */ @@ -118,6 +129,9 @@ public interface HttpClientEngine : CoroutineScope, Closeable { * Use it to register interceptors, validate configuration, or prepare the engine * for use with the client. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.HttpClientEngine.install) + * * @param client The [HttpClient] instance to which the engine is being installed. */ @InternalAPI @@ -180,6 +194,8 @@ public interface HttpClientEngine : CoroutineScope, Closeable { /** * Creates a new [HttpClientEngineFactory] based on this one * with further configurations from the [nested] block. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.config) */ public fun HttpClientEngineFactory.config( nested: T.() -> Unit diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/engine/HttpClientEngineBase.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/engine/HttpClientEngineBase.kt index 14ca79b3887..31e06fee51f 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/engine/HttpClientEngineBase.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/engine/HttpClientEngineBase.kt @@ -22,6 +22,9 @@ import kotlin.coroutines.* * Developers creating custom HTTP client engines are encouraged to use this class as their parent, * as it handles much of the boilerplate related to engine lifecycle and coroutine management. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.HttpClientEngineBase) + * * @param engineName The name of the engine, used for debugging and context naming. * * Example: @@ -53,6 +56,8 @@ public abstract class HttpClientEngineBase(private val engineName: String) : Htt /** * An exception indicating that the client's engine is already closed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.ClientEngineClosedException) */ public class ClientEngineClosedException(override val cause: Throwable? = null) : IllegalStateException("Client already closed") diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/engine/HttpClientEngineCapability.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/engine/HttpClientEngineCapability.kt index 61fcf979cf7..3afbb3fa609 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/engine/HttpClientEngineCapability.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/engine/HttpClientEngineCapability.kt @@ -15,6 +15,8 @@ internal val ENGINE_CAPABILITIES_KEY = /** * Default capabilities expected to be supported by engine. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.DEFAULT_CAPABILITIES) */ public val DEFAULT_CAPABILITIES: Set> = setOf(HttpTimeoutCapability) @@ -30,6 +32,9 @@ public val DEFAULT_CAPABILITIES: Set> = setOf(Http * Capabilities can be set on a per-request basis using the `HttpRequestBuilder.setCapability` method, * allowing users to configure engine-specific behavior for individual requests. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.HttpClientEngineCapability) + * * @param T The type of the configuration or metadata associated with this capability. * * Example: diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/engine/HttpClientEngineConfig.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/engine/HttpClientEngineConfig.kt index 7bbacdb2714..4e3df391b2a 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/engine/HttpClientEngineConfig.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/engine/HttpClientEngineConfig.kt @@ -9,11 +9,15 @@ import kotlinx.coroutines.* /** * Base configuration for [HttpClientEngine]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.HttpClientEngineConfig) */ @KtorDsl public open class HttpClientEngineConfig { /** * Specifies network threads count advice. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.HttpClientEngineConfig.threadsCount) */ @Deprecated( "The [threadsCount] property is deprecated. Consider setting [dispatcher] instead.", @@ -23,11 +27,15 @@ public open class HttpClientEngineConfig { /** * Allow specifying the coroutine dispatcher to use for IO operations. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.HttpClientEngineConfig.dispatcher) */ public var dispatcher: CoroutineDispatcher? = null /** * Enables HTTP pipelining advice. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.HttpClientEngineConfig.pipelining) */ public var pipelining: Boolean = false @@ -36,6 +44,8 @@ public open class HttpClientEngineConfig { * Uses a system proxy by default. * * You can learn more from [Proxy](https://ktor.io/docs/proxy.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.HttpClientEngineConfig.proxy) */ public var proxy: ProxyConfig? = null } diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/engine/HttpClientEngineFactory.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/engine/HttpClientEngineFactory.kt index e3f93d2090b..cb0931d1f6f 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/engine/HttpClientEngineFactory.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/engine/HttpClientEngineFactory.kt @@ -14,6 +14,9 @@ package io.ktor.client.engine * underlying engine that will handle HTTP requests. This allows users to seamlessly plug in different * engines based on their requirements, such as for performance, platform compatibility, or protocol support. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.HttpClientEngineFactory) + * * @param T The type of [HttpClientEngineConfig] used to configure the engine. * * Example: @@ -46,6 +49,9 @@ public interface HttpClientEngineFactory { * Typically, this method is invoked internally by the [io.ktor.client.HttpClient] constructor when the factory * is passed to it. Users can, however, call it directly to explicitly control engine instantiation. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.HttpClientEngineFactory.create) + * * @param block A lambda that applies additional configurations to the engine's [T] object. * @return An [HttpClientEngine] instance, which may be newly created or reused. * diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/engine/ProxyConfig.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/engine/ProxyConfig.kt index cd80d4b676c..e4c4ddf0e78 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/engine/ProxyConfig.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/engine/ProxyConfig.kt @@ -9,16 +9,22 @@ import io.ktor.util.network.* /** * A [proxy](https://ktor.io/docs/proxy.html) configuration. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.ProxyConfig) */ public expect class ProxyConfig /** * A type of the configured proxy. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.type) */ public expect val ProxyConfig.type: ProxyType /** * A [proxy](https://ktor.io/docs/proxy.html) type. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.ProxyType) */ @Suppress("NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "KDocMissingDocumentation") public enum class ProxyType { @@ -31,27 +37,38 @@ public enum class ProxyType { * Resolves a remote address of [ProxyConfig]. * * This operation can block. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.resolveAddress) */ public expect fun ProxyConfig.resolveAddress(): NetworkAddress /** * A [ProxyConfig] factory. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.ProxyBuilder) + * * @see [io.ktor.client.engine.HttpClientEngineConfig.proxy] */ public expect object ProxyBuilder { /** * Creates an HTTP proxy from [url]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.ProxyBuilder.http) */ public fun http(url: Url): ProxyConfig /** * Creates a socks proxy from [host] and [port]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.ProxyBuilder.socks) */ public fun socks(host: String, port: Int): ProxyConfig } /** * Creates an HTTP proxy from [urlString]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.http) */ public fun ProxyBuilder.http(urlString: String): ProxyConfig = http(Url(urlString)) diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/engine/Utils.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/engine/Utils.kt index c5d4f742c51..0f3352d2f89 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/engine/Utils.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/engine/Utils.kt @@ -14,6 +14,8 @@ import kotlin.coroutines.* /** * Default user agent to use in a Ktor client. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.KTOR_DEFAULT_USER_AGENT) */ @InternalAPI public val KTOR_DEFAULT_USER_AGENT: String = "ktor-client" @@ -28,6 +30,8 @@ private val DATE_HEADERS = setOf( /** * Merge headers from [content] and [requestHeaders] according to [OutgoingContent] properties + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.mergeHeaders) */ @InternalAPI public fun mergeHeaders( @@ -72,6 +76,8 @@ public fun mergeHeaders( /** * Returns current call context if exists, otherwise null. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.callContext) */ @InternalAPI public suspend fun callContext(): CoroutineContext = coroutineContext[KtorCallContextElement]!!.callContext diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/network/sockets/TimeoutExceptions.common.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/network/sockets/TimeoutExceptions.common.kt index 29665b28f15..44b0da9a434 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/network/sockets/TimeoutExceptions.common.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/network/sockets/TimeoutExceptions.common.kt @@ -8,6 +8,8 @@ import kotlinx.io.IOException /** * This exception is thrown in case connect timeout exceeded. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.network.sockets.ConnectTimeoutException) */ public expect class ConnectTimeoutException(message: String, cause: Throwable? = null) : IOException @@ -15,6 +17,8 @@ public expect open class InterruptedIOException : IOException /** * This exception is thrown in case socket timeout (read or write) exceeded. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.network.sockets.SocketTimeoutException) */ public expect class SocketTimeoutException : InterruptedIOException diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/BodyProgress.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/BodyProgress.kt index 94160c3eb10..b05a07b92a9 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/BodyProgress.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/BodyProgress.kt @@ -25,6 +25,8 @@ private val DownloadProgressListenerAttributeKey = /** * Plugin that provides observable progress for uploads and downloads + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.BodyProgress) */ public val BodyProgress: ClientPlugin = createClientPlugin("BodyProgress") { @@ -74,6 +76,8 @@ internal fun HttpResponse.withObservableDownload(listener: ProgressListener): Ht /** * Registers listener to observe download progress. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.onDownload) */ public fun HttpRequestBuilder.onDownload(listener: ProgressListener?) { if (listener == null) { @@ -85,6 +89,8 @@ public fun HttpRequestBuilder.onDownload(listener: ProgressListener?) { /** * Registers listener to observe upload progress. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.onUpload) */ public fun HttpRequestBuilder.onUpload(listener: ProgressListener?) { if (listener == null) { diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/DataConversion.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/DataConversion.kt index dc723712d53..d9d5d58d35c 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/DataConversion.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/DataConversion.kt @@ -10,6 +10,8 @@ import io.ktor.util.converters.DataConversion /** * Object for installing [io.ktor.util.converters.DataConversion] as plugin + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.DataConversion) */ public object DataConversion : HttpClientPlugin { override val key: AttributeKey = AttributeKey("DataConversion") diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/DefaultRequest.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/DefaultRequest.kt index 52e14a4b682..81b219fc381 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/DefaultRequest.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/DefaultRequest.kt @@ -57,6 +57,8 @@ private val LOGGER = KtorSimpleLogger("io.ktor.client.plugins.DefaultRequest") * client.get("https://some.url") { HttpHeaders.ContentType = ContentType.Application.Xml } * // <- requests "https://some.url/", ContentType = Application.Xml * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.DefaultRequest) */ public class DefaultRequest private constructor(private val block: DefaultRequestBuilder.() -> Unit) { @@ -157,6 +159,8 @@ public class DefaultRequest private constructor(private val block: DefaultReques /** * Configuration object for [DefaultRequestBuilder] plugin + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.DefaultRequest.DefaultRequestBuilder) */ @KtorDsl public class DefaultRequestBuilder internal constructor() : HttpMessageBuilder { @@ -167,12 +171,16 @@ public class DefaultRequest private constructor(private val block: DefaultReques /** * Executes a [block] that configures the [URLBuilder] associated to this request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.DefaultRequest.DefaultRequestBuilder.url) */ public fun url(block: URLBuilder.() -> Unit): Unit = block(url) /** * Sets the [url] using the specified [scheme], [host], [port] and [path]. * Pass `null` to keep existing value in the [URLBuilder]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.DefaultRequest.DefaultRequestBuilder.url) */ public fun url( scheme: String? = null, @@ -186,6 +194,8 @@ public class DefaultRequest private constructor(private val block: DefaultReques /** * Sets the [HttpRequestBuilder.url] from [urlString]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.DefaultRequest.DefaultRequestBuilder.url) */ public fun url(urlString: String) { url.takeFrom(urlString) @@ -193,6 +203,8 @@ public class DefaultRequest private constructor(private val block: DefaultReques /** * Gets the associated URL's host. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.DefaultRequest.DefaultRequestBuilder.host) */ public var host: String get() = url.host @@ -202,6 +214,8 @@ public class DefaultRequest private constructor(private val block: DefaultReques /** * Gets the associated URL's port. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.DefaultRequest.DefaultRequestBuilder.port) */ public var port: Int get() = url.port @@ -211,6 +225,8 @@ public class DefaultRequest private constructor(private val block: DefaultReques /** * Sets attributes using [block]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.DefaultRequest.DefaultRequestBuilder.setAttributes) */ public fun setAttributes(block: Attributes.() -> Unit) { attributes.apply(block) @@ -220,6 +236,8 @@ public class DefaultRequest private constructor(private val block: DefaultReques /** * Set default request parameters. See [DefaultRequest] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.defaultRequest) */ public fun HttpClientConfig<*>.defaultRequest(block: DefaultRequest.DefaultRequestBuilder.() -> Unit) { install(DefaultRequest) { diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/DefaultResponseValidation.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/DefaultResponseValidation.kt index 0e5f740fd10..a258ed6b142 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/DefaultResponseValidation.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/DefaultResponseValidation.kt @@ -19,6 +19,8 @@ private val LOGGER = KtorSimpleLogger("io.ktor.client.plugins.DefaultResponseVal /** * Default response validation. * Check the response status code in range (0..299). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.addDefaultResponseValidation) */ public fun HttpClientConfig<*>.addDefaultResponseValidation() { HttpResponseValidator { @@ -65,6 +67,9 @@ private const val DEPRECATED_EXCEPTION_CTOR: String = "Please, provide response /** * Base for default response exceptions. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.ResponseException) + * * @param [response]: origin response */ public open class ResponseException( @@ -78,6 +83,8 @@ public open class ResponseException( /** * Unhandled redirect exception. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.RedirectResponseException) */ public class RedirectResponseException(response: HttpResponse, cachedResponseText: String) : ResponseException(response, cachedResponseText) { @@ -89,6 +96,8 @@ public class RedirectResponseException(response: HttpResponse, cachedResponseTex /** * Server error exception. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.ServerResponseException) */ public class ServerResponseException( response: HttpResponse, @@ -101,6 +110,8 @@ public class ServerResponseException( /** * Bad client request exception. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.ClientRequestException) */ public class ClientRequestException( response: HttpResponse, diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/DefaultTransform.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/DefaultTransform.kt index bdc67852b57..fb8101548b0 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/DefaultTransform.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/DefaultTransform.kt @@ -23,6 +23,8 @@ private val LOGGER = KtorSimpleLogger("io.ktor.client.plugins.defaultTransformer * Install default transformers. * Usually installed by default so there is no need to use it * unless you have disabled it via [HttpClientConfig.useDefaultTransformers]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.defaultTransformers) */ @OptIn(InternalAPI::class) public fun HttpClient.defaultTransformers() { diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/DoubleReceivePlugin.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/DoubleReceivePlugin.kt index 90be9943945..1e256643dd8 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/DoubleReceivePlugin.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/DoubleReceivePlugin.kt @@ -18,6 +18,8 @@ private val RESPONSE_BODY_SAVED = AttributeKey("ResponseBodySaved") /** * Configuration for [SaveBodyPlugin] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.SaveBodyPluginConfig) */ public class SaveBodyPluginConfig { /** @@ -29,6 +31,8 @@ public class SaveBodyPluginConfig { * skipSavingBody() * } * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.SaveBodyPluginConfig.disabled) */ public var disabled: Boolean = false } @@ -51,6 +55,8 @@ public class SaveBodyPluginConfig { * } * } * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.SaveBodyPlugin) */ @OptIn(InternalAPI::class) public val SaveBodyPlugin: ClientPlugin = createClientPlugin( @@ -87,6 +93,8 @@ public val HttpResponse.isSaved: Boolean * } * } * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.skipSavingBody) */ public fun HttpRequestBuilder.skipSavingBody() { attributes.put(SKIP_SAVE_BODY, Unit) diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpCallValidator.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpCallValidator.kt index 7b8968d9ccd..2bbb88c6454 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpCallValidator.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpCallValidator.kt @@ -21,6 +21,8 @@ private val LOGGER = KtorSimpleLogger("io.ktor.client.plugins.HttpCallValidator" /** * [HttpCallValidator] configuration. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpCallValidatorConfig) */ @KtorDsl public class HttpCallValidatorConfig { @@ -35,6 +37,8 @@ public class HttpCallValidatorConfig { /** * Add [CallRequestExceptionHandler]. * Last added handler executes first. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpCallValidatorConfig.handleResponseException) */ public fun handleResponseException(block: CallRequestExceptionHandler) { responseExceptionHandlers += RequestExceptionHandlerWrapper(block) @@ -43,6 +47,8 @@ public class HttpCallValidatorConfig { /** * Add [CallRequestExceptionHandler]. * Last added handler executes first. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpCallValidatorConfig.handleResponseExceptionWithRequest) */ public fun handleResponseExceptionWithRequest(block: CallRequestExceptionHandler) { responseExceptionHandlers += RequestExceptionHandlerWrapper(block) @@ -51,6 +57,8 @@ public class HttpCallValidatorConfig { /** * Add [ResponseValidator]. * Last added validator executes first. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpCallValidatorConfig.validateResponse) */ public fun validateResponse(block: ResponseValidator) { responseValidators += block @@ -61,16 +69,22 @@ public class HttpCallValidatorConfig { * Response validator method. * * You could throw an exception to fail the response. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.ResponseValidator) */ public typealias ResponseValidator = suspend (response: HttpResponse) -> Unit /** * Response exception handler method. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.CallExceptionHandler) */ public typealias CallExceptionHandler = suspend (cause: Throwable) -> Unit /** * Response exception handler method. [request] is null if + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.CallRequestExceptionHandler) */ public typealias CallRequestExceptionHandler = suspend (cause: Throwable, request: HttpRequest) -> Unit @@ -78,6 +92,8 @@ public typealias CallRequestExceptionHandler = suspend (cause: Throwable, reques * The response validator plugin is used for validating an [HttpClient] response and handling response exceptions. * * For more details, see [HttpCallValidatorConfig]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpCallValidator) */ public val HttpCallValidator: ClientPlugin = createClientPlugin( "HttpResponseValidator", @@ -168,6 +184,8 @@ private fun HttpRequest(builder: HttpRequestBuilder): HttpRequest = object : Htt /** * Install [HttpCallValidator] with [block] configuration. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpResponseValidator) */ @Suppress("FunctionName") public fun HttpClientConfig<*>.HttpResponseValidator(block: HttpCallValidatorConfig.() -> Unit) { @@ -176,6 +194,8 @@ public fun HttpClientConfig<*>.HttpResponseValidator(block: HttpCallValidatorCon /** * Terminate [HttpClient.receivePipeline] if status code is not successful (>=300). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.expectSuccess) */ public var HttpRequestBuilder.expectSuccess: Boolean get() = attributes.getOrNull(ExpectSuccessAttributeKey) ?: true diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpClientPlugin.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpClientPlugin.kt index cd083ded4f1..cb5e1f7b369 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpClientPlugin.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpClientPlugin.kt @@ -12,26 +12,36 @@ internal val PLUGIN_INSTALLED_LIST = AttributeKey("ApplicationPlugin /** * Base interface representing a [HttpClient] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpClientPlugin) */ public interface HttpClientPlugin { /** * The [AttributeKey] for this plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpClientPlugin.key) */ public val key: AttributeKey /** * Builds a [TPlugin] by calling the [block] with a [TConfig] config instance as receiver. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpClientPlugin.prepare) */ public fun prepare(block: TConfig.() -> Unit = {}): TPlugin /** * Installs the [plugin] class for a [HttpClient] defined at [scope]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpClientPlugin.install) */ public fun install(plugin: TPlugin, scope: HttpClient) } /** * Returns a [plugin] installed in this client. Returns `null` if the plugin was not previously installed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.pluginOrNull) */ public fun HttpClient.pluginOrNull(plugin: HttpClientPlugin): F? = attributes.getOrNull(PLUGIN_INSTALLED_LIST)?.getOrNull(plugin.key) @@ -39,6 +49,9 @@ public fun HttpClient.pluginOrNull(plugin: HttpClientPlugin HttpClient.plugin(plugin: HttpClientPlugin): F { diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpPlainText.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpPlainText.kt index b5d1a055e11..d3e9b34f51f 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpPlainText.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpPlainText.kt @@ -21,6 +21,8 @@ private val LOGGER = KtorSimpleLogger("io.ktor.client.plugins.HttpPlainText") /** * Charset configuration for [HttpPlainText] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpPlainTextConfig) */ @KtorDsl public class HttpPlainTextConfig { @@ -29,6 +31,8 @@ public class HttpPlainTextConfig { /** * Add [charset] to allowed list with selected [quality]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpPlainTextConfig.register) */ public fun register(charset: Charset, quality: Float? = null) { quality?.let { check(it in 0.0..1.0) } @@ -46,12 +50,16 @@ public class HttpPlainTextConfig { * Explicit [Charset] for sending content. * * Use first with the highest quality from [register] charset if null. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpPlainTextConfig.sendCharset) */ public var sendCharset: Charset? = null /** * Fallback charset for the response. * Use it if no charset specified. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpPlainTextConfig.responseCharsetFallback) */ public var responseCharsetFallback: Charset = Charsets.UTF_8 } @@ -61,6 +69,8 @@ public class HttpPlainTextConfig { * and processes the response body as [String]. * * To configure charsets set following properties in [HttpPlainText.Config]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpPlainText) */ public val HttpPlainText: ClientPlugin = createClientPlugin("HttpPlainText", ::HttpPlainTextConfig) { @@ -159,6 +169,8 @@ internal object RenderRequestHook : ClientHook.Charsets(block: HttpPlainTextConfig.() -> Unit) { diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpRedirect.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpRedirect.kt index 2d489535429..9c6ada1fbfd 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpRedirect.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpRedirect.kt @@ -20,6 +20,8 @@ private val LOGGER = KtorSimpleLogger("io.ktor.client.plugins.HttpRedirect") /** * Occurs when receiving a response with a redirect message. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpResponseRedirectEvent) */ public val HttpResponseRedirectEvent: EventDefinition = EventDefinition() @@ -31,11 +33,15 @@ public class HttpRedirectConfig { * Only [HttpMethod.Get] and [HttpMethod.Head] are allowed for implicit redirection. * * Please note: changing this flag could lead to security issues, consider changing the request URL instead. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpRedirectConfig.checkHttpMethod) */ public var checkHttpMethod: Boolean = true /** * `true` allows a client to make a redirect with downgrading from HTTPS to plain HTTP. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpRedirectConfig.allowHttpsDowngrade) */ public var allowHttpsDowngrade: Boolean = false } diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpRequestLifecycle.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpRequestLifecycle.kt index 17d5a199690..4c00fa2f815 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpRequestLifecycle.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpRequestLifecycle.kt @@ -15,6 +15,8 @@ private val LOGGER = KtorSimpleLogger("io.ktor.client.plugins.HttpRequestLifecyc /** * A client's HTTP plugin that sets up [HttpRequestBuilder.executionContext] and completes it when the pipeline is fully * processed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpRequestLifecycle) */ public val HttpRequestLifecycle: ClientPlugin = createClientPlugin("RequestLifecycle") { on(SetupRequestContext) { request, proceed -> diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpRequestRetry.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpRequestRetry.kt index e894f026ede..a9292282031 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpRequestRetry.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpRequestRetry.kt @@ -24,11 +24,15 @@ private val LOGGER = KtorSimpleLogger("io.ktor.client.plugins.HttpRequestRetry") /** * Occurs on request retry. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpRequestRetryEvent) */ public val HttpRequestRetryEvent: EventDefinition = EventDefinition() /** * Contains [HttpRequestRetry] configurations settings. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpRequestRetryConfig) */ @KtorDsl public class HttpRequestRetryConfig { @@ -39,24 +43,32 @@ public class HttpRequestRetryConfig { /** * Function that determines whether a request should be retried based on the response. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpRequestRetryConfig.retryIf) */ public val retryIf: (HttpRetryShouldRetryContext.(HttpRequest, HttpResponse) -> Boolean)? get() = if (::shouldRetry.isInitialized) shouldRetry else null /** * Function that determines whether a request should be retried based on the exception. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpRequestRetryConfig.retryOnExceptionIf) */ public val retryOnExceptionIf: (HttpRetryShouldRetryContext.(HttpRequestBuilder, Throwable) -> Boolean)? get() = if (::shouldRetryOnException.isInitialized) shouldRetryOnException else null /** * Indicated how the request should be modified before retrying. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpRequestRetryConfig.modifyRequest) */ public var modifyRequest: HttpRetryModifyRequestContext.(HttpRequestBuilder) -> Unit = {} private set /** * The maximum amount of retries to perform for a request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpRequestRetryConfig.maxRetries) */ public var maxRetries: Int = 0 @@ -67,6 +79,8 @@ public class HttpRequestRetryConfig { /** * Disables retry. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpRequestRetryConfig.noRetry) */ public fun noRetry() { maxRetries = 0 @@ -76,6 +90,8 @@ public class HttpRequestRetryConfig { /** * Modifies a request before retrying. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpRequestRetryConfig.modifyRequest) */ public fun modifyRequest(block: HttpRetryModifyRequestContext.(HttpRequestBuilder) -> Unit) { modifyRequest = block @@ -84,6 +100,8 @@ public class HttpRequestRetryConfig { /** * Specifies retry logic for a response. The [block] accepts [HttpRequest] and [HttpResponse] * and should return `true` if this request should be retried. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpRequestRetryConfig.retryIf) */ public fun retryIf( maxRetries: Int = -1, @@ -96,6 +114,8 @@ public class HttpRequestRetryConfig { /** * Specifies retry logic for failed requests. The [block] accepts [HttpRequestBuilder] * and [Throwable] and should return true if this request should be retried. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpRequestRetryConfig.retryOnExceptionIf) */ public fun retryOnExceptionIf( maxRetries: Int = -1, @@ -112,6 +132,8 @@ public class HttpRequestRetryConfig { * are not retried. * Set [retryOnTimeout] to `true` to retry on timeout. * Note, that in this case, [HttpTimeout] plugin should be installed after [HttpRequestRetry]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpRequestRetryConfig.retryOnException) */ public fun retryOnException(maxRetries: Int = -1, retryOnTimeout: Boolean = false) { retryOnExceptionIf(maxRetries) { _, cause -> @@ -126,6 +148,8 @@ public class HttpRequestRetryConfig { /** * Enables retrying a request if a 5xx response is received from a server * and specifies the number of retries. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpRequestRetryConfig.retryOnServerErrors) */ public fun retryOnServerErrors(maxRetries: Int = -1) { retryIf(maxRetries) { _, response -> @@ -136,6 +160,8 @@ public class HttpRequestRetryConfig { /** * Enables retrying a request if an exception is thrown during the [HttpSend] phase * or a 5xx response is received and specifies the number of retries. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpRequestRetryConfig.retryOnExceptionOrServerErrors) */ public fun retryOnExceptionOrServerErrors(maxRetries: Int = -1) { retryOnServerErrors(maxRetries) @@ -145,6 +171,8 @@ public class HttpRequestRetryConfig { /** * Specifies delay logic for retries. The [block] accepts the number of retries * and should return the number of milliseconds to wait before retrying. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpRequestRetryConfig.delayMillis) */ public fun delayMillis( respectRetryAfterHeader: Boolean = true, @@ -163,6 +191,8 @@ public class HttpRequestRetryConfig { /** * Specifies a constant delay between retries. * This delay equals to `millis + [0..randomizationMs]` milliseconds. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpRequestRetryConfig.constantDelay) */ public fun constantDelay( millis: Long = 1000, @@ -183,6 +213,8 @@ public class HttpRequestRetryConfig { * * For the defaults (base delay 1000ms, base 2), this results in 1000ms, 2000ms, 4000ms, 8000ms ... plus a random * value up to 1000ms. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpRequestRetryConfig.exponentialDelay) */ public fun exponentialDelay( base: Double = 2.0, @@ -205,6 +237,8 @@ public class HttpRequestRetryConfig { /** * A function that waits for the specified number of milliseconds. Uses [kotlinx.coroutines.delay] by default. * Useful for tests. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpRequestRetryConfig.delay) */ public fun delay(block: suspend (Long) -> Unit) { delay = block @@ -234,6 +268,8 @@ public class HttpRequestRetryConfig { * modifyRequest { it.headers.append("X_RETRY_COUNT", retryCount.toString()) } * } * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpRequestRetry) */ @Suppress("NAME_SHADOWING") public val HttpRequestRetry: ClientPlugin = createClientPlugin( @@ -342,6 +378,8 @@ public val HttpRequestRetry: ClientPlugin = createClient /** * A context for [HttpRequestRetry.Configuration.shouldRetry] * and [HttpRequestRetry.Configuration.shouldRetryOnException] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpRetryShouldRetryContext) */ public class HttpRetryShouldRetryContext( /** @@ -353,6 +391,8 @@ public class HttpRetryShouldRetryContext( /** * A context for [HttpRequestRetry.Configuration.delayMillis]. * Contains a non-null [response] or [cause] but not both. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpRetryDelayContext) */ public class HttpRetryDelayContext internal constructor( public val request: HttpRequestBuilder, @@ -363,6 +403,8 @@ public class HttpRetryDelayContext internal constructor( /** * A context for [HttpRequestRetry.Configuration.modifyRequest]. * Contains a non-null [response] or [cause] but not both. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpRetryModifyRequestContext) */ public class HttpRetryModifyRequestContext internal constructor( /** @@ -379,6 +421,8 @@ public class HttpRetryModifyRequestContext internal constructor( /** * Data for the [HttpRequestRetryEvent] event. Contains a non-null [response] or [cause] but not both. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpRetryEventData) */ public class HttpRetryEventData internal constructor( public val request: HttpRequestBuilder, @@ -389,6 +433,8 @@ public class HttpRetryEventData internal constructor( /** * Configures the [HttpRequestRetry] plugin on a per-request level. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.retry) */ public fun HttpRequestBuilder.retry(block: HttpRequestRetryConfig.() -> Unit) { val configuration = HttpRequestRetryConfig().apply(block) diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpSend.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpSend.kt index 652ea81c141..163940eb0c9 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpSend.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpSend.kt @@ -15,21 +15,29 @@ import kotlinx.coroutines.* /** * HttpSend pipeline interceptor function + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpSendInterceptor) */ public typealias HttpSendInterceptor = suspend Sender.(HttpRequestBuilder) -> HttpClientCall /** * This interface represents a request send pipeline interceptor chain + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.Sender) */ public interface Sender { /** * Execute send pipeline. It could start pipeline execution or replace the call + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.Sender.execute) */ public suspend fun execute(requestBuilder: HttpRequestBuilder): HttpClientCall } /** * This is an internal plugin that is always installed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpSend) */ public class HttpSend private constructor( private val maxSendCount: Int = 20 @@ -39,6 +47,8 @@ public class HttpSend private constructor( public class Config { /** * Maximum number of requests that can be sent during a call + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpSend.Config.maxSendCount) */ public var maxSendCount: Int = 20 } @@ -47,6 +57,8 @@ public class HttpSend private constructor( /** * Install send pipeline starter interceptor + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpSend.intercept) */ public fun intercept(block: HttpSendInterceptor) { interceptors += block @@ -54,6 +66,8 @@ public class HttpSend private constructor( /** * A plugin's installation object + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpSend.Plugin) */ public companion object Plugin : HttpClientPlugin { override val key: AttributeKey = AttributeKey("HttpSend") @@ -133,5 +147,7 @@ public class HttpSend private constructor( * Thrown when too many actual requests were sent during a client call. * It could be caused by infinite or too long redirect sequence. * Maximum number of requests is limited by [HttpSend.maxSendCount] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.SendCountExceedException) */ public class SendCountExceedException(message: String) : IllegalStateException(message) diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpTimeout.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpTimeout.kt index f4854ee41ff..0b10a70e314 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpTimeout.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpTimeout.kt @@ -24,6 +24,8 @@ private val LOGGER = KtorSimpleLogger("io.ktor.client.plugins.HttpTimeout") /** * An [HttpTimeout] extension configuration that is used during installation. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpTimeoutConfig) */ @KtorDsl public class HttpTimeoutConfig { @@ -34,6 +36,8 @@ public class HttpTimeoutConfig { /** * Creates a new instance of [HttpTimeoutConfig]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpTimeoutConfig.HttpTimeoutConfig) */ public constructor( requestTimeoutMillis: Long? = null, @@ -49,6 +53,8 @@ public class HttpTimeoutConfig { * Specifies a request timeout in milliseconds. * The request timeout is the time period required to process an HTTP call: from sending a request to receiving a * response. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpTimeoutConfig.requestTimeoutMillis) */ public var requestTimeoutMillis: Long? get() = _requestTimeoutMillis @@ -59,6 +65,8 @@ public class HttpTimeoutConfig { /** * Specifies a connection timeout in milliseconds. * The connection timeout is the time period in which a client should establish a connection with a server. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpTimeoutConfig.connectTimeoutMillis) */ public var connectTimeoutMillis: Long? get() = _connectTimeoutMillis @@ -69,6 +77,8 @@ public class HttpTimeoutConfig { /** * Specifies a socket timeout (read and write) in milliseconds. * The socket timeout is the maximum time of inactivity between two data packets when exchanging data with a server. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpTimeoutConfig.socketTimeoutMillis) */ public var socketTimeoutMillis: Long? get() = _socketTimeoutMillis @@ -119,6 +129,8 @@ public data object HttpTimeoutCapability : HttpClientEngineCapability = createClientPlugin( @@ -178,6 +190,8 @@ public val HttpTimeout: ClientPlugin = createClientPlugin( /** * Adds timeout boundaries to the request. Requires the [HttpTimeout] plugin to be installed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.timeout) */ public fun HttpRequestBuilder.timeout(block: HttpTimeoutConfig.() -> Unit): Unit = setCapability(HttpTimeoutCapability, HttpTimeoutConfig().apply(block)) @@ -186,6 +200,8 @@ public fun HttpRequestBuilder.timeout(block: HttpTimeoutConfig.() -> Unit): Unit * This exception is thrown in case the request timeout is exceeded. * The request timeout is the time period required to process an HTTP call: from sending a request to receiving * a response. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.HttpRequestTimeoutException) */ @OptIn(ExperimentalCoroutinesApi::class) public class HttpRequestTimeoutException( @@ -213,6 +229,8 @@ public class HttpRequestTimeoutException( /** * This exception is thrown in case the connection timeout is exceeded. * It indicates the client took too long to establish a connection with a server. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.ConnectTimeoutException) */ public fun ConnectTimeoutException( request: HttpRequestData, @@ -226,6 +244,8 @@ public fun ConnectTimeoutException( /** * This exception is thrown in case the connection timeout is exceeded. * It indicates the client took too long to establish a connection with a server. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.ConnectTimeoutException) */ public fun ConnectTimeoutException( url: String, @@ -239,6 +259,8 @@ public fun ConnectTimeoutException( /** * This exception is thrown in case the socket timeout (read or write) is exceeded. * It indicates the time between two data packets when exchanging data with a server was too long. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.SocketTimeoutException) */ public fun SocketTimeoutException( request: HttpRequestData, @@ -254,6 +276,8 @@ public fun SocketTimeoutException( /** * Converts a long timeout in milliseconds to int value. To do that, we need to consider [HttpTimeout.INFINITE_TIMEOUT_MS] * as zero and convert timeout value to [Int]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.convertLongTimeoutToIntWithInfiniteAsZero) */ @InternalAPI public fun convertLongTimeoutToIntWithInfiniteAsZero(timeout: Long): Int = when { @@ -266,6 +290,8 @@ public fun convertLongTimeoutToIntWithInfiniteAsZero(timeout: Long): Int = when /** * Converts long timeout in milliseconds to long value. To do that, we need to consider [HttpTimeout.INFINITE_TIMEOUT_MS] * as zero and convert timeout value to [Int]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.convertLongTimeoutToLongWithInfiniteAsZero) */ @InternalAPI public fun convertLongTimeoutToLongWithInfiniteAsZero(timeout: Long): Long = when (timeout) { diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/UserAgent.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/UserAgent.kt index 98e30d59ff4..7a374e7b79b 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/UserAgent.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/UserAgent.kt @@ -20,6 +20,9 @@ public class UserAgentConfig(public var agent: String = "Ktor http-client") /** * A plugin that adds a `User-Agent` header to all requests. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.UserAgent) + * * @property agent a `User-Agent` header value. */ public val UserAgent: ClientPlugin = createClientPlugin("UserAgent", ::UserAgentConfig) { @@ -34,6 +37,8 @@ public val UserAgent: ClientPlugin = createClientPlugin("UserAg /** * Installs the [UserAgent] plugin with a browser-like user agent. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.BrowserUserAgent) */ @Suppress("FunctionName") public fun HttpClientConfig<*>.BrowserUserAgent() { @@ -45,6 +50,8 @@ public fun HttpClientConfig<*>.BrowserUserAgent() { /** * Installs the [UserAgent] plugin with a CURL user agent. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.CurlUserAgent) */ @Suppress("FunctionName") public fun HttpClientConfig<*>.CurlUserAgent() { diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/api/ClientHook.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/api/ClientHook.kt index bf44a38bf4d..9e48484c6ee 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/api/ClientHook.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/api/ClientHook.kt @@ -9,12 +9,16 @@ import io.ktor.utils.io.* /** * A hook that can be registered in [ClientPluginBuilder]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.api.ClientHook) */ @KtorDsl public interface ClientHook { /** * Specifies how to install a hook into [client]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.api.ClientHook.install) */ public fun install(client: HttpClient, handler: HookHandler) } diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/api/ClientPluginBuilder.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/api/ClientPluginBuilder.kt index f7aaa24382c..08104ef94e3 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/api/ClientPluginBuilder.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/api/ClientPluginBuilder.kt @@ -17,6 +17,8 @@ import io.ktor.utils.io.* /** * An utility class used to build a [ClientPlugin] instance. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.api.ClientPluginBuilder) **/ @KtorDsl public class ClientPluginBuilder internal constructor( @@ -40,6 +42,9 @@ public class ClientPluginBuilder internal constructor( * This block is invoked for every [HttpClient.request] call. * There you can modify the request in a way you want: add headers, configure logging, etc. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.api.ClientPluginBuilder.onRequest) + * * @see [createClientPlugin] * * @param block An action that needs to be executed when a client creates an HTTP request. @@ -56,6 +61,9 @@ public class ClientPluginBuilder internal constructor( * This block is invoked for every incoming response. * There you can inspect the response in a way you want: save cookies, add logging, etc. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.api.ClientPluginBuilder.onResponse) + * * @see [createClientPlugin] * * @param block An action that needs to be executed when a client receives an HTTP response. @@ -72,6 +80,9 @@ public class ClientPluginBuilder internal constructor( * This block is invoked for every [HttpClient.request] call. * Here you should serialize body into [OutgoingContent] or return `null` if your transformation is not applicable. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.api.ClientPluginBuilder.transformRequestBody) + * * @see [createClientPlugin] * * @param block A transformation of request body. @@ -93,6 +104,9 @@ public class ClientPluginBuilder internal constructor( * Here you should deserialize body into an instance of [requestedType] * or return `null` if your transformation is not applicable. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.api.ClientPluginBuilder.transformResponseBody) + * * @see [createClientPlugin] * * @param block A transformation of response body. @@ -109,6 +123,8 @@ public class ClientPluginBuilder internal constructor( /** * Specifies the [block] to clean resources allocated with this plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.api.ClientPluginBuilder.onClose) */ public fun onClose(block: () -> Unit) { onClose = block @@ -119,6 +135,9 @@ public class ClientPluginBuilder internal constructor( * A [hook] can be a specific place in time or event during the request * processing like receiving a response, an exception during call processing, etc. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.api.ClientPluginBuilder.on) + * * @see [createClientPlugin] */ public fun on( diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/api/ClientPluginInstance.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/api/ClientPluginInstance.kt index 21fdf9fdd47..21383234414 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/api/ClientPluginInstance.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/api/ClientPluginInstance.kt @@ -11,6 +11,8 @@ import io.ktor.utils.io.core.* /** * An instance of [ClientPlugin] that can be installed into [HttpClient]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.api.ClientPluginInstance) */ public class ClientPluginInstance internal constructor( private val key: AttributeKey>, diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/api/CommonHooks.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/api/CommonHooks.kt index cf599a12af4..de3ffe354c5 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/api/CommonHooks.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/api/CommonHooks.kt @@ -15,6 +15,8 @@ import kotlin.coroutines.* /** * A hook that executes first in request processing. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.api.SetupRequest) */ public object SetupRequest : ClientHook Unit> { override fun install(client: HttpClient, handler: suspend (HttpRequestBuilder) -> Unit) { @@ -27,6 +29,8 @@ public object SetupRequest : ClientHook Unit> { /** * A hook that can inspect response and initiate additional requests if needed. * Useful for handling redirects, retries, authentication, etc. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.api.Send) */ public object Send : ClientHook HttpClientCall> { @@ -36,6 +40,8 @@ public object Send : ClientHook Http ) : CoroutineScope { /** * Continues execution of the request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.api.Send.Sender.proceed) */ public suspend fun proceed(requestBuilder: HttpRequestBuilder): HttpClientCall = httpSendSender.execute(requestBuilder) @@ -53,6 +59,8 @@ public object Send : ClientHook Http * For example, if a request results in redirect, * [ClientPluginBuilder.onRequest] will be executed only for the original request, * but this hook will be executed for both original and redirected requests. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.api.SendingRequest) */ public object SendingRequest : ClientHook Unit> { @@ -69,6 +77,8 @@ public object SendingRequest : /** * A shortcut hook for [HttpClient.monitor] subscription. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.api.MonitoringEvent) */ public class MonitoringEvent>(private val event: Event) : ClientHook<(Param) -> Unit> { diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/api/CreatePluginUtils.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/api/CreatePluginUtils.kt index 47575b0ca5a..ee05692dff7 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/api/CreatePluginUtils.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/api/CreatePluginUtils.kt @@ -11,6 +11,8 @@ import io.ktor.utils.io.* /** * Client plugins factory. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.api.ClientPlugin) */ public interface ClientPlugin : HttpClientPlugin> @@ -38,6 +40,9 @@ public interface ClientPlugin : HttpClientPlugin( * client.install(CustomHeaderPlugin) * ``` * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.api.createClientPlugin) + * * @param name A name of a plugin that is used to get its instance. * @param body Allows you to define handlers ([onRequest], [onResponse], and so on) that * can modify the behaviour of an [HttpClient] where your plugin is installed. diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/api/KtorCallContexts.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/api/KtorCallContexts.kt index 46bf10e8307..790800b7df2 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/api/KtorCallContexts.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/api/KtorCallContexts.kt @@ -13,24 +13,32 @@ import io.ktor.utils.io.* /** * A context for [ClientPluginBuilder.onRequest] callback. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.api.OnRequestContext) */ @KtorDsl public class OnRequestContext internal constructor() /** * A context for [ClientPluginBuilder.onResponse] callback. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.api.OnResponseContext) */ @KtorDsl public class OnResponseContext internal constructor() /** * A context for [ClientPluginBuilder.transformRequestBody] callback. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.api.TransformRequestBodyContext) */ @KtorDsl public class TransformRequestBodyContext internal constructor() /** * A context for [ClientPluginBuilder.transformResponseBody] callback. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.api.TransformResponseBodyContext) */ @KtorDsl public class TransformResponseBodyContext internal constructor() diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cache/HttpCache.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cache/HttpCache.kt index 4e5fd5a57ca..dee1ef0a411 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cache/HttpCache.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cache/HttpCache.kt @@ -39,6 +39,8 @@ internal val LOGGER = KtorSimpleLogger("io.ktor.client.plugins.HttpCache") * the client executes only the first request and skips the second one since data is already saved in a cache. * * You can learn more from [Caching](https://ktor.io/docs/client-caching.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cache.HttpCache) */ public class HttpCache private constructor( @Deprecated( @@ -56,6 +58,8 @@ public class HttpCache private constructor( ) { /** * A configuration for the [HttpCache] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cache.HttpCache.Config) */ @KtorDsl public class Config { @@ -66,6 +70,8 @@ public class HttpCache private constructor( /** * Specifies if the client where this plugin is installed is shared among multiple users. * When set to true, all responses with `private` Cache-Control directive will not be cached. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cache.HttpCache.Config.isShared) */ public var isShared: Boolean = false @@ -73,6 +79,8 @@ public class HttpCache private constructor( * Specifies a storage for public cache entries. * * [HttpCacheStorage.Unlimited] by default. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cache.HttpCache.Config.publicStorage) */ @Deprecated( "This will become internal. Use setter method instead with new storage interface", @@ -91,6 +99,8 @@ public class HttpCache private constructor( * [HttpCacheStorage.Unlimited] by default. * * Consider using [HttpCacheStorage.Disabled] if the client is used as intermediate. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cache.HttpCache.Config.privateStorage) */ @Deprecated( "This will become internal. Use setter method instead with new storage interface", @@ -107,6 +117,8 @@ public class HttpCache private constructor( * Specifies a storage for public cache entries. * * [CacheStorage.Unlimited] by default. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cache.HttpCache.Config.publicStorage) */ public fun publicStorage(storage: CacheStorage) { publicStorageNew = storage @@ -118,6 +130,8 @@ public class HttpCache private constructor( * [CacheStorage.Unlimited] by default. * * Consider using [CacheStorage.Disabled] if the client is used as intermediate. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cache.HttpCache.Config.privateStorage) */ public fun privateStorage(storage: CacheStorage) { privateStorageNew = storage diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cache/HttpCacheEntry.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cache/HttpCacheEntry.kt index 0554b4557be..1645314aa5a 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cache/HttpCacheEntry.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cache/HttpCacheEntry.kt @@ -21,6 +21,8 @@ internal suspend fun HttpCacheEntry(isShared: Boolean, response: HttpResponse): /** * Client single response cache with [expires] and [varyKeys]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cache.HttpCacheEntry) */ public class HttpCacheEntry internal constructor( public val expires: GMTDate, diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cache/storage/HttpCacheStorage.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cache/storage/HttpCacheStorage.kt index c30d2108fda..a5ba93990a2 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cache/storage/HttpCacheStorage.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cache/storage/HttpCacheStorage.kt @@ -21,6 +21,8 @@ import kotlin.coroutines.* /** * Cache storage interface. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cache.storage.HttpCacheStorage) */ @Deprecated("Use new [CacheStorage] instead.", level = DeprecationLevel.ERROR) @Suppress("DEPRECATION_ERROR") @@ -28,27 +30,37 @@ public abstract class HttpCacheStorage { /** * Store [value] in cache storage for [url] key. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cache.storage.HttpCacheStorage.store) */ public abstract fun store(url: Url, value: HttpCacheEntry) /** * Find valid entry in cache storage with additional [varyKeys]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cache.storage.HttpCacheStorage.find) */ public abstract fun find(url: Url, varyKeys: Map): HttpCacheEntry? /** * Find all matched [HttpCacheEntry] for [url]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cache.storage.HttpCacheStorage.findByUrl) */ public abstract fun findByUrl(url: Url): Set public companion object { /** * Default unlimited cache storage. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cache.storage.HttpCacheStorage.Companion.Unlimited) */ public val Unlimited: () -> HttpCacheStorage = { UnlimitedCacheStorage() } /** * Disabled cache always empty and store nothing. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cache.storage.HttpCacheStorage.Companion.Disabled) */ public val Disabled: HttpCacheStorage = DisabledCacheStorage } @@ -63,32 +75,44 @@ internal suspend fun HttpCacheStorage.store(url: Url, value: HttpResponse, isSha /** * Cache storage interface. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cache.storage.CacheStorage) */ public interface CacheStorage { /** * Store [value] in cache storage for [url] key. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cache.storage.CacheStorage.store) */ public suspend fun store(url: Url, data: CachedResponseData) /** * Find valid entry in cache storage with additional [varyKeys]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cache.storage.CacheStorage.find) */ public suspend fun find(url: Url, varyKeys: Map): CachedResponseData? /** * Find all matched [HttpCacheEntry] for [url]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cache.storage.CacheStorage.findAll) */ public suspend fun findAll(url: Url): Set public companion object { /** * Default unlimited cache storage. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cache.storage.CacheStorage.Companion.Unlimited) */ public val Unlimited: () -> CacheStorage = { UnlimitedStorage() } /** * Disabled cache always empty and store nothing. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cache.storage.CacheStorage.Companion.Disabled) */ public val Disabled: CacheStorage = DisabledStorage } @@ -96,6 +120,8 @@ public interface CacheStorage { /** * Store [response] in cache storage. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cache.storage.store) */ @Deprecated( message = "Please use method with `response.varyKeys()` and `isShared` arguments", @@ -108,6 +134,8 @@ public suspend fun CacheStorage.store(response: HttpResponse): CachedResponseDat /** * Store [response] with [varyKeys] in cache storage. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cache.storage.store) */ @OptIn(InternalAPI::class) public suspend fun CacheStorage.store( @@ -154,6 +182,8 @@ internal fun CachedResponseData.createResponse( /** * Cached representation of response + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cache.storage.CachedResponseData) */ public class CachedResponseData( public val url: Url, diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cookies/AcceptAllCookiesStorage.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cookies/AcceptAllCookiesStorage.kt index 60fe219bb3a..f176e8a6e00 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cookies/AcceptAllCookiesStorage.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cookies/AcceptAllCookiesStorage.kt @@ -12,6 +12,8 @@ import kotlin.math.* /** * [CookiesStorage] that stores all the cookies in an in-memory map. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cookies.AcceptAllCookiesStorage) */ public class AcceptAllCookiesStorage(private val clock: () -> Long = { getTimeMillis() }) : CookiesStorage { diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cookies/ConstantCookiesStorage.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cookies/ConstantCookiesStorage.kt index 00b3062871d..d047eeda521 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cookies/ConstantCookiesStorage.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cookies/ConstantCookiesStorage.kt @@ -8,6 +8,8 @@ import io.ktor.http.* /** * [CookiesStorage] that ignores [addCookie] and returns a list of specified [cookies] when constructed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cookies.ConstantCookiesStorage) */ public class ConstantCookiesStorage(vararg cookies: Cookie) : CookiesStorage { private val storage: List = cookies.map { it.fillDefaults(URLBuilder().build()) }.toList() diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cookies/CookiesStorage.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cookies/CookiesStorage.kt index 7c6d34582b2..96f39331e9a 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cookies/CookiesStorage.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cookies/CookiesStorage.kt @@ -10,21 +10,29 @@ import io.ktor.utils.io.core.* /** * A storage for [Cookie]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cookies.CookiesStorage) */ public interface CookiesStorage : Closeable { /** * Gets a map of [String] to [Cookie] for a specific host. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cookies.CookiesStorage.get) */ public suspend fun get(requestUrl: Url): List /** * Sets a [cookie] for the specified host. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cookies.CookiesStorage.addCookie) */ public suspend fun addCookie(requestUrl: Url, cookie: Cookie) } /** * Adds a [cookie] with the [urlString] key to storage. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cookies.addCookie) */ public suspend fun CookiesStorage.addCookie(urlString: String, cookie: Cookie) { addCookie(Url(urlString), cookie) @@ -32,6 +40,8 @@ public suspend fun CookiesStorage.addCookie(urlString: String, cookie: Cookie) { /** * Checks if [Cookie] matches [requestUrl]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cookies.matches) */ public fun Cookie.matches(requestUrl: Url): Boolean { val domain = domain?.toLowerCasePreservingASCIIRules()?.trimStart('.') @@ -64,6 +74,8 @@ public fun Cookie.matches(requestUrl: Url): Boolean { /** * Fills [Cookie] with default values from [requestUrl]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cookies.fillDefaults) */ public fun Cookie.fillDefaults(requestUrl: Url): Cookie { var result = this diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cookies/HttpCookies.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cookies/HttpCookies.kt index 5302bdb1373..a7087b9233b 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cookies/HttpCookies.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cookies/HttpCookies.kt @@ -22,6 +22,8 @@ private val LOGGER = KtorSimpleLogger("io.ktor.client.plugins.HttpCookies") * By default, it uses an in-memory storage, but you can also implement a persistent storage using [CookiesStorage]. * * You can learn more from [Cookies](https://ktor.io/docs/http-cookies.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cookies.HttpCookies) */ public class HttpCookies internal constructor( private val storage: CookiesStorage, @@ -34,6 +36,8 @@ public class HttpCookies internal constructor( /** * Gets all the cookies associated with a specific [requestUrl]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cookies.HttpCookies.get) */ public suspend fun get(requestUrl: Url): List { initializer.join() @@ -85,6 +89,8 @@ public class HttpCookies internal constructor( /** * A configuration for the [HttpCookies] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cookies.HttpCookies.Config) */ @KtorDsl public class Config { @@ -93,12 +99,16 @@ public class HttpCookies internal constructor( /** * Specifies a storage used to keep cookies between calls. * By default, it uses an initially empty in-memory [AcceptAllCookiesStorage]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cookies.HttpCookies.Config.storage) */ public var storage: CookiesStorage = AcceptAllCookiesStorage() /** * Registers a [block] that will be called when the configuration is complete the specified [storage]. * The [block] can potentially add new cookies by calling [CookiesStorage.addCookie]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cookies.HttpCookies.Config.default) */ public fun default(block: suspend CookiesStorage.() -> Unit) { defaults.add(block) @@ -132,16 +142,22 @@ private fun renderClientCookies(cookies: List): String = /** * Gets all the cookies for the specified [url] for this [HttpClient]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cookies.cookies) */ public suspend fun HttpClient.cookies(url: Url): List = pluginOrNull(HttpCookies)?.get(url) ?: emptyList() /** * Gets all the cookies for the specified [urlString] for this [HttpClient]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cookies.cookies) */ public suspend fun HttpClient.cookies(urlString: String): List = pluginOrNull(HttpCookies)?.get(Url(urlString)) ?: emptyList() /** * Gets the specified [Cookie] by its [name]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cookies.get) */ public operator fun List.get(name: String): Cookie? = find { it.name == name } diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/internal/ByteChannelReplay.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/internal/ByteChannelReplay.kt index e156338bf44..47a94b8c1ed 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/internal/ByteChannelReplay.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/internal/ByteChannelReplay.kt @@ -90,5 +90,7 @@ internal class ByteChannelReplay(private val origin: ByteReadChannel) { /** * Thrown when a second attempt to read the body is made while the first call is blocked. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.internal.SaveBodyAbandonedReadException) */ public class SaveBodyAbandonedReadException : RuntimeException("Save body abandoned") diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/observer/DelegatedCall.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/observer/DelegatedCall.kt index 4890427355d..c0130e21175 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/observer/DelegatedCall.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/observer/DelegatedCall.kt @@ -16,6 +16,8 @@ import kotlin.coroutines.* /** * Wrap existing [HttpClientCall] with new [content]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.observer.wrapWithContent) */ public fun HttpClientCall.wrapWithContent(content: ByteReadChannel): HttpClientCall { return DelegatedCall(client, content, this) @@ -23,6 +25,8 @@ public fun HttpClientCall.wrapWithContent(content: ByteReadChannel): HttpClientC /** * Wrap existing [HttpClientCall] with new [content]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.observer.wrapWithContent) */ public fun HttpClientCall.wrapWithContent(block: () -> ByteReadChannel): HttpClientCall { return DelegatedCall(client, block, this) @@ -30,6 +34,8 @@ public fun HttpClientCall.wrapWithContent(block: () -> ByteReadChannel): HttpCli /** * Wrap existing [HttpClientCall] with new response [content] and [headers]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.observer.wrap) */ public fun HttpClientCall.wrap(content: ByteReadChannel, headers: Headers): HttpClientCall { return DelegatedCall(client, content, this, headers) diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/observer/ResponseObserver.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/observer/ResponseObserver.kt index 85f231043fe..de157b3b9b9 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/observer/ResponseObserver.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/observer/ResponseObserver.kt @@ -16,6 +16,8 @@ import kotlin.coroutines.* /** * [ResponseObserver] callback. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.observer.ResponseHandler) */ public typealias ResponseHandler = suspend (HttpResponse) -> Unit @@ -27,6 +29,8 @@ public class ResponseObserverConfig { /** * Set response handler for logging. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.observer.ResponseObserverConfig.onResponse) */ public fun onResponse(block: ResponseHandler) { responseHandler = block @@ -34,6 +38,8 @@ public class ResponseObserverConfig { /** * Set filter predicate to dynamically control if interceptor is executed or not for each http call. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.observer.ResponseObserverConfig.filter) */ public fun filter(block: ((HttpClientCall) -> Boolean)) { filter = block @@ -42,6 +48,8 @@ public class ResponseObserverConfig { /** * Observe response plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.observer.ResponseObserver) */ @OptIn(InternalAPI::class) public val ResponseObserver: ClientPlugin = createClientPlugin( @@ -90,6 +98,8 @@ internal expect suspend fun getResponseObserverContext(): CoroutineContext /** * Install [ResponseObserver] plugin in client. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.observer.ResponseObserver) */ @Suppress("FunctionName") public fun HttpClientConfig<*>.ResponseObserver(block: ResponseHandler) { diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/sse/ClientSSESession.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/sse/ClientSSESession.kt index 43287d5f361..f50e1327f52 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/sse/ClientSSESession.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/sse/ClientSSESession.kt @@ -26,6 +26,8 @@ import kotlinx.coroutines.flow.* * * To learn more, see [the SSE](https://en.wikipedia.org/wiki/Server-sent_events) * and [the SSE specification](https://html.spec.whatwg.org/multipage/server-sent-events.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.SSESession) */ public interface SSESession : CoroutineScope { /** @@ -37,6 +39,8 @@ public interface SSESession : CoroutineScope { * - [ServerSentEvent.id] event ID. * - [ServerSentEvent.retry] reconnection time, in milliseconds to wait before reconnecting. * - [ServerSentEvent.comments] comment lines starting with a ':' character. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.SSESession.incoming) */ public val incoming: Flow } @@ -68,6 +72,8 @@ public interface SSESession : CoroutineScope { * * To learn more, see [the SSE](https://en.wikipedia.org/wiki/Server-sent_events) * and [the SSE specification](https://html.spec.whatwg.org/multipage/server-sent-events.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.SSESessionWithDeserialization) */ public interface SSESessionWithDeserialization : CoroutineScope { /** @@ -80,11 +86,15 @@ public interface SSESessionWithDeserialization : CoroutineScope { * - [TypedServerSentEvent.id] event ID. * - [TypedServerSentEvent.retry] reconnection time, in milliseconds to wait before reconnecting. * - [TypedServerSentEvent.comments] comment lines starting with a ':' character. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.SSESessionWithDeserialization.incoming) */ public val incoming: Flow> /** * Deserializer for transforming the `data` field of a `ServerSentEvent` into a desired data object. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.SSESessionWithDeserialization.deserializer) */ public val deserializer: (TypeInfo, String) -> Any? } @@ -93,6 +103,9 @@ public interface SSESessionWithDeserialization : CoroutineScope { * Deserialize the provided [data] into an object of type [T] using the deserializer function * defined in the [SSESessionWithDeserialization] interface. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.deserialize) + * * @param data The string data to deserialize. * @return The deserialized object of type [T], or null if deserialization is not successful. * @@ -128,6 +141,9 @@ public inline fun SSESessionWithDeserialization.deserialize(data: St * Deserialize the provided [event] data into an object of type [T] using the deserializer function * defined in the [SSESessionWithDeserialization] interface. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.deserialize) + * * @param event The Server-sent event containing data to deserialize. * @return The deserialized object of type [T], or null if deserialization is not successful. * @@ -160,6 +176,9 @@ public inline fun SSESessionWithDeserialization.deserialize( /** * A client session for handling Server-Sent Events (SSE) from a server. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.ClientSSESession) + * * @property call The HTTP call associated with the session. * * Example of usage: @@ -181,6 +200,9 @@ public class ClientSSESession(public val call: HttpClientCall, delegate: SSESess /** * A client session with deserialization support for handling Server-Sent Events (SSE) from a server. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.ClientSSESessionWithDeserialization) + * * @property call The HTTP call associated with the session. * * Example of usage: diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/sse/SSE.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/sse/SSE.kt index e88b58c61ee..be08cd53c58 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/sse/SSE.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/sse/SSE.kt @@ -24,6 +24,8 @@ internal val LOGGER = KtorSimpleLogger("io.ktor.client.plugins.sse.SSE") /** * Indicates if a client engine supports Server-Sent Events (SSE). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.SSECapability) */ public data object SSECapability : HttpClientEngineCapability @@ -70,6 +72,8 @@ public data object SSECapability : HttpClientEngineCapability * * To learn more, see [the SSE](https://en.wikipedia.org/wiki/Server-sent_events) * and [the SSE specification](https://html.spec.whatwg.org/multipage/server-sent-events.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.SSE) */ @OptIn(InternalAPI::class) public val SSE: ClientPlugin = createClientPlugin( @@ -154,6 +158,8 @@ public val SSE: ClientPlugin = createClientPlugin( /** * Represents an exception which can be thrown during client SSE session. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.SSEClientException) */ public class SSEClientException( public val response: HttpResponse? = null, diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/sse/SSEConfig.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/sse/SSEConfig.kt index b84098f4f8d..51f67ebc6e8 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/sse/SSEConfig.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/sse/SSEConfig.kt @@ -9,6 +9,8 @@ import kotlin.time.Duration.Companion.milliseconds /** * A config for the [SSE] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.SSEConfig) */ public class SSEConfig { internal var showCommentEvents = false @@ -19,11 +21,15 @@ public class SSEConfig { * the client will wait for the specified time before attempting to reconnect. * * Note: this parameter is not supported for some engines. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.SSEConfig.reconnectionTime) */ public var reconnectionTime: Duration = 3000.milliseconds /** * Adds events consisting only of comments in the incoming flow. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.SSEConfig.showCommentEvents) */ public fun showCommentEvents() { showCommentEvents = true @@ -31,6 +37,8 @@ public class SSEConfig { /** * Adds events consisting only of the retry field in the incoming flow. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.SSEConfig.showRetryEvents) */ public fun showRetryEvents() { showRetryEvents = true diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/sse/builders.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/sse/builders.kt index 9795d418660..1f4c0ff1296 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/sse/builders.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/sse/builders.kt @@ -32,6 +32,8 @@ internal val deserializerAttr = AttributeKey<(TypeInfo, String) -> Any?>("SSEDes * } * } * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.SSE) */ @Suppress("FunctionName") public fun HttpClientConfig<*>.SSE(config: SSEConfig.() -> Unit) { @@ -45,6 +47,9 @@ public fun HttpClientConfig<*>.SSE(config: SSEConfig.() -> Unit) { /** * Opens a [ClientSSESession] to receive Server-Sent Events (SSE) from a server. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.serverSentEventsSession) + * * @param reconnectionTime The time duration to wait before attempting reconnection in case of connection loss * @param showCommentEvents When enabled, events containing only comments field will be presented in the incoming flow * @param showRetryEvents When enabled, events containing only comments field will be presented in the incoming flow @@ -71,6 +76,9 @@ public suspend fun HttpClient.serverSentEventsSession( /** * Opens a [ClientSSESession] to receive Server-Sent Events (SSE) from a server. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.serverSentEventsSession) + * * @param reconnectionTime The time duration to wait before attempting reconnection in case of connection loss * @param showCommentEvents When enabled, events containing only comments field will be presented in the incoming flow * @param showRetryEvents When enabled, events containing only comments field will be presented in the incoming flow @@ -104,6 +112,9 @@ public suspend fun HttpClient.serverSentEventsSession( /** * Opens a [ClientSSESession] to receive Server-Sent Events (SSE) from a server. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.serverSentEventsSession) + * * @param reconnectionTime The time duration to wait before attempting reconnection in case of connection loss * @param showCommentEvents When enabled, events containing only comments field will be presented in the incoming flow * @param showRetryEvents When enabled, events containing only comments field will be presented in the incoming flow @@ -134,6 +145,9 @@ public suspend fun HttpClient.serverSentEventsSession( /** * Opens a [ClientSSESession] to receive Server-Sent Events (SSE) from a server and performs [block]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.serverSentEvents) + * * @param reconnectionTime The time duration to wait before attempting reconnection in case of connection loss * @param showCommentEvents When enabled, events containing only comments field will be presented in the incoming flow * @param showRetryEvents When enabled, events containing only comments field will be presented in the incoming flow @@ -171,6 +185,9 @@ public suspend fun HttpClient.serverSentEvents( /** * Opens a [ClientSSESession] to receive Server-Sent Events (SSE) from a server and performs [block]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.serverSentEvents) + * * @param reconnectionTime The time duration to wait before attempting reconnection in case of connection loss * @param showCommentEvents When enabled, events containing only comments field will be presented in the incoming flow * @param showRetryEvents When enabled, events containing only comments field will be presented in the incoming flow @@ -212,6 +229,9 @@ public suspend fun HttpClient.serverSentEvents( /** * Opens a [ClientSSESession] to receive Server-Sent Events (SSE) from a server and performs [block]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.serverSentEvents) + * * @param reconnectionTime The time duration to wait before attempting reconnection in case of connection loss * @param showCommentEvents When enabled, events containing only comments field will be presented in the incoming flow * @param showRetryEvents When enabled, events containing only comments field will be presented in the incoming flow @@ -250,6 +270,9 @@ public suspend fun HttpClient.serverSentEvents( /** * Opens a [ClientSSESession] to receive Server-Sent Events (SSE) from a server. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.sseSession) + * * @param reconnectionTime The time duration to wait before attempting reconnection in case of connection loss * @param showCommentEvents When enabled, events containing only comments field will be presented in the incoming flow * @param showRetryEvents When enabled, events containing only comments field will be presented in the incoming flow @@ -276,6 +299,9 @@ public suspend fun HttpClient.sseSession( /** * Opens a [ClientSSESession] to receive Server-Sent Events (SSE) from a server. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.sseSession) + * * @param reconnectionTime The time duration to wait before attempting reconnection in case of connection loss * @param showCommentEvents When enabled, events containing only comments field will be presented in the incoming flow * @param showRetryEvents When enabled, events containing only comments field will be presented in the incoming flow @@ -307,6 +333,9 @@ public suspend fun HttpClient.sseSession( /** * Opens a [ClientSSESession] to receive Server-Sent Events (SSE) from a server. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.sseSession) + * * @param reconnectionTime The time duration to wait before attempting reconnection in case of connection loss * @param showCommentEvents When enabled, events containing only comments field will be presented in the incoming flow * @param showRetryEvents When enabled, events containing only comments field will be presented in the incoming flow @@ -334,6 +363,9 @@ public suspend fun HttpClient.sseSession( /** * Opens a [ClientSSESession] to receive Server-Sent Events (SSE) from a server and performs [block]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.sse) + * * @param reconnectionTime The time duration to wait before attempting reconnection in case of connection loss * @param showCommentEvents When enabled, events containing only comments field will be presented in the incoming flow * @param showRetryEvents When enabled, events containing only comments field will be presented in the incoming flow @@ -360,6 +392,9 @@ public suspend fun HttpClient.sse( /** * Opens a [ClientSSESession] to receive Server-Sent Events (SSE) from a server and performs [block]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.sse) + * * @param reconnectionTime The time duration to wait before attempting reconnection in case of connection loss * @param showCommentEvents When enabled, events containing only comments field will be presented in the incoming flow * @param showRetryEvents When enabled, events containing only comments field will be presented in the incoming flow @@ -391,6 +426,9 @@ public suspend fun HttpClient.sse( /** * Opens a [ClientSSESession] to receive Server-Sent Events (SSE) from a server and performs [block]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.sse) + * * @param reconnectionTime The time duration to wait before attempting reconnection in case of connection loss * @param showCommentEvents When enabled, events containing only comments field will be presented in the incoming flow * @param showRetryEvents When enabled, events containing only comments field will be presented in the incoming flow @@ -421,6 +459,9 @@ public suspend fun HttpClient.sse( * Opens a [ClientSSESessionWithDeserialization] to receive Server-Sent Events (SSE) from a server with ability to * deserialize the `data` field of the `TypedServerSentEvent`. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.serverSentEventsSession) + * * @param deserialize The deserializer function to transform the `data` field of the `TypedServerSentEvent` * into an object * @param reconnectionTime The time duration to wait before attempting reconnection in case of connection loss @@ -466,6 +507,9 @@ public suspend fun HttpClient.serverSentEventsSession( * Opens a [ClientSSESessionWithDeserialization] to receive Server-Sent Events (SSE) from a server with ability to * deserialize the `data` field of the `TypedServerSentEvent`. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.serverSentEventsSession) + * * @param deserialize The deserializer function to transform the `data` field of the `TypedServerSentEvent` * into an object * @param reconnectionTime The time duration to wait before attempting reconnection in case of connection loss @@ -514,6 +558,9 @@ public suspend fun HttpClient.serverSentEventsSession( * Opens a [ClientSSESessionWithDeserialization] to receive Server-Sent Events (SSE) from a server with ability to * deserialize the `data` field of the `TypedServerSentEvent`. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.serverSentEventsSession) + * * @param deserialize The deserializer function to transform the `data` field of the `TypedServerSentEvent` * into an object * @param reconnectionTime The time duration to wait before attempting reconnection in case of connection loss @@ -559,6 +606,9 @@ public suspend fun HttpClient.serverSentEventsSession( * Opens a [ClientSSESessionWithDeserialization] to receive Server-Sent Events (SSE) from a server with ability to * deserialize the `data` field of the `TypedServerSentEvent`. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.serverSentEvents) + * * @param deserialize The deserializer function to transform the `data` field of the `TypedServerSentEvent` * into an object * @param reconnectionTime The time duration to wait before attempting reconnection in case of connection loss @@ -611,6 +661,9 @@ public suspend fun HttpClient.serverSentEvents( * Opens a [ClientSSESessionWithDeserialization] to receive Server-Sent Events (SSE) from a server with ability to * deserialize the `data` field of the `TypedServerSentEvent` and performs [block]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.serverSentEvents) + * * @param deserialize The deserializer function to transform the `data` field of the `TypedServerSentEvent` * into an object * @param reconnectionTime The time duration to wait before attempting reconnection in case of connection loss @@ -668,6 +721,9 @@ public suspend fun HttpClient.serverSentEvents( * Opens a [ClientSSESessionWithDeserialization] to receive Server-Sent Events (SSE) from a server with ability to * deserialize the `data` field of the `TypedServerSentEvent` and performs [block]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.serverSentEvents) + * * @param deserialize The deserializer function to transform the `data` field of the `TypedServerSentEvent` * into an object * @param reconnectionTime The time duration to wait before attempting reconnection in case of connection loss @@ -722,6 +778,9 @@ public suspend fun HttpClient.serverSentEvents( * Opens a [ClientSSESessionWithDeserialization] to receive Server-Sent Events (SSE) from a server with ability to * deserialize the `data` field of the `TypedServerSentEvent` and performs [block]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.sseSession) + * * @param deserialize The deserializer function to transform the `data` field of the `TypedServerSentEvent` * into an object * @param reconnectionTime The time duration to wait before attempting reconnection in case of connection loss @@ -763,6 +822,9 @@ public suspend fun HttpClient.sseSession( * Opens a [ClientSSESessionWithDeserialization] to receive Server-Sent Events (SSE) from a server with ability to * deserialize the `data` field of the `TypedServerSentEvent` and performs [block]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.sseSession) + * * @param deserialize The deserializer function to transform the `data` field of the `TypedServerSentEvent` * into an object * @param reconnectionTime The time duration to wait before attempting reconnection in case of connection loss @@ -817,6 +879,9 @@ public suspend fun HttpClient.sseSession( * Opens a [ClientSSESessionWithDeserialization] to receive Server-Sent Events (SSE) from a server with ability to * deserialize the `data` field of the `TypedServerSentEvent` and performs [block]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.sseSession) + * * @param deserialize The deserializer function to transform the `data` field of the `TypedServerSentEvent` * into an object * @param reconnectionTime The time duration to wait before attempting reconnection in case of connection loss @@ -859,6 +924,9 @@ public suspend fun HttpClient.sseSession( * Opens a [ClientSSESessionWithDeserialization] to receive Server-Sent Events (SSE) from a server with ability to * deserialize the `data` field of the `TypedServerSentEvent` and performs [block]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.sse) + * * @param deserialize The deserializer function to transform the `data` field of the `TypedServerSentEvent` * into an object * @param reconnectionTime The time duration to wait before attempting reconnection in case of connection loss @@ -900,6 +968,9 @@ public suspend fun HttpClient.sse( * Opens a [ClientSSESessionWithDeserialization] to receive Server-Sent Events (SSE) from a server with ability to * deserialize the `data` field of the `TypedServerSentEvent` and performs [block]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.sse) + * * @param deserialize The deserializer function to transform the `data` field of the `TypedServerSentEvent` * into an object * @param reconnectionTime The time duration to wait before attempting reconnection in case of connection loss @@ -956,6 +1027,9 @@ public suspend fun HttpClient.sse( * Opens a [ClientSSESessionWithDeserialization] to receive Server-Sent Events (SSE) from a server with ability to * deserialize the `data` field of the `TypedServerSentEvent` and performs [block]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.sse.sse) + * * @param deserialize The deserializer function to transform the `data` field of the `TypedServerSentEvent` * into an object * @param reconnectionTime The time duration to wait before attempting reconnection in case of connection loss diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/websocket/ClientSessions.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/websocket/ClientSessions.kt index 2c53e461f79..795fa39c0dc 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/websocket/ClientSessions.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/websocket/ClientSessions.kt @@ -15,16 +15,22 @@ import io.ktor.websocket.serialization.* /** * Client specific [WebSocketSession]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.ClientWebSocketSession) */ public interface ClientWebSocketSession : WebSocketSession { /** * [HttpClientCall] associated with session. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.ClientWebSocketSession.call) */ public val call: HttpClientCall } /** * ClientSpecific [DefaultWebSocketSession]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.DefaultClientWebSocketSession) */ public class DefaultClientWebSocketSession( override val call: HttpClientCall, @@ -38,6 +44,8 @@ internal class DelegatingClientWebSocketSession( /** * Converter for web socket session + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.converter) */ public val DefaultClientWebSocketSession.converter: WebsocketContentConverter? get() = call.client.pluginOrNull(WebSockets)?.contentConverter @@ -49,6 +57,9 @@ public val DefaultClientWebSocketSession.converter: WebsocketContentConverter? * Frames sent after a Close frame are silently ignored. * Note that a Close frame could be sent automatically in reply to a peer's Close frame unless it is a raw WebSocket session. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.sendSerialized) + * * @param typeInfo Type info of [T]. Can be retrieved with [typeInfo] function. * * @throws WebsocketConverterNotFoundException if no [contentConverter] is found for the [WebSockets] plugin @@ -73,6 +84,9 @@ public suspend fun DefaultClientWebSocketSession.sendSerialized(data: Any?, type * Frames sent after a Close frame are silently ignored. * Note that a Close frame could be sent automatically in reply to a peer's Close frame unless it is a raw WebSocket session. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.sendSerialized) + * * @throws WebsocketConverterNotFoundException if no [contentConverter] is found for the [WebSockets] plugin */ public suspend inline fun DefaultClientWebSocketSession.sendSerialized(data: T) { @@ -86,6 +100,9 @@ public suspend inline fun DefaultClientWebSocketSession.sendSerializ * In this case, [WebsocketDeserializeException.frame] contains the received frame. * May throw [ClosedReceiveChannelException] if a channel was closed * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.receiveDeserialized) + * * @param typeInfo Type info of [T]. Can be retrieved with [typeInfo] function. * * @throws WebsocketConverterNotFoundException if no [contentConverter] is found for the [WebSockets] plugin @@ -111,6 +128,9 @@ public suspend fun DefaultClientWebSocketSession.receiveDeserialized(typeInf * In this case, [WebsocketDeserializeException.frame] contains the received frame. * May throw [ClosedReceiveChannelException] if a channel was closed * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.receiveDeserialized) + * * @throws WebsocketConverterNotFoundException if no [contentConverter] is found for the [WebSockets] plugin * @throws WebsocketDeserializeException if the received frame can't be deserialized to type [T] */ diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/websocket/Durations.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/websocket/Durations.kt index 63581d6a4df..c6ec8db41d5 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/websocket/Durations.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/websocket/Durations.kt @@ -11,6 +11,9 @@ import kotlin.time.Duration.Companion.milliseconds /** * Client WebSocket plugin. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.WebSockets) + * * @param pingInterval - interval between [FrameType.PING] messages. * @param maxFrameSize - max size of a single websocket frame. */ @@ -23,7 +26,11 @@ public fun WebSockets( extensionsConfig = WebSocketExtensionsConfig(), ) -/** Interval between [FrameType.PING] messages. */ +/** + * Interval between [FrameType.PING] messages. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.pingInterval) + */ public inline val WebSockets.pingInterval: Duration? get() = pingIntervalMillis.takeIf { it > PINGER_DISABLED }?.milliseconds @@ -31,6 +38,8 @@ public inline val WebSockets.pingInterval: Duration? * Sets interval of sending [FrameType.PING] messages. * * Use `null` to disable ping. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.pingInterval) */ public inline var WebSockets.Config.pingInterval: Duration? get() = pingIntervalMillis.takeIf { it > PINGER_DISABLED }?.milliseconds diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/websocket/WebSockets.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/websocket/WebSockets.kt index e413f4cd8aa..71d6e78dfad 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/websocket/WebSockets.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/websocket/WebSockets.kt @@ -23,17 +23,24 @@ internal val LOGGER = KtorSimpleLogger("io.ktor.client.plugins.websocket.WebSock /** * Indicates if a client engine supports WebSockets. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.WebSocketCapability) */ public data object WebSocketCapability : HttpClientEngineCapability /** * Indicates if a client engine supports extensions for WebSocket plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.WebSocketExtensionsCapability) */ public data object WebSocketExtensionsCapability : HttpClientEngineCapability /** * Client WebSocket plugin. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.WebSockets) + * * @property pingIntervalMillis - interval between [FrameType.PING] messages. * @property maxFrameSize - max size of a single websocket frame. * @property extensionsConfig - extensions configuration @@ -48,6 +55,9 @@ public class WebSockets internal constructor( /** * Client WebSocket plugin. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.WebSockets.WebSockets) + * * @property pingIntervalMillis - interval between [FrameType.PING] messages. * @property maxFrameSize - max size of a single websocket frame. */ @@ -58,6 +68,8 @@ public class WebSockets internal constructor( /** * Client WebSocket plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.WebSockets.WebSockets) */ public constructor() : this(PINGER_DISABLED, Int.MAX_VALUE.toLong(), WebSocketExtensionsConfig()) @@ -98,6 +110,8 @@ public class WebSockets internal constructor( /** * [WebSockets] configuration. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.WebSockets.Config) */ @KtorDsl public class Config { @@ -107,21 +121,29 @@ public class WebSockets internal constructor( * Sets interval of sending ping frames. * * Use [PINGER_DISABLED] to disable ping. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.WebSockets.Config.pingIntervalMillis) */ public var pingIntervalMillis: Long = PINGER_DISABLED /** * Sets maximum frame size in bytes. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.WebSockets.Config.maxFrameSize) */ public var maxFrameSize: Long = Int.MAX_VALUE.toLong() /** * A converter for serialization/deserialization + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.WebSockets.Config.contentConverter) */ public var contentConverter: WebsocketContentConverter? = null /** * Configure WebSocket extensions. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.WebSockets.Config.extensions) */ public fun extensions(block: WebSocketExtensionsConfig.() -> Unit) { extensionsConfig.apply(block) @@ -130,6 +152,8 @@ public class WebSockets internal constructor( /** * Add WebSockets support for ktor http client. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.WebSockets.Plugin) */ public companion object Plugin : HttpClientPlugin { override val key: AttributeKey = AttributeKey("Websocket") diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/websocket/builders.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/websocket/builders.kt index 12337c04fe6..0a468a2ae56 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/websocket/builders.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/websocket/builders.kt @@ -13,6 +13,8 @@ import kotlinx.coroutines.* /** * Installs the [WebSockets] plugin using the [config] as configuration. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.WebSockets) */ @Suppress("FunctionName") public fun HttpClientConfig<*>.WebSockets(config: WebSockets.Config.() -> Unit) { @@ -23,6 +25,8 @@ public fun HttpClientConfig<*>.WebSockets(config: WebSockets.Config.() -> Unit) /** * Opens a [DefaultClientWebSocketSession]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.webSocketSession) */ public suspend fun HttpClient.webSocketSession( block: HttpRequestBuilder.() -> Unit @@ -60,6 +64,8 @@ public suspend fun HttpClient.webSocketSession( /** * Opens a [DefaultClientWebSocketSession]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.webSocketSession) */ public suspend fun HttpClient.webSocketSession( method: HttpMethod = HttpMethod.Get, @@ -75,6 +81,8 @@ public suspend fun HttpClient.webSocketSession( /** * Opens a [DefaultClientWebSocketSession]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.webSocketSession) */ public suspend fun HttpClient.webSocketSession( urlString: String, @@ -86,6 +94,8 @@ public suspend fun HttpClient.webSocketSession( /** * Opens a [block] with [DefaultClientWebSocketSession]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.webSocket) */ public suspend fun HttpClient.webSocket( request: HttpRequestBuilder.() -> Unit, @@ -111,6 +121,8 @@ public suspend fun HttpClient.webSocket( /** * Opens a [block] with [DefaultClientWebSocketSession]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.webSocket) */ public suspend fun HttpClient.webSocket( method: HttpMethod = HttpMethod.Get, @@ -132,6 +144,8 @@ public suspend fun HttpClient.webSocket( /** * Opens a [block] with [DefaultClientWebSocketSession]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.webSocket) */ public suspend fun HttpClient.webSocket( urlString: String, @@ -156,6 +170,8 @@ public suspend fun HttpClient.webSocket( /** * Opens a [block] with [DefaultClientWebSocketSession]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.ws) */ public suspend fun HttpClient.ws( method: HttpMethod = HttpMethod.Get, @@ -168,6 +184,8 @@ public suspend fun HttpClient.ws( /** * Opens a [block] with [DefaultClientWebSocketSession]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.ws) */ public suspend fun HttpClient.ws( request: HttpRequestBuilder.() -> Unit, @@ -176,6 +194,8 @@ public suspend fun HttpClient.ws( /** * Opens a [block] with [DefaultClientWebSocketSession]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.ws) */ public suspend fun HttpClient.ws( urlString: String, @@ -185,6 +205,8 @@ public suspend fun HttpClient.ws( /** * Opens a [block] with secure [DefaultClientWebSocketSession]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.wss) */ public suspend fun HttpClient.wss( request: HttpRequestBuilder.() -> Unit, @@ -200,6 +222,8 @@ public suspend fun HttpClient.wss( /** * Opens a [block] with secure [DefaultClientWebSocketSession]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.wss) */ public suspend fun HttpClient.wss( urlString: String, @@ -215,6 +239,8 @@ public suspend fun HttpClient.wss( /** * Opens a [block] with secure [DefaultClientWebSocketSession]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.websocket.wss) */ public suspend fun HttpClient.wss( method: HttpMethod = HttpMethod.Get, diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/request/DefaultHttpRequest.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/request/DefaultHttpRequest.kt index e9fd363bc30..124322c501d 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/request/DefaultHttpRequest.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/request/DefaultHttpRequest.kt @@ -13,6 +13,8 @@ import kotlin.coroutines.* /** * Default [HttpRequest] implementation. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.DefaultHttpRequest) */ @InternalAPI public open class DefaultHttpRequest(override val call: HttpClientCall, data: HttpRequestData) : HttpRequest { diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/request/HttpRequest.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/request/HttpRequest.kt index b353ef0fd66..57442399585 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/request/HttpRequest.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/request/HttpRequest.kt @@ -22,11 +22,15 @@ import kotlin.reflect.* /** * A request for [HttpClient], first part of [HttpClientCall]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.HttpRequest) */ public interface HttpRequest : HttpMessage, CoroutineScope { /** * The associated [HttpClientCall] containing both * the underlying [HttpClientCall.request] and [HttpClientCall.response]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.HttpRequest.call) */ public val call: HttpClientCall @@ -34,21 +38,29 @@ public interface HttpRequest : HttpMessage, CoroutineScope { /** * The [HttpMethod] or HTTP VERB used for this request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.HttpRequest.method) */ public val method: HttpMethod /** * The [Url] representing the endpoint and the uri for this request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.HttpRequest.url) */ public val url: Url /** * Typed [Attributes] associated to this call serving as a lightweight container. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.HttpRequest.attributes) */ public val attributes: Attributes /** * An [OutgoingContent] representing the request body + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.HttpRequest.content) */ public val content: OutgoingContent } @@ -57,31 +69,43 @@ public interface HttpRequest : HttpMessage, CoroutineScope { * Contains parameters used to make an HTTP request. * * Learn more from [Making requests](https://ktor.io/docs/request.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.HttpRequestBuilder) */ public class HttpRequestBuilder : HttpMessageBuilder { /** * [URLBuilder] to configure the URL for this request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.HttpRequestBuilder.url) */ public val url: URLBuilder = URLBuilder() /** * [HttpMethod] used by this request. [HttpMethod.Get] by default. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.HttpRequestBuilder.method) */ public var method: HttpMethod = HttpMethod.Get /** * [HeadersBuilder] to configure the headers for this request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.HttpRequestBuilder.headers) */ override val headers: HeadersBuilder = HeadersBuilder() /** * The [body] for this request. Initially [EmptyContent]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.HttpRequestBuilder.body) */ public var body: Any = EmptyContent @InternalAPI public set /** * The [KType] of [body] for this request. Null for default types that don't need serialization. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.HttpRequestBuilder.bodyType) */ public var bodyType: TypeInfo? get() = attributes.getOrNull(BodyTypeAttributeKey) @@ -96,22 +120,30 @@ public class HttpRequestBuilder : HttpMessageBuilder { /** * A deferred used to control the execution of this request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.HttpRequestBuilder.executionContext) */ public var executionContext: Job = SupervisorJob() internal set /** * Provides access to attributes specific for this request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.HttpRequestBuilder.attributes) */ public val attributes: Attributes = Attributes(concurrent = true) /** * Executes a [block] that configures the [URLBuilder] associated to this request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.HttpRequestBuilder.url) */ public fun url(block: URLBuilder.(URLBuilder) -> Unit): Unit = url.block(url) /** * Creates immutable [HttpRequestData]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.HttpRequestBuilder.build) */ @OptIn(InternalAPI::class) public fun build(): HttpRequestData = HttpRequestData( @@ -125,6 +157,8 @@ public class HttpRequestBuilder : HttpMessageBuilder { /** * Sets request-specific attributes specified by [block]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.HttpRequestBuilder.setAttributes) */ public fun setAttributes(block: Attributes.() -> Unit) { attributes.apply(block) @@ -132,6 +166,8 @@ public class HttpRequestBuilder : HttpMessageBuilder { /** * Mutates [this] copying all the data from another [builder] using it as the base. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.HttpRequestBuilder.takeFromWithExecutionContext) */ @InternalAPI public fun takeFromWithExecutionContext(builder: HttpRequestBuilder): HttpRequestBuilder { @@ -141,6 +177,8 @@ public class HttpRequestBuilder : HttpMessageBuilder { /** * Mutates [this] by copying all the data but execution context from another [builder] using it as the base. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.HttpRequestBuilder.takeFrom) */ @OptIn(InternalAPI::class) public fun takeFrom(builder: HttpRequestBuilder): HttpRequestBuilder { @@ -157,6 +195,8 @@ public class HttpRequestBuilder : HttpMessageBuilder { /** * Sets capability configuration. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.HttpRequestBuilder.setCapability) */ public fun setCapability(key: HttpClientEngineCapability, capability: T) { val capabilities = attributes.computeIfAbsent(ENGINE_CAPABILITIES_KEY) { mutableMapOf() } @@ -165,6 +205,8 @@ public class HttpRequestBuilder : HttpMessageBuilder { /** * Retrieves capability by the key. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.HttpRequestBuilder.getCapabilityOrNull) */ public fun getCapabilityOrNull(key: HttpClientEngineCapability): T? { @Suppress("UNCHECKED_CAST") @@ -177,6 +219,8 @@ public class HttpRequestBuilder : HttpMessageBuilder { /** * Actual data of the [HttpRequest], including [url], [method], [headers], [body] and [executionContext]. * Built by [HttpRequestBuilder]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.HttpRequestData) */ public class HttpRequestData @InternalAPI constructor( public val url: Url, @@ -188,6 +232,8 @@ public class HttpRequestData @InternalAPI constructor( ) { /** * Retrieve extension by its key. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.HttpRequestData.getCapabilityOrNull) */ public fun getCapabilityOrNull(key: HttpClientEngineCapability): T? { @Suppress("UNCHECKED_CAST") @@ -205,6 +251,8 @@ public class HttpRequestData @InternalAPI constructor( /** * Data prepared for [HttpResponse]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.HttpResponseData) */ public class HttpResponseData( public val statusCode: HttpStatusCode, @@ -221,11 +269,15 @@ public class HttpResponseData( /** * Executes a [block] that configures the [HeadersBuilder] associated to this request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.headers) */ public fun HttpMessageBuilder.headers(block: HeadersBuilder.() -> Unit): HeadersBuilder = headers.apply(block) /** * Mutates [this] copying all the data from another [request] using it as base. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.takeFrom) */ @OptIn(InternalAPI::class) public fun HttpRequestBuilder.takeFrom(request: HttpRequest): HttpRequestBuilder { @@ -240,11 +292,15 @@ public fun HttpRequestBuilder.takeFrom(request: HttpRequest): HttpRequestBuilder /** * Executes a [block] that configures the [URLBuilder] associated to this request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.url) */ public fun HttpRequestBuilder.url(block: URLBuilder.() -> Unit): Unit = block(url) /** * Sets the [HttpRequestBuilder] from [request]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.takeFrom) */ @OptIn(InternalAPI::class) public fun HttpRequestBuilder.takeFrom(request: HttpRequestData): HttpRequestBuilder { @@ -260,6 +316,8 @@ public fun HttpRequestBuilder.takeFrom(request: HttpRequestData): HttpRequestBui /** * Executes a [block] that configures the [URLBuilder] associated to this request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.invoke) */ public operator fun HttpRequestBuilder.Companion.invoke(block: URLBuilder.() -> Unit): HttpRequestBuilder = HttpRequestBuilder().apply { url(block) } @@ -267,6 +325,8 @@ public operator fun HttpRequestBuilder.Companion.invoke(block: URLBuilder.() -> /** * Sets the [url] using the specified [scheme], [host], [port] and [path]. * Pass `null` to keep the existing value in the [URLBuilder]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.url) */ public fun HttpRequestBuilder.url( scheme: String? = null, @@ -282,6 +342,8 @@ public fun HttpRequestBuilder.url( * Constructs a [HttpRequestBuilder] from URL information: [scheme], [host], [port] and [path] * and optionally further configures it using [block]. * Pass `null` to keep the existing value in the [URLBuilder]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.invoke) */ public operator fun HttpRequestBuilder.Companion.invoke( scheme: String? = null, @@ -293,6 +355,8 @@ public operator fun HttpRequestBuilder.Companion.invoke( /** * Sets the [HttpRequestBuilder.url] from [urlString]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.url) */ public fun HttpRequestBuilder.url(urlString: String) { url.takeFrom(urlString) diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/request/HttpRequestPipeline.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/request/HttpRequestPipeline.kt index 0cc0b2b356e..140f118e307 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/request/HttpRequestPipeline.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/request/HttpRequestPipeline.kt @@ -10,6 +10,8 @@ import io.ktor.util.pipeline.* /** * An [HttpClient]'s pipeline used for executing [HttpRequest]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.HttpRequestPipeline) */ public class HttpRequestPipeline( override val developmentMode: Boolean = true @@ -17,30 +19,42 @@ public class HttpRequestPipeline( /** * All interceptors accept payload as [subject] and try to convert it to [OutgoingContent]. * Last phase should proceed with [HttpClientCall]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.HttpRequestPipeline.Phases) */ public companion object Phases { /** * The earliest phase that happens before any other. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.HttpRequestPipeline.Phases.Before) */ public val Before: PipelinePhase = PipelinePhase("Before") /** * Use this phase to modify a request with a shared state. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.HttpRequestPipeline.Phases.State) */ public val State: PipelinePhase = PipelinePhase("State") /** * Transform a request body to supported render format. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.HttpRequestPipeline.Phases.Transform) */ public val Transform: PipelinePhase = PipelinePhase("Transform") /** * Encode a request body to [OutgoingContent]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.HttpRequestPipeline.Phases.Render) */ public val Render: PipelinePhase = PipelinePhase("Render") /** * A phase for the [HttpSend] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.HttpRequestPipeline.Phases.Send) */ public val Send: PipelinePhase = PipelinePhase("Send") } @@ -48,6 +62,8 @@ public class HttpRequestPipeline( /** * An [HttpClient]'s pipeline used for sending [HttpRequest] to a remote server. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.HttpSendPipeline) */ public class HttpSendPipeline( override val developmentMode: Boolean = true @@ -56,26 +72,36 @@ public class HttpSendPipeline( public companion object Phases { /** * The earliest phase that happens before any other. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.HttpSendPipeline.Phases.Before) */ public val Before: PipelinePhase = PipelinePhase("Before") /** * Use this phase to modify request with a shared state. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.HttpSendPipeline.Phases.State) */ public val State: PipelinePhase = PipelinePhase("State") /** * Use this phase for logging and other actions that don't modify a request or shared data. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.HttpSendPipeline.Phases.Monitoring) */ public val Monitoring: PipelinePhase = PipelinePhase("Monitoring") /** * Send a request to a remote server. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.HttpSendPipeline.Phases.Engine) */ public val Engine: PipelinePhase = PipelinePhase("Engine") /** * Receive a pipeline execution phase. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.HttpSendPipeline.Phases.Receive) */ public val Receive: PipelinePhase = PipelinePhase("Receive") } diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/request/builders.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/request/builders.kt index 5a775111dc6..35a558f4f38 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/request/builders.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/request/builders.kt @@ -29,6 +29,9 @@ import io.ktor.http.* * [HttpClient.get], [HttpClient.post], [HttpClient.put], and [HttpClient.delete], which are often more * convenient for common HTTP methods. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.request) + * * @param builder The [HttpRequestBuilder] used to configure request parameters. Defaults to an empty * builder if none is provided. * @return [HttpResponse] The response received from the server after executing the request. @@ -41,6 +44,8 @@ public suspend inline fun HttpClient.request( /** * Prepares an [HttpClient]'s request with the parameters specified using [builder]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.prepareRequest) */ public suspend inline fun HttpClient.prepareRequest( builder: HttpRequestBuilder = HttpRequestBuilder() @@ -67,6 +72,9 @@ public suspend inline fun HttpClient.prepareRequest( * [HttpClient.get], [HttpClient.post], [HttpClient.put], and [HttpClient.delete], which are often more * convenient for common HTTP methods. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.request) + * * @param block The [HttpRequestBuilder] block used to configure request parameters. * Defaults to an empty builder if none is provided. * @return [HttpResponse] The response received from the server after executing the request. @@ -78,6 +86,8 @@ public suspend inline fun HttpClient.request(block: HttpRequestBuilder.() -> Uni /** * Prepares an [HttpClient]'s request with the parameters specified using [block]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.prepareRequest) */ public suspend inline fun HttpClient.prepareRequest(block: HttpRequestBuilder.() -> Unit): HttpStatement = prepareRequest(HttpRequestBuilder().apply(block)) @@ -102,6 +112,9 @@ public suspend inline fun HttpClient.prepareRequest(block: HttpRequestBuilder.() * [HttpClient.get], [HttpClient.post], [HttpClient.put], and [HttpClient.delete], which are often more * convenient for common HTTP methods. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.request) + * * @param [urlString] The URL to which the request is sent. * @param [block] The [HttpRequestBuilder] used to configure request parameters. Defaults to an empty * builder if none is provided. @@ -119,6 +132,8 @@ public suspend inline fun HttpClient.request( /** * Prepares an [HttpClient]'s request with the [urlString] and the parameters configured in [block]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.prepareRequest) */ public suspend inline fun HttpClient.prepareRequest( urlString: String, @@ -148,6 +163,9 @@ public suspend inline fun HttpClient.prepareRequest( * [HttpClient.get], [HttpClient.post], [HttpClient.put], and [HttpClient.delete], which are often more * convenient for common HTTP methods. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.request) + * * @param [url] The URL to which the request is sent. * @param [block] The [HttpRequestBuilder] used to configure request parameters. Defaults to an empty * builder if none is provided. @@ -165,6 +183,8 @@ public suspend inline fun HttpClient.request( /** * Prepares an [HttpClient]'s request with the [url] and the parameters configured in [block]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.prepareRequest) */ public suspend inline fun HttpClient.prepareRequest( url: Url, @@ -178,6 +198,8 @@ public suspend inline fun HttpClient.prepareRequest( * Executes an [HttpClient]'s GET request with the parameters configured in [builder]. * * Learn more from [Making requests](https://ktor.io/docs/request.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.get) */ public suspend inline fun HttpClient.get(builder: HttpRequestBuilder): HttpResponse { builder.method = HttpMethod.Get @@ -188,6 +210,8 @@ public suspend inline fun HttpClient.get(builder: HttpRequestBuilder): HttpRespo * Executes an [HttpClient]'s POST request with the parameters configured in [builder]. * * Learn more from [Making requests](https://ktor.io/docs/request.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.post) */ public suspend inline fun HttpClient.post(builder: HttpRequestBuilder): HttpResponse { builder.method = HttpMethod.Post @@ -198,6 +222,8 @@ public suspend inline fun HttpClient.post(builder: HttpRequestBuilder): HttpResp * Executes a [HttpClient] PUT request with the parameters configured in [builder]. * * Learn more from [Making requests](https://ktor.io/docs/request.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.put) */ public suspend inline fun HttpClient.put(builder: HttpRequestBuilder): HttpResponse { builder.method = HttpMethod.Put @@ -208,6 +234,8 @@ public suspend inline fun HttpClient.put(builder: HttpRequestBuilder): HttpRespo * Executes a [HttpClient] DELETE request with the parameters configured in [builder]. * * Learn more from [Making requests](https://ktor.io/docs/request.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.delete) */ public suspend inline fun HttpClient.delete(builder: HttpRequestBuilder): HttpResponse { builder.method = HttpMethod.Delete @@ -218,6 +246,8 @@ public suspend inline fun HttpClient.delete(builder: HttpRequestBuilder): HttpRe * Executes a [HttpClient] OPTIONS request with the parameters configured in [builder]. * * Learn more from [Making requests](https://ktor.io/docs/request.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.options) */ public suspend inline fun HttpClient.options(builder: HttpRequestBuilder): HttpResponse { builder.method = HttpMethod.Options @@ -228,6 +258,8 @@ public suspend inline fun HttpClient.options(builder: HttpRequestBuilder): HttpR * Executes a [HttpClient] PATCH request with the parameters configured in [builder]. * * Learn more from [Making requests](https://ktor.io/docs/request.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.patch) */ public suspend inline fun HttpClient.patch(builder: HttpRequestBuilder): HttpResponse { builder.method = HttpMethod.Patch @@ -238,6 +270,8 @@ public suspend inline fun HttpClient.patch(builder: HttpRequestBuilder): HttpRes * Executes a [HttpClient] HEAD request with the parameters configured in [builder]. * * Learn more from [Making requests](https://ktor.io/docs/request.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.head) */ public suspend inline fun HttpClient.head(builder: HttpRequestBuilder): HttpResponse { builder.method = HttpMethod.Head @@ -246,6 +280,8 @@ public suspend inline fun HttpClient.head(builder: HttpRequestBuilder): HttpResp /** * Prepares an [HttpClient]'s GET request with the parameters configured in [builder]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.prepareGet) */ public suspend inline fun HttpClient.prepareGet(builder: HttpRequestBuilder): HttpStatement { builder.method = HttpMethod.Get @@ -254,6 +290,8 @@ public suspend inline fun HttpClient.prepareGet(builder: HttpRequestBuilder): Ht /** * Prepares an [HttpClient]'s POST request with the parameters configured in [builder]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.preparePost) */ public suspend inline fun HttpClient.preparePost(builder: HttpRequestBuilder): HttpStatement { builder.method = HttpMethod.Post @@ -262,6 +300,8 @@ public suspend inline fun HttpClient.preparePost(builder: HttpRequestBuilder): H /** * Prepares an [HttpClient]'s PUT request with the parameters configured in [builder]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.preparePut) */ public suspend inline fun HttpClient.preparePut(builder: HttpRequestBuilder): HttpStatement { builder.method = HttpMethod.Put @@ -270,6 +310,8 @@ public suspend inline fun HttpClient.preparePut(builder: HttpRequestBuilder): Ht /** * Prepares an [HttpClient]'s DELETE request with the parameters configured in [builder]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.prepareDelete) */ public suspend inline fun HttpClient.prepareDelete(builder: HttpRequestBuilder): HttpStatement { builder.method = HttpMethod.Delete @@ -278,6 +320,8 @@ public suspend inline fun HttpClient.prepareDelete(builder: HttpRequestBuilder): /** * Prepares an [HttpClient]'s OPTIONS request with the parameters configured in [builder]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.prepareOptions) */ public suspend inline fun HttpClient.prepareOptions(builder: HttpRequestBuilder): HttpStatement { builder.method = HttpMethod.Options @@ -286,6 +330,8 @@ public suspend inline fun HttpClient.prepareOptions(builder: HttpRequestBuilder) /** * Prepares an [HttpClient]'s PATCH request with the parameters configured in [builder]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.preparePatch) */ public suspend inline fun HttpClient.preparePatch(builder: HttpRequestBuilder): HttpStatement { builder.method = HttpMethod.Patch @@ -294,6 +340,8 @@ public suspend inline fun HttpClient.preparePatch(builder: HttpRequestBuilder): /** * Prepares an [HttpClient]'s HEAD request with the parameters configured in [builder]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.prepareHead) */ public suspend inline fun HttpClient.prepareHead(builder: HttpRequestBuilder): HttpStatement { builder.method = HttpMethod.Head @@ -304,6 +352,8 @@ public suspend inline fun HttpClient.prepareHead(builder: HttpRequestBuilder): H * Executes an [HttpClient]'s GET request with the parameters configured in [block]. * * Learn more from [Making requests](https://ktor.io/docs/request.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.get) */ public suspend inline fun HttpClient.get(block: HttpRequestBuilder.() -> Unit): HttpResponse = get(HttpRequestBuilder().apply(block)) @@ -312,6 +362,8 @@ public suspend inline fun HttpClient.get(block: HttpRequestBuilder.() -> Unit): * Executes an [HttpClient]'s POST request with the parameters configured in [block]. * * Learn more from [Making requests](https://ktor.io/docs/request.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.post) */ public suspend inline fun HttpClient.post(block: HttpRequestBuilder.() -> Unit): HttpResponse = post(HttpRequestBuilder().apply(block)) @@ -320,6 +372,8 @@ public suspend inline fun HttpClient.post(block: HttpRequestBuilder.() -> Unit): * Executes an [HttpClient]'s PUT request with the parameters configured in [block]. * * Learn more from [Making requests](https://ktor.io/docs/request.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.put) */ public suspend inline fun HttpClient.put(block: HttpRequestBuilder.() -> Unit): HttpResponse = put(HttpRequestBuilder().apply(block)) @@ -328,6 +382,8 @@ public suspend inline fun HttpClient.put(block: HttpRequestBuilder.() -> Unit): * Executes an [HttpClient]'s DELETE request with the parameters configured in [block]. * * Learn more from [Making requests](https://ktor.io/docs/request.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.delete) */ public suspend inline fun HttpClient.delete(block: HttpRequestBuilder.() -> Unit): HttpResponse = delete(HttpRequestBuilder().apply(block)) @@ -336,6 +392,8 @@ public suspend inline fun HttpClient.delete(block: HttpRequestBuilder.() -> Unit * Executes an [HttpClient]'s OPTIONS request with the parameters configured in [block]. * * Learn more from [Making requests](https://ktor.io/docs/request.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.options) */ public suspend inline fun HttpClient.options(block: HttpRequestBuilder.() -> Unit): HttpResponse = options(HttpRequestBuilder().apply(block)) @@ -344,6 +402,8 @@ public suspend inline fun HttpClient.options(block: HttpRequestBuilder.() -> Uni * Executes an [HttpClient]'s PATCH request with the parameters configured in [block]. * * Learn more from [Making requests](https://ktor.io/docs/request.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.patch) */ public suspend inline fun HttpClient.patch(block: HttpRequestBuilder.() -> Unit): HttpResponse = patch(HttpRequestBuilder().apply(block)) @@ -352,54 +412,72 @@ public suspend inline fun HttpClient.patch(block: HttpRequestBuilder.() -> Unit) * Executes an [HttpClient]'s HEAD request with the parameters configured in [block]. * * Learn more from [Making requests](https://ktor.io/docs/request.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.head) */ public suspend inline fun HttpClient.head(block: HttpRequestBuilder.() -> Unit): HttpResponse = head(HttpRequestBuilder().apply(block)) /** * Prepares an [HttpClient]'s GET request with the parameters configured in [block]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.prepareGet) */ public suspend inline fun HttpClient.prepareGet(block: HttpRequestBuilder.() -> Unit): HttpStatement = prepareGet(HttpRequestBuilder().apply(block)) /** * Prepares an [HttpClient]'s POST request with the parameters configured in [block]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.preparePost) */ public suspend inline fun HttpClient.preparePost(block: HttpRequestBuilder.() -> Unit): HttpStatement = preparePost(HttpRequestBuilder().apply(block)) /** * Prepares an [HttpClient]'s PUT request with the parameters configured in [block]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.preparePut) */ public suspend inline fun HttpClient.preparePut(block: HttpRequestBuilder.() -> Unit): HttpStatement = preparePut(HttpRequestBuilder().apply(block)) /** * Prepares an [HttpClient]'s DELETE request with the parameters configured in [block]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.prepareDelete) */ public suspend inline fun HttpClient.prepareDelete(block: HttpRequestBuilder.() -> Unit): HttpStatement = prepareDelete(HttpRequestBuilder().apply(block)) /** * Prepares an [HttpClient]'s OPTIONS request with the parameters configured in [block]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.prepareOptions) */ public suspend inline fun HttpClient.prepareOptions(block: HttpRequestBuilder.() -> Unit): HttpStatement = prepareOptions(HttpRequestBuilder().apply(block)) /** * Prepares an [HttpClient]'s PATCH request with the parameters configured in [block]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.preparePatch) */ public suspend inline fun HttpClient.preparePatch(block: HttpRequestBuilder.() -> Unit): HttpStatement = preparePatch(HttpRequestBuilder().apply(block)) /** * Prepares an [HttpClient]'s HEAD request with the parameters configured in [block]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.prepareHead) */ public suspend inline fun HttpClient.prepareHead(block: HttpRequestBuilder.() -> Unit): HttpStatement = prepareHead(HttpRequestBuilder().apply(block)) /** * Creates an [HttpRequestBuilder] and configures it using [block]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.request) */ public fun request(block: HttpRequestBuilder.() -> Unit): HttpRequestBuilder = HttpRequestBuilder().apply(block) @@ -409,6 +487,8 @@ public fun request(block: HttpRequestBuilder.() -> Unit): HttpRequestBuilder = * an optional [block] receiving an [HttpRequestBuilder] for configuring the request. * * Learn more from [Making requests](https://ktor.io/docs/request.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.get) */ public suspend inline fun HttpClient.get( urlString: String, @@ -423,6 +503,8 @@ public suspend inline fun HttpClient.get( * an optional [block] receiving an [HttpRequestBuilder] for configuring the request. * * Learn more from [Making requests](https://ktor.io/docs/request.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.post) */ public suspend inline fun HttpClient.post( urlString: String, @@ -437,6 +519,8 @@ public suspend inline fun HttpClient.post( * an optional [block] receiving an [HttpRequestBuilder] for configuring the request. * * Learn more from [Making requests](https://ktor.io/docs/request.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.put) */ public suspend inline fun HttpClient.put( urlString: String, @@ -451,6 +535,8 @@ public suspend inline fun HttpClient.put( * an optional [block] receiving an [HttpRequestBuilder] for configuring the request. * * Learn more from [Making requests](https://ktor.io/docs/request.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.delete) */ public suspend inline fun HttpClient.delete( urlString: String, @@ -465,6 +551,8 @@ public suspend inline fun HttpClient.delete( * an optional [block] receiving an [HttpRequestBuilder] for configuring the request. * * Learn more from [Making requests](https://ktor.io/docs/request.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.options) */ public suspend inline fun HttpClient.options( urlString: String, @@ -479,6 +567,8 @@ public suspend inline fun HttpClient.options( * an optional [block] receiving an [HttpRequestBuilder] for configuring the request. * * Learn more from [Making requests](https://ktor.io/docs/request.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.patch) */ public suspend inline fun HttpClient.patch( urlString: String, @@ -493,6 +583,8 @@ public suspend inline fun HttpClient.patch( * an optional [block] receiving an [HttpRequestBuilder] for configuring the request. * * Learn more from [Making requests](https://ktor.io/docs/request.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.head) */ public suspend inline fun HttpClient.head( urlString: String, @@ -505,6 +597,8 @@ public suspend inline fun HttpClient.head( /** * Prepares an [HttpClient]'s GET request with the specified [url] and * an optional [block] receiving an [HttpRequestBuilder] for configuring the request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.prepareGet) */ public suspend inline fun HttpClient.prepareGet( urlString: String, @@ -517,6 +611,8 @@ public suspend inline fun HttpClient.prepareGet( /** * Prepares an [HttpClient]'s POST request with the specified [url] and * an optional [block] receiving an [HttpRequestBuilder] for configuring the request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.preparePost) */ public suspend inline fun HttpClient.preparePost( urlString: String, @@ -529,6 +625,8 @@ public suspend inline fun HttpClient.preparePost( /** * Prepares an [HttpClient]'s PUT request with the specified [url] and * an optional [block] receiving an [HttpRequestBuilder] for configuring the request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.preparePut) */ public suspend inline fun HttpClient.preparePut( urlString: String, @@ -541,6 +639,8 @@ public suspend inline fun HttpClient.preparePut( /** * Prepares an [HttpClient]'s DELETE request with the specified [url] and * an optional [block] receiving an [HttpRequestBuilder] for configuring the request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.prepareDelete) */ public suspend inline fun HttpClient.prepareDelete( urlString: String, @@ -553,6 +653,8 @@ public suspend inline fun HttpClient.prepareDelete( /** * Prepares an [HttpClient]'s OPTIONS request with the specified [url] and * an optional [block] receiving an [HttpRequestBuilder] for configuring the request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.prepareOptions) */ public suspend inline fun HttpClient.prepareOptions( urlString: String, @@ -565,6 +667,8 @@ public suspend inline fun HttpClient.prepareOptions( /** * Prepares an [HttpClient]'s PATCH request with the specified [url] and * an optional [block] receiving an [HttpRequestBuilder] for configuring the request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.preparePatch) */ public suspend inline fun HttpClient.preparePatch( urlString: String, @@ -577,6 +681,8 @@ public suspend inline fun HttpClient.preparePatch( /** * Prepares an [HttpClient]'s HEAD request with the specified [url] and * an optional [block] receiving an [HttpRequestBuilder] for configuring the request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.prepareHead) */ public suspend inline fun HttpClient.prepareHead( urlString: String, diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/request/buildersWithUrl.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/request/buildersWithUrl.kt index 192619f308d..d72f68f1784 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/request/buildersWithUrl.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/request/buildersWithUrl.kt @@ -13,6 +13,8 @@ import io.ktor.http.* * an optional [block] receiving an [HttpRequestBuilder] for configuring the request. * * Learn more from [Making requests](https://ktor.io/docs/request.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.get) */ public suspend inline fun HttpClient.get( url: Url, @@ -25,6 +27,8 @@ public suspend inline fun HttpClient.get( /** * Prepares a [HttpClient] GET request with the specified [url] and * an optional [block] receiving an [HttpRequestBuilder] for configuring the request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.prepareGet) */ public suspend inline fun HttpClient.prepareGet( url: Url, @@ -39,6 +43,8 @@ public suspend inline fun HttpClient.prepareGet( * an optional [block] receiving an [HttpRequestBuilder] for configuring the request. * * Learn more from [Making requests](https://ktor.io/docs/request.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.post) */ public suspend inline fun HttpClient.post( url: Url, @@ -51,6 +57,8 @@ public suspend inline fun HttpClient.post( /** * Prepares a [HttpClient] POST request with the specified [url] and * an optional [block] receiving an [HttpRequestBuilder] for configuring the request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.preparePost) */ public suspend inline fun HttpClient.preparePost( url: Url, @@ -65,6 +73,8 @@ public suspend inline fun HttpClient.preparePost( * an optional [block] receiving an [HttpRequestBuilder] for configuring the request. * * Learn more from [Making requests](https://ktor.io/docs/request.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.put) */ public suspend inline fun HttpClient.put( url: Url, @@ -77,6 +87,8 @@ public suspend inline fun HttpClient.put( /** * Prepares a [HttpClient] PUT request with the specified [url] and * an optional [block] receiving an [HttpRequestBuilder] for configuring the request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.preparePut) */ public suspend inline fun HttpClient.preparePut( url: Url, @@ -91,6 +103,8 @@ public suspend inline fun HttpClient.preparePut( * an optional [block] receiving an [HttpRequestBuilder] for configuring the request. * * Learn more from [Making requests](https://ktor.io/docs/request.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.patch) */ public suspend inline fun HttpClient.patch( url: Url, @@ -103,6 +117,8 @@ public suspend inline fun HttpClient.patch( /** * Prepares a [HttpClient] PATCH request with the specified [url] and * an optional [block] receiving an [HttpRequestBuilder] for configuring the request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.preparePatch) */ public suspend inline fun HttpClient.preparePatch( url: Url, @@ -117,6 +133,8 @@ public suspend inline fun HttpClient.preparePatch( * an optional [block] receiving an [HttpRequestBuilder] for configuring the request. * * Learn more from [Making requests](https://ktor.io/docs/request.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.options) */ public suspend inline fun HttpClient.options( url: Url, @@ -129,6 +147,8 @@ public suspend inline fun HttpClient.options( /** * Prepares a [HttpClient] OPTIONS request with the specified [url] and * an optional [block] receiving an [HttpRequestBuilder] for configuring the request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.prepareOptions) */ public suspend inline fun HttpClient.prepareOptions( url: Url, @@ -143,6 +163,8 @@ public suspend inline fun HttpClient.prepareOptions( * an optional [block] receiving an [HttpRequestBuilder] for configuring the request. * * Learn more from [Making requests](https://ktor.io/docs/request.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.head) */ public suspend inline fun HttpClient.head( url: Url, @@ -155,6 +177,8 @@ public suspend inline fun HttpClient.head( /** * Prepares a [HttpClient] HEAD request with the specified [url] and * an optional [block] receiving an [HttpRequestBuilder] for configuring the request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.prepareHead) */ public suspend inline fun HttpClient.prepareHead( url: Url, @@ -169,6 +193,8 @@ public suspend inline fun HttpClient.prepareHead( * an optional [block] receiving an [HttpRequestBuilder] for configuring the request. * * Learn more from [Making requests](https://ktor.io/docs/request.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.delete) */ public suspend inline fun HttpClient.delete( url: Url, @@ -181,6 +207,8 @@ public suspend inline fun HttpClient.delete( /** * Prepares a [HttpClient] HEAD request with the specified [url] and * an optional [block] receiving an [HttpRequestBuilder] for configuring the request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.prepareDelete) */ public suspend inline fun HttpClient.prepareDelete( url: Url, @@ -192,6 +220,8 @@ public suspend inline fun HttpClient.prepareDelete( /** * Sets the [HttpRequestBuilder.url] from [url]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.url) */ public fun HttpRequestBuilder.url(url: Url) { this.url.takeFrom(url) diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/request/forms/FormDataContent.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/request/forms/FormDataContent.kt index e9da3990dad..a304345a583 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/request/forms/FormDataContent.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/request/forms/FormDataContent.kt @@ -19,6 +19,9 @@ private val RN_BYTES = "\r\n".toByteArray() * * Example: [Form parameters](https://ktor.io/docs/request.html#form_parameters). * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.forms.FormDataContent) + * * @param formData data to send. */ public class FormDataContent( @@ -37,6 +40,9 @@ public class FormDataContent( * * Example: [Upload a file](https://ktor.io/docs/request.html#upload_file). * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.forms.MultiPartFormDataContent) + * * @param parts form part data */ diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/request/forms/formBuilders.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/request/forms/formBuilders.kt index cb748b671bb..c7cd0b3d895 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/request/forms/formBuilders.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/request/forms/formBuilders.kt @@ -17,6 +17,8 @@ import io.ktor.http.content.* * Otherwise, form parameters are sent in a POST request body. * * Example: [Form parameters](https://ktor.io/docs/request.html#form_parameters). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.forms.submitForm) */ public suspend inline fun HttpClient.submitForm( formParameters: Parameters = Parameters.Empty, @@ -41,6 +43,8 @@ public suspend inline fun HttpClient.submitForm( * Otherwise, form parameters are sent in a POST request body. * * Example: [Form parameters](https://ktor.io/docs/request.html#form_parameters). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.forms.submitForm) */ public suspend fun HttpClient.submitForm( url: String, @@ -56,6 +60,8 @@ public suspend fun HttpClient.submitForm( * Makes a POST request containing form parameters encoded using the `multipart/form-data` format. * * Example: [Upload a file](https://ktor.io/docs/request.html#upload_file). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.forms.submitFormWithBinaryData) */ public suspend inline fun HttpClient.submitFormWithBinaryData( formData: List, @@ -70,6 +76,8 @@ public suspend inline fun HttpClient.submitFormWithBinaryData( * Makes a POST request containing form parameters encoded using the `multipart/form-data` format. * * Example: [Upload a file](https://ktor.io/docs/request.html#upload_file). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.forms.submitFormWithBinaryData) */ public suspend inline fun HttpClient.submitFormWithBinaryData( url: String, @@ -85,6 +93,8 @@ public suspend inline fun HttpClient.submitFormWithBinaryData( * * If [encodeInQuery] is set to `true`, form parameters are sent as URL parameters using the GET request. * Otherwise, form parameters are sent in a POST request body. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.forms.prepareForm) */ public suspend inline fun HttpClient.prepareForm( formParameters: Parameters = Parameters.Empty, @@ -107,6 +117,8 @@ public suspend inline fun HttpClient.prepareForm( * * If [encodeInQuery] is set to `true`, form parameters are sent as URL parameters using the GET request. * Otherwise, form parameters are sent in a POST request body. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.forms.prepareForm) */ public suspend fun HttpClient.prepareForm( url: String, @@ -120,6 +132,8 @@ public suspend fun HttpClient.prepareForm( /** * Prepares a POST request containing form parameters encoded using the `multipart/form-data` format. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.forms.prepareFormWithBinaryData) */ public suspend inline fun HttpClient.prepareFormWithBinaryData( formData: List, @@ -132,6 +146,8 @@ public suspend inline fun HttpClient.prepareFormWithBinaryData( /** * Prepares a POST request containing form parameters encoded using the `multipart/form-data` format. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.forms.prepareFormWithBinaryData) */ public suspend inline fun HttpClient.prepareFormWithBinaryData( url: String, diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/request/forms/formDsl.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/request/forms/formDsl.kt index a908189d10e..ef14c5b5364 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/request/forms/formDsl.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/request/forms/formDsl.kt @@ -14,6 +14,9 @@ import kotlin.contracts.* /** * A multipart form item. Use it to build a form in client. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.forms.FormPart) + * * @param key multipart name * @param value content, could be [String], [Number], [ByteArray], [ByteReadPacket] or [InputProvider] * @param headers part headers, note that some servers may fail if an unknown header provided @@ -24,6 +27,8 @@ public data class FormPart(val key: String, val value: T, val headers: * Builds a multipart form from [values]. * * Example: [Upload a file](https://ktor.io/docs/request.html#upload_file). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.forms.formData) */ public fun formData(vararg values: FormPart<*>): List { @@ -72,18 +77,24 @@ public fun formData(vararg values: FormPart<*>): List { /** * Build multipart form using [block] function. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.forms.formData) */ public fun formData(block: FormBuilder.() -> Unit): List = formData(*FormBuilder().apply(block).build().toTypedArray()) /** * A form builder type used in the [formData] builder function. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.forms.FormBuilder) */ public class FormBuilder internal constructor() { private val parts = mutableListOf>() /** * Appends a pair [key]:[value] with optional [headers]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.forms.FormBuilder.append) */ @InternalAPI public fun append(key: String, value: T, headers: Headers = Headers.Empty) { @@ -92,6 +103,8 @@ public class FormBuilder internal constructor() { /** * Appends a pair [key]:[value] with optional [headers]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.forms.FormBuilder.append) */ public fun append(key: String, value: String, headers: Headers = Headers.Empty) { parts += FormPart(key, value, headers) @@ -99,6 +112,8 @@ public class FormBuilder internal constructor() { /** * Appends a pair [key]:[value] with optional [headers]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.forms.FormBuilder.append) */ public fun append(key: String, value: Number, headers: Headers = Headers.Empty) { parts += FormPart(key, value, headers) @@ -106,6 +121,8 @@ public class FormBuilder internal constructor() { /** * Appends a pair [key]:[value] with optional [headers]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.forms.FormBuilder.append) */ public fun append(key: String, value: Boolean, headers: Headers = Headers.Empty) { parts += FormPart(key, value, headers) @@ -113,6 +130,8 @@ public class FormBuilder internal constructor() { /** * Appends a pair [key]:[value] with optional [headers]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.forms.FormBuilder.append) */ public fun append(key: String, value: ByteArray, headers: Headers = Headers.Empty) { parts += FormPart(key, value, headers) @@ -120,6 +139,8 @@ public class FormBuilder internal constructor() { /** * Appends a pair [key]:[value] with optional [headers]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.forms.FormBuilder.append) */ public fun append(key: String, value: InputProvider, headers: Headers = Headers.Empty) { parts += FormPart(key, value, headers) @@ -127,6 +148,8 @@ public class FormBuilder internal constructor() { /** * Appends a pair [key]:[InputProvider(block)] with optional [headers]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.forms.FormBuilder.appendInput) */ public fun appendInput(key: String, headers: Headers = Headers.Empty, size: Long? = null, block: () -> Input) { @@ -135,6 +158,8 @@ public class FormBuilder internal constructor() { /** * Appends a pair [key]:[value] with optional [headers]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.forms.FormBuilder.append) */ public fun append(key: String, value: Source, headers: Headers = Headers.Empty) { parts += FormPart(key, value, headers) @@ -142,6 +167,8 @@ public class FormBuilder internal constructor() { /** * Appends a pair [key]:[values] with optional [headers]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.forms.FormBuilder.append) */ public fun append(key: String, values: Iterable, headers: Headers = Headers.Empty) { require(key.endsWith("[]")) { @@ -154,6 +181,8 @@ public class FormBuilder internal constructor() { /** * Appends a pair [key]:[values] with optional [headers]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.forms.FormBuilder.append) */ public fun append(key: String, values: Array, headers: Headers = Headers.Empty) { return append(key, values.asIterable(), headers) @@ -161,6 +190,8 @@ public class FormBuilder internal constructor() { /** * Appends a pair [key]:[ChannelProvider] with optional [headers]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.forms.FormBuilder.append) */ public fun append(key: String, value: ChannelProvider, headers: Headers = Headers.Empty) { parts += FormPart(key, value, headers) @@ -168,6 +199,8 @@ public class FormBuilder internal constructor() { /** * Appends a form [part]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.forms.FormBuilder.append) */ public fun append(part: FormPart) { parts += part @@ -178,6 +211,8 @@ public class FormBuilder internal constructor() { /** * Appends a form part with the specified [key] using [bodyBuilder] for its body. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.forms.append) */ @OptIn(ExperimentalContracts::class) @@ -196,6 +231,9 @@ public inline fun FormBuilder.append( /** * A reusable [Input] form entry. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.forms.InputProvider) + * * @property size estimate for data produced by the block or `null` if no size estimation known * @param block: content generator */ @@ -204,6 +242,9 @@ public class InputProvider(public val size: Long? = null, public val block: () - /** * Supplies a new [ByteReadChannel]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.forms.ChannelProvider) + * * @property size is total number of bytes that can be read from [ByteReadChannel] or `null` if [size] is unknown * @param block returns a new [ByteReadChannel] */ @@ -211,6 +252,8 @@ public class ChannelProvider(public val size: Long? = null, public val block: () /** * Appends a form part with the specified [key], [filename], and optional [contentType] using [bodyBuilder] for its body. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.forms.append) */ @OptIn(ExperimentalContracts::class) diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/request/utils.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/request/utils.kt index 83a711a003a..cdccc3320b0 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/request/utils.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/request/utils.kt @@ -10,6 +10,8 @@ import io.ktor.util.date.* /** * Gets the associated URL's host. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.host) */ public var HttpRequestBuilder.host: String get() = url.host @@ -19,6 +21,8 @@ public var HttpRequestBuilder.host: String /** * Gets the associated URL's port. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.port) */ public var HttpRequestBuilder.port: Int get() = url.port @@ -28,12 +32,16 @@ public var HttpRequestBuilder.port: Int /** * Appends a single header of [key] with a specific [value] if the value is not null. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.header) */ public fun HttpMessageBuilder.header(key: String, value: Any?): Unit = value?.let { headers.append(key, it.toString()) } ?: Unit /** * Appends a single header of [key] with a specific [value] if the value is not null. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.cookie) */ public fun HttpMessageBuilder.cookie( name: String, @@ -69,12 +77,16 @@ public fun HttpMessageBuilder.cookie( /** * Appends a single URL query parameter of [key] with a specific [value] if the value is not null. Can not be used to set * form parameters in the body. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.parameter) */ public fun HttpRequestBuilder.parameter(key: String, value: Any?): Unit = value?.let { url.parameters.append(key, it.toString()) } ?: Unit /** * Appends the `Accept` header with a specific [contentType]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.accept) */ public fun HttpMessageBuilder.accept(contentType: ContentType): Unit = headers.append(HttpHeaders.Accept, contentType.toString()) @@ -82,6 +94,8 @@ public fun HttpMessageBuilder.accept(contentType: ContentType): Unit = /** * Appends the [HttpHeaders.Authorization] to Basic Authorization with the provided [username] and [password]. * For advanced configuration use the `io.ktor:ktor-client-auth` plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.basicAuth) */ public fun HttpMessageBuilder.basicAuth(username: String, password: String): Unit = header(HttpHeaders.Authorization, "Basic ${"$username:$password".encodeBase64()}") @@ -89,6 +103,8 @@ public fun HttpMessageBuilder.basicAuth(username: String, password: String): Uni /** * Appends the [HttpHeaders.Authorization] to Bearer Authorization with the provided [token]. * For advanced configuration use the `io.ktor:ktor-client-auth` plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.bearerAuth) */ public fun HttpMessageBuilder.bearerAuth(token: String): Unit = header(HttpHeaders.Authorization, "Bearer $token") diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/statement/HttpResponse.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/statement/HttpResponse.kt index bfabf1f3f72..bf986f09922 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/statement/HttpResponse.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/statement/HttpResponse.kt @@ -18,32 +18,44 @@ import kotlinx.io.* * An [HttpClient]'s response, a second part of [HttpClientCall]. * * Learn more from [Receiving responses](https://ktor.io/docs/response.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.statement.HttpResponse) */ public abstract class HttpResponse : HttpMessage, CoroutineScope { /** * The associated [HttpClientCall] containing both * the underlying [HttpClientCall.request] and [HttpClientCall.response]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.statement.HttpResponse.call) */ public abstract val call: HttpClientCall /** * The [HttpStatusCode] returned by the server. It includes both, * the [HttpStatusCode.description] and the [HttpStatusCode.value] (code). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.statement.HttpResponse.status) */ public abstract val status: HttpStatusCode /** * HTTP version. Usually [HttpProtocolVersion.HTTP_1_1] or [HttpProtocolVersion.HTTP_2_0]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.statement.HttpResponse.version) */ public abstract val version: HttpProtocolVersion /** * [GMTDate] of the request start. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.statement.HttpResponse.requestTime) */ public abstract val requestTime: GMTDate /** * [GMTDate] of the response start. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.statement.HttpResponse.responseTime) */ public abstract val responseTime: GMTDate @@ -56,6 +68,8 @@ public abstract class HttpResponse : HttpMessage, CoroutineScope { * If you need to read the content as decoded bytes, use the [bodyAsChannel] method instead. * * This property produces a new channel every time it's accessed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.statement.HttpResponse.rawContent) */ @InternalAPI public abstract val rawContent: ByteReadChannel @@ -70,6 +84,8 @@ public abstract class HttpResponse : HttpMessage, CoroutineScope { * This content doesn't go through any interceptors from [HttpResponsePipeline]. * * If you need to read the content as decoded bytes, use the [bodyAsChannel] method instead. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.statement.content) */ @InternalAPI @Deprecated( @@ -80,6 +96,8 @@ public val HttpResponse.content: ByteReadChannel get() = rawContent /** * Gets [HttpRequest] associated with this response. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.statement.request) */ public val HttpResponse.request: HttpRequest get() = call.request @@ -98,6 +116,8 @@ internal fun HttpResponse.complete() { * * Note that [fallbackCharset] parameter will be ignored if the response already has a charset. * So it just acts as a fallback, honoring the server preference. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.statement.bodyAsText) */ public suspend fun HttpResponse.bodyAsText(fallbackCharset: Charset = Charsets.UTF_8): String { val originCharset = charset() ?: fallbackCharset @@ -109,6 +129,8 @@ public suspend fun HttpResponse.bodyAsText(fallbackCharset: Charset = Charsets.U /** * Reads the [HttpResponse.rawContent] as a [ByteReadChannel]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.statement.bodyAsChannel) */ public suspend fun HttpResponse.bodyAsChannel(): ByteReadChannel = body() @@ -117,5 +139,7 @@ public suspend fun HttpResponse.bodyAsChannel(): ByteReadChannel = body() * decompressed or decoded. * * If you need to read the raw payload of the HTTP response as a byte array, use the [rawContent] property instead. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.statement.bodyAsBytes) */ public suspend fun HttpResponse.bodyAsBytes(): ByteArray = body() diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/statement/HttpResponsePipeline.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/statement/HttpResponsePipeline.kt index 8079eddf65f..80289db52de 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/statement/HttpResponsePipeline.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/statement/HttpResponsePipeline.kt @@ -11,6 +11,8 @@ import io.ktor.util.reflect.* /** * [HttpClient] Pipeline used for executing [HttpResponse]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.statement.HttpResponsePipeline) */ public class HttpResponsePipeline( override val developmentMode: Boolean = true @@ -24,26 +26,36 @@ public class HttpResponsePipeline( public companion object Phases { /** * The earliest phase that happens before any other + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.statement.HttpResponsePipeline.Phases.Receive) */ public val Receive: PipelinePhase = PipelinePhase("Receive") /** * Decode response body + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.statement.HttpResponsePipeline.Phases.Parse) */ public val Parse: PipelinePhase = PipelinePhase("Parse") /** * Transform response body to expected format + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.statement.HttpResponsePipeline.Phases.Transform) */ public val Transform: PipelinePhase = PipelinePhase("Transform") /** * Use this phase to store request shared state + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.statement.HttpResponsePipeline.Phases.State) */ public val State: PipelinePhase = PipelinePhase("State") /** * Latest response pipeline phase + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.statement.HttpResponsePipeline.Phases.After) */ public val After: PipelinePhase = PipelinePhase("After") } @@ -51,6 +63,8 @@ public class HttpResponsePipeline( /** * [HttpClient] Pipeline used for receiving [HttpResponse] without any processing. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.statement.HttpReceivePipeline) */ public class HttpReceivePipeline( override val developmentMode: Boolean = true @@ -58,16 +72,22 @@ public class HttpReceivePipeline( public companion object Phases { /** * The earliest phase that happens before any other + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.statement.HttpReceivePipeline.Phases.Before) */ public val Before: PipelinePhase = PipelinePhase("Before") /** * Use this phase to store request shared state + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.statement.HttpReceivePipeline.Phases.State) */ public val State: PipelinePhase = PipelinePhase("State") /** * Latest response pipeline phase + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.statement.HttpReceivePipeline.Phases.After) */ public val After: PipelinePhase = PipelinePhase("After") } @@ -75,6 +95,9 @@ public class HttpReceivePipeline( /** * Class representing a typed [response] with an attached [expectedType]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.statement.HttpResponseContainer) + * * @param expectedType: information about expected type. * @param response: current response state. */ diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/statement/HttpStatement.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/statement/HttpStatement.kt index 10d878032c4..69f79aa20c0 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/statement/HttpStatement.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/statement/HttpStatement.kt @@ -24,6 +24,8 @@ import kotlinx.coroutines.* * the same request configuration. * * Example: [Streaming data](https://ktor.io/docs/response.html#streaming) + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.statement.HttpStatement) */ public class HttpStatement( private val builder: HttpRequestBuilder, @@ -42,6 +44,9 @@ public class HttpStatement( * The [response] object should not be accessed outside of [block] as it will be canceled upon * block completion. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.statement.HttpStatement.execute) + * * @param block A suspend function that receives the [HttpResponse] for streaming. * @return The result of executing [block] with the streaming [response]. */ @@ -63,6 +68,9 @@ public class HttpStatement( * * For retrieving a specific data type directly, consider using [body()]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.statement.HttpStatement.execute) + * * @return [HttpResponse] The complete response with the body loaded into memory. */ public suspend fun execute(): HttpResponse = fetchResponse() @@ -74,6 +82,9 @@ public class HttpStatement( * If [T] represents a streaming type (such as [ByteReadChannel]), it is the caller's responsibility to * properly manage the resource, ensuring it is closed when no longer needed. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.statement.HttpStatement.body) + * * @return The response body transformed to the specified type [T]. */ @OptIn(InternalAPI::class) @@ -106,6 +117,9 @@ public class HttpStatement( * // Resources are released automatically after block completes * ``` * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.statement.HttpStatement.body) + * * @param block A suspend function that handles the streamed [response] of type [T]. * @return The result of [block] applied to the streaming [response]. * diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/statement/Readers.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/statement/Readers.kt index 18bf86eb496..97f526b5e26 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/statement/Readers.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/statement/Readers.kt @@ -9,6 +9,8 @@ import kotlinx.io.* /** * Reads exactly [count] bytes of the [HttpResponse.rawContent]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.statement.readBytes) */ @OptIn(InternalAPI::class) public suspend fun HttpResponse.readBytes(count: Int): ByteArray = ByteArray(count).also { @@ -24,6 +26,9 @@ public suspend fun HttpResponse.readBytes(count: Int): ByteArray = ByteArray(cou * The content will retain its original * compression or encoding as received from the server. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.statement.readRawBytes) + * * @return the raw payload of the HTTP response as a byte array */ @OptIn(InternalAPI::class) @@ -38,6 +43,9 @@ public suspend fun HttpResponse.readRawBytes(): ByteArray = rawContent.readRemai * * If you need to read the content as decoded bytes, use the [bodyAsBytes()] method instead. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.statement.readBytes) + * * @return the raw payload of the HTTP response as a byte array */ @OptIn(InternalAPI::class) @@ -46,6 +54,8 @@ public suspend fun HttpResponse.readBytes(): ByteArray = rawContent.readRemainin /** * Efficiently discards the remaining bytes of [HttpResponse.rawContent]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.statement.discardRemaining) */ @OptIn(InternalAPI::class) public suspend fun HttpResponse.discardRemaining() { diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/utils/CIO.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/utils/CIO.kt index f71de6da207..8308c499617 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/utils/CIO.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/utils/CIO.kt @@ -6,10 +6,14 @@ package io.ktor.client.utils /** * Maximum number of buffers to be allocated in the [HttpClientDefaultPool]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.utils.DEFAULT_HTTP_POOL_SIZE) */ public const val DEFAULT_HTTP_POOL_SIZE: Int = 1000 /** * Size of each buffer in the [HttpClientDefaultPool]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.utils.DEFAULT_HTTP_BUFFER_SIZE) */ public const val DEFAULT_HTTP_BUFFER_SIZE: Int = 4096 diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/utils/CacheControl.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/utils/CacheControl.kt index 0564aef4f90..1fe34bf0386 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/utils/CacheControl.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/utils/CacheControl.kt @@ -6,6 +6,8 @@ package io.ktor.client.utils /** * List of [CacheControl] known values. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.utils.CacheControl) */ @Suppress("KDocMissingDocumentation", "MemberVisibilityCanBePrivate") public object CacheControl { diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/utils/ClientEvents.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/utils/ClientEvents.kt index 7245740092a..8a70e85e011 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/utils/ClientEvents.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/utils/ClientEvents.kt @@ -11,30 +11,42 @@ import kotlin.native.concurrent.* /** * Occurs after the creation of a new request + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.utils.HttpRequestCreated) */ public val HttpRequestCreated: EventDefinition = EventDefinition() /** * Occurs before sending the request, and after execution of all interceptors. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.utils.HttpRequestIsReadyForSending) */ public val HttpRequestIsReadyForSending: EventDefinition = EventDefinition() /** * Occurs after responses headers have been received. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.utils.HttpResponseReceived) */ public val HttpResponseReceived: EventDefinition = EventDefinition() /** * Utility class containing response and fail reasons for an [HttpResponseReceiveFailed] event. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.utils.HttpResponseReceiveFail) */ public class HttpResponseReceiveFail(public val response: HttpResponse, public val cause: Throwable) /** * Occurs when an exception is thrown during receiving of body. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.utils.HttpResponseReceiveFailed) */ public val HttpResponseReceiveFailed: EventDefinition = EventDefinition() /** * Occurs when the response is cancelled due to an exception. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.utils.HttpResponseCancelled) */ public val HttpResponseCancelled: EventDefinition = EventDefinition() diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/utils/Content.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/utils/Content.kt index 3ce3dc56b10..493ee7abcc0 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/utils/Content.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/utils/Content.kt @@ -12,6 +12,8 @@ import kotlin.coroutines.* /** * Concrete [OutgoingContent] without a payload. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.utils.EmptyContent) */ public data object EmptyContent : OutgoingContent.NoContent() { override val contentLength: Long = 0 @@ -20,6 +22,8 @@ public data object EmptyContent : OutgoingContent.NoContent() { /** * Generates a new [OutgoingContent] of the same abstract type * but with [OutgoingContent.headers] transformed by the specified [block]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.utils.wrapHeaders) */ public fun OutgoingContent.wrapHeaders(block: (Headers) -> Headers): OutgoingContent = when (this) { is OutgoingContent.NoContent -> object : OutgoingContent.NoContent() { diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/utils/CoroutineUtils.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/utils/CoroutineUtils.kt index 69739a7e225..8b579252d4a 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/utils/CoroutineUtils.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/utils/CoroutineUtils.kt @@ -10,6 +10,9 @@ import kotlinx.coroutines.* /** * Creates [CoroutineDispatcher] for the client with fixed [threadCount] and specified [dispatcherName]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.utils.clientDispatcher) + * * @param threadCount the number of threads for the new [CoroutineDispatcher]. * @param dispatcherName the name of the new [CoroutineDispatcher]. */ diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/utils/ExceptionUtils.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/utils/ExceptionUtils.kt index aa21e7c8e16..6503d0b38a6 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/utils/ExceptionUtils.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/utils/ExceptionUtils.kt @@ -8,5 +8,7 @@ import io.ktor.utils.io.* /** * If the exception contains cause that differs from [CancellationException] returns it otherwise returns itself. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.utils.unwrapCancellationException) */ public expect fun Throwable.unwrapCancellationException(): Throwable diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/utils/HeadersUtils.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/utils/HeadersUtils.kt index b48e3817e68..2db044ee334 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/utils/HeadersUtils.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/utils/HeadersUtils.kt @@ -13,6 +13,8 @@ private val DecompressionListAttribute: AttributeKey> = Attr /** * This function should be used for engines which apply decompression but don't drop compression headers * (like js and Curl) to make sure all the plugins and checks work with the correct content length and encoding. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.utils.dropCompressionHeaders) */ @InternalAPI public fun HeadersBuilder.dropCompressionHeaders( diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/utils/headers.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/utils/headers.kt index c3ed8a83582..5fe0561b0a4 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/utils/headers.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/utils/headers.kt @@ -8,6 +8,8 @@ import io.ktor.http.* /** * Builds an instance of [Headers] using the [block] function. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.utils.buildHeaders) */ public fun buildHeaders(block: HeadersBuilder.() -> Unit = {}): Headers = HeadersBuilder().apply(block).build() diff --git a/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/Js.kt b/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/Js.kt index 3b12c807001..6c4fbee6d43 100644 --- a/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/Js.kt +++ b/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/Js.kt @@ -20,13 +20,19 @@ import io.ktor.utils.io.* * ``` * * You can learn more about client engines from [Engines](https://ktor.io/docs/http-client-engines.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.js.Js) */ public actual data object Js : HttpClientEngineFactory { override fun create(block: JsClientEngineConfig.() -> Unit): HttpClientEngine = JsClientEngine(JsClientEngineConfig().apply(block)) } -/** Configuration for the [Js] client. */ +/** + * Configuration for the [Js] client. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.js.JsClientEngineConfig) + */ public actual open class JsClientEngineConfig : HttpClientEngineConfig() { /** * An `Object` which can contain additional configuration options that should get passed to node-fetch. @@ -43,6 +49,8 @@ public actual open class JsClientEngineConfig : HttpClientEngineConfig() { * } * } * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.js.JsClientEngineConfig.nodeOptions) */ public var nodeOptions: dynamic = js("Object").create(null) } diff --git a/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/JsClientEngine.kt b/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/JsClientEngine.kt index 84c2edc2571..a5bcafdbcad 100644 --- a/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/JsClientEngine.kt +++ b/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/JsClientEngine.kt @@ -162,6 +162,9 @@ private fun org.w3c.fetch.Headers.mapToKtor(method: HttpMethod, attributes: Attr /** * Wrapper for javascript `error` objects. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.js.JsError) + * * @property origin: fail reason */ @Suppress("MemberVisibilityCanBePrivate") diff --git a/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/browser/BrowserFetch.kt b/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/browser/BrowserFetch.kt index 49e7d747d05..350c0d97a41 100644 --- a/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/browser/BrowserFetch.kt +++ b/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/browser/BrowserFetch.kt @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. + * Copyright 2014-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ package io.ktor.client.engine.js.browser @@ -7,13 +7,16 @@ package io.ktor.client.engine.js.browser import io.ktor.client.engine.js.* import io.ktor.client.fetch.* import io.ktor.utils.io.* -import kotlinx.coroutines.* +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.await import org.khronos.webgl.Uint8Array import org.w3c.fetch.Response -import kotlin.coroutines.* +import kotlin.coroutines.resume +import kotlin.coroutines.resumeWithException +import kotlin.coroutines.suspendCoroutine internal fun CoroutineScope.readBodyBrowser(response: Response): ByteReadChannel { - @Suppress("UNCHECKED_CAST_TO_EXTERNAL_INTERFACE") + @Suppress("UnsafeCastFromDynamic") val stream: ReadableStream = response.body ?: return ByteReadChannel.Empty return channelFromStream(stream) } @@ -22,24 +25,24 @@ internal fun CoroutineScope.channelFromStream( stream: ReadableStream ): ByteReadChannel = writer { val reader: ReadableStreamDefaultReader = stream.getReader() - while (true) { - try { + try { + while (true) { val chunk = reader.readChunk() ?: break channel.writeFully(chunk.asByteArray()) channel.flush() - } catch (cause: Throwable) { - reader.cancel(cause) - throw cause } + } catch (cause: Throwable) { + reader.cancel(cause).catch { /* ignore */ }.await() + throw cause } }.channel internal suspend fun ReadableStreamDefaultReader.readChunk(): Uint8Array? = - suspendCancellableCoroutine { continuation -> + suspendCoroutine { continuation -> read().then { val chunk = it.value val result = if (it.done) null else chunk - continuation.resumeWith(Result.success(result)) + continuation.resume(result) }.catch { cause -> continuation.resumeWithException(cause) } diff --git a/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/compatibility/Utils.kt b/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/compatibility/Utils.kt index 0e8afe66f84..168abdc683d 100644 --- a/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/compatibility/Utils.kt +++ b/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/compatibility/Utils.kt @@ -13,6 +13,8 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.InternalCoroutinesApi import kotlinx.coroutines.Job import kotlinx.coroutines.suspendCancellableCoroutine +import kotlin.coroutines.resume +import kotlin.coroutines.resumeWithException import kotlin.js.Promise @OptIn(InternalCoroutinesApi::class) @@ -25,9 +27,7 @@ internal suspend fun commonFetch( val controller = AbortController() init.signal = controller.signal - val abortOnCallCompletion = callJob.invokeOnCompletion(onCancelling = true) { - controller.abort() - } + callJob.invokeOnCompletion(onCancelling = true) { controller.abort() } val promise: Promise = when { PlatformUtils.IS_BROWSER -> fetch(input, init) @@ -39,12 +39,12 @@ internal suspend fun commonFetch( promise.then( onFulfilled = { - continuation.resumeWith(Result.success(it)) + continuation.resume(it) }, onRejected = { - continuation.resumeWith(Result.failure(Error("Fail to fetch", it))) + continuation.resumeWithException(Error("Fail to fetch", it)) } - ).finally { abortOnCallCompletion.dispose() } + ) } private fun AbortController(): AbortController = js("new AbortController()") diff --git a/ktor-client/ktor-client-core/jsAndWasmShared/src/io/ktor/client/HttpClientJs.kt b/ktor-client/ktor-client-core/jsAndWasmShared/src/io/ktor/client/HttpClientJs.kt index db69d907cdc..8d95c54ef10 100644 --- a/ktor-client/ktor-client-core/jsAndWasmShared/src/io/ktor/client/HttpClientJs.kt +++ b/ktor-client/ktor-client-core/jsAndWasmShared/src/io/ktor/client/HttpClientJs.kt @@ -13,6 +13,8 @@ import io.ktor.utils.io.* * * The [HttpClientEngine] is selected from the dependencies. * https://ktor.io/docs/http-client-engines.html + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.HttpClient) */ @KtorDsl public actual fun HttpClient( diff --git a/ktor-client/ktor-client-core/jsAndWasmShared/src/io/ktor/client/engine/ProxyConfigJs.kt b/ktor-client/ktor-client-core/jsAndWasmShared/src/io/ktor/client/engine/ProxyConfigJs.kt index 73008b88c00..fd473e8c7fc 100644 --- a/ktor-client/ktor-client-core/jsAndWasmShared/src/io/ktor/client/engine/ProxyConfigJs.kt +++ b/ktor-client/ktor-client-core/jsAndWasmShared/src/io/ktor/client/engine/ProxyConfigJs.kt @@ -11,15 +11,21 @@ import io.ktor.util.network.* * Proxy configuration. * * See [ProxyBuilder] to create proxy. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.ProxyConfig) */ public actual class ProxyConfig /** * [ProxyConfig] factory. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.ProxyBuilder) */ public actual object ProxyBuilder { /** * Create http proxy from [url]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.ProxyBuilder.http) */ public actual fun http(url: Url): ProxyConfig { error("Proxy unsupported in js client engine.") @@ -27,6 +33,8 @@ public actual object ProxyBuilder { /** * Create socks proxy from [host] and [port]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.ProxyBuilder.socks) */ public actual fun socks(host: String, port: Int): ProxyConfig { error("Proxy unsupported in js client engine.") @@ -37,6 +45,8 @@ public actual object ProxyBuilder { * Resolve remote address of [ProxyConfig]. * * This operations can block. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.resolveAddress) */ public actual fun ProxyConfig.resolveAddress(): NetworkAddress { error("Proxy unsupported in js client engine.") @@ -44,6 +54,8 @@ public actual fun ProxyConfig.resolveAddress(): NetworkAddress { /** * Type of configured proxy. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.type) */ public actual val ProxyConfig.type: ProxyType get() = error("Proxy unsupported in js client engine.") diff --git a/ktor-client/ktor-client-core/jsAndWasmShared/src/io/ktor/client/engine/js/Js.kt b/ktor-client/ktor-client-core/jsAndWasmShared/src/io/ktor/client/engine/js/Js.kt index 76d19cd4e10..47abcdc2a34 100644 --- a/ktor-client/ktor-client-core/jsAndWasmShared/src/io/ktor/client/engine/js/Js.kt +++ b/ktor-client/ktor-client-core/jsAndWasmShared/src/io/ktor/client/engine/js/Js.kt @@ -19,14 +19,22 @@ import io.ktor.client.engine.* * ``` * * You can learn more about client engines from [Engines](https://ktor.io/docs/http-client-engines.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.js.Js) */ public expect object Js : HttpClientEngineFactory -/** Configuration for the [Js] client. */ +/** + * Configuration for the [Js] client. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.js.JsClientEngineConfig) + */ public expect open class JsClientEngineConfig : HttpClientEngineConfig /** * Creates a [Js] client engine. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.js.JsClient) */ @Suppress("FunctionName") @JsName("JsClient") diff --git a/ktor-client/ktor-client-core/jsAndWasmShared/src/io/ktor/client/network/sockets/TimeoutExceptions.jsAndWasm.kt b/ktor-client/ktor-client-core/jsAndWasmShared/src/io/ktor/client/network/sockets/TimeoutExceptions.jsAndWasm.kt index 1fcf2ce0ce3..36cb6ab7a09 100644 --- a/ktor-client/ktor-client-core/jsAndWasmShared/src/io/ktor/client/network/sockets/TimeoutExceptions.jsAndWasm.kt +++ b/ktor-client/ktor-client-core/jsAndWasmShared/src/io/ktor/client/network/sockets/TimeoutExceptions.jsAndWasm.kt @@ -8,6 +8,8 @@ import kotlinx.io.IOException /** * This exception is thrown in case connect timeout exceeded. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.network.sockets.ConnectTimeoutException) */ public actual class ConnectTimeoutException actual constructor( message: String, @@ -18,6 +20,8 @@ public actual open class InterruptedIOException : IOException() /** * This exception is thrown in case socket timeout (read or write) exceeded. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.network.sockets.SocketTimeoutException) */ public actual class SocketTimeoutException internal constructor( override val message: String?, diff --git a/ktor-client/ktor-client-core/jsAndWasmShared/src/io/ktor/client/utils/CoroutineUtilsJs.kt b/ktor-client/ktor-client-core/jsAndWasmShared/src/io/ktor/client/utils/CoroutineUtilsJs.kt index f7ad23089b9..f50d036e0b1 100644 --- a/ktor-client/ktor-client-core/jsAndWasmShared/src/io/ktor/client/utils/CoroutineUtilsJs.kt +++ b/ktor-client/ktor-client-core/jsAndWasmShared/src/io/ktor/client/utils/CoroutineUtilsJs.kt @@ -9,6 +9,8 @@ import kotlinx.coroutines.* /** * Creates [CoroutineDispatcher] for client with fixed [threadCount] and specified [dispatcherName]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.utils.clientDispatcher) */ @InternalAPI public actual fun Dispatchers.clientDispatcher( diff --git a/ktor-client/ktor-client-core/jsAndWasmShared/src/io/ktor/client/utils/ExceptionUtilsJs.kt b/ktor-client/ktor-client-core/jsAndWasmShared/src/io/ktor/client/utils/ExceptionUtilsJs.kt index 2f01ecee8ba..feb96470847 100644 --- a/ktor-client/ktor-client-core/jsAndWasmShared/src/io/ktor/client/utils/ExceptionUtilsJs.kt +++ b/ktor-client/ktor-client-core/jsAndWasmShared/src/io/ktor/client/utils/ExceptionUtilsJs.kt @@ -8,6 +8,8 @@ import io.ktor.utils.io.* /** * If the exception contains cause that differs from [CancellationException] returns it otherwise returns itself. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.utils.unwrapCancellationException) */ public actual fun Throwable.unwrapCancellationException(): Throwable { var exception: Throwable? = this diff --git a/ktor-client/ktor-client-core/jvm/src/io/ktor/client/HttpClientJvm.kt b/ktor-client/ktor-client-core/jvm/src/io/ktor/client/HttpClientJvm.kt index 24632d8fa47..e867ed0cddd 100644 --- a/ktor-client/ktor-client-core/jvm/src/io/ktor/client/HttpClientJvm.kt +++ b/ktor-client/ktor-client-core/jvm/src/io/ktor/client/HttpClientJvm.kt @@ -17,6 +17,8 @@ import java.util.* * An exception is thrown if no implementations found. * * See https://ktor.io/docs/http-client-engines.html + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.HttpClient) */ @KtorDsl public actual fun HttpClient( @@ -29,6 +31,9 @@ public actual fun HttpClient( * to find the default client engine * when [HttpClient] function is called with no particular client implementation specified * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.HttpClientEngineContainer) + * * @property factory that produces HTTP client instances */ public interface HttpClientEngineContainer { diff --git a/ktor-client/ktor-client-core/jvm/src/io/ktor/client/content/LocalFileContent.kt b/ktor-client/ktor-client-core/jvm/src/io/ktor/client/content/LocalFileContent.kt index 5d3c3576057..84896f411c7 100644 --- a/ktor-client/ktor-client-core/jvm/src/io/ktor/client/content/LocalFileContent.kt +++ b/ktor-client/ktor-client-core/jvm/src/io/ktor/client/content/LocalFileContent.kt @@ -14,6 +14,9 @@ import java.io.* /** * OutgoingContent representing a local [file] with a specified [contentType], [expires] date and [caching] * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.content.LocalFileContent) + * * @param file specifies the File to be served to a client */ public class LocalFileContent( @@ -30,6 +33,8 @@ public class LocalFileContent( /** * Creates an instance of [LocalFileContent] for a file designated by [relativePath] in a [baseDir] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.content.LocalFileContent) */ public fun LocalFileContent( baseDir: File, diff --git a/ktor-client/ktor-client-core/jvm/src/io/ktor/client/engine/ProxyConfigJvm.kt b/ktor-client/ktor-client-core/jvm/src/io/ktor/client/engine/ProxyConfigJvm.kt index 417f1f0a6b5..cdd67b6b3fb 100644 --- a/ktor-client/ktor-client-core/jvm/src/io/ktor/client/engine/ProxyConfigJvm.kt +++ b/ktor-client/ktor-client-core/jvm/src/io/ktor/client/engine/ProxyConfigJvm.kt @@ -12,20 +12,28 @@ import java.net.* * Proxy configuration. * * See [ProxyBuilder] to create proxy. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.ProxyConfig) */ public actual typealias ProxyConfig = Proxy /** * [ProxyConfig] factory. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.ProxyBuilder) */ public actual object ProxyBuilder { /** * Create http proxy from [url]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.ProxyBuilder.http) */ public actual fun http(url: Url): ProxyConfig = Proxy(Proxy.Type.HTTP, InetSocketAddress(url.host, url.port)) /** * Create socks proxy from [host] and [port]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.ProxyBuilder.socks) */ public actual fun socks(host: String, port: Int): ProxyConfig = Proxy(Proxy.Type.SOCKS, InetSocketAddress(host, port)) @@ -35,11 +43,15 @@ public actual object ProxyBuilder { * Resolve remote address of [ProxyConfig]. * * This operation can block. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.resolveAddress) */ public actual fun ProxyConfig.resolveAddress(): NetworkAddress = address() /** * Type of configured proxy. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.type) */ public actual val ProxyConfig.type: ProxyType get() = when (type()) { diff --git a/ktor-client/ktor-client-core/jvm/src/io/ktor/client/network/sockets/TimeoutExceptions.kt b/ktor-client/ktor-client-core/jvm/src/io/ktor/client/network/sockets/TimeoutExceptions.kt index f2ad951486e..05c66cc1610 100644 --- a/ktor-client/ktor-client-core/jvm/src/io/ktor/client/network/sockets/TimeoutExceptions.kt +++ b/ktor-client/ktor-client-core/jvm/src/io/ktor/client/network/sockets/TimeoutExceptions.kt @@ -8,6 +8,8 @@ import java.net.* /** * This exception is thrown in case of connect timeout exceeded. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.network.sockets.ConnectTimeoutException) */ @Suppress("ACTUAL_WITHOUT_EXPECT") public actual class ConnectTimeoutException actual constructor( @@ -19,6 +21,8 @@ internal actual typealias InterruptedIOException = java.io.InterruptedIOExceptio /** * This exception is thrown in case socket timeout (read or write) exceeded. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.network.sockets.SocketTimeoutException) */ public actual typealias SocketTimeoutException = java.net.SocketTimeoutException diff --git a/ktor-client/ktor-client-core/jvm/src/io/ktor/client/plugins/cache/storage/FileCacheStorage.kt b/ktor-client/ktor-client-core/jvm/src/io/ktor/client/plugins/cache/storage/FileCacheStorage.kt index b9b0660481d..eaee95be87c 100644 --- a/ktor-client/ktor-client-core/jvm/src/io/ktor/client/plugins/cache/storage/FileCacheStorage.kt +++ b/ktor-client/ktor-client-core/jvm/src/io/ktor/client/plugins/cache/storage/FileCacheStorage.kt @@ -18,6 +18,9 @@ import java.security.* /** * Creates storage that uses file system to store cache data. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.cache.storage.FileStorage) + * * @param directory directory to store cache data. * @param dispatcher dispatcher to use for file operations. */ diff --git a/ktor-client/ktor-client-core/jvm/src/io/ktor/client/request/HttpRequestJvm.kt b/ktor-client/ktor-client-core/jvm/src/io/ktor/client/request/HttpRequestJvm.kt index 658e0b6b0fe..2a67f9a0f51 100644 --- a/ktor-client/ktor-client-core/jvm/src/io/ktor/client/request/HttpRequestJvm.kt +++ b/ktor-client/ktor-client-core/jvm/src/io/ktor/client/request/HttpRequestJvm.kt @@ -8,11 +8,15 @@ import io.ktor.http.* /** * Sets the [HttpRequestBuilder.url] from [url]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.url) */ public fun HttpRequestBuilder.url(url: java.net.URL): URLBuilder = this.url.takeFrom(url) /** * Constructs a [HttpRequestBuilder] from [url]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.invoke) */ public operator fun HttpRequestBuilder.Companion.invoke(url: java.net.URL): HttpRequestBuilder = HttpRequestBuilder().apply { url(url) } diff --git a/ktor-client/ktor-client-core/jvm/src/io/ktor/client/request/buildersJvm.kt b/ktor-client/ktor-client-core/jvm/src/io/ktor/client/request/buildersJvm.kt index a253dc225d7..b8816e9cdf8 100644 --- a/ktor-client/ktor-client-core/jvm/src/io/ktor/client/request/buildersJvm.kt +++ b/ktor-client/ktor-client-core/jvm/src/io/ktor/client/request/buildersJvm.kt @@ -13,6 +13,8 @@ import java.net.* /** * Executes a [HttpClient] request, with the specified [url] as URL and * an optional [block] receiving an [HttpRequestBuilder] for further configuring the request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.request) */ public suspend fun HttpClient.request( url: URL, @@ -27,6 +29,8 @@ public suspend fun HttpClient.request( * an optional [block] receiving an [HttpRequestBuilder] for further configuring the request. * * Tries to receive a specific type [T], if fails, an exception is thrown. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.get) */ public suspend fun HttpClient.get( url: URL, @@ -39,6 +43,8 @@ public suspend fun HttpClient.get( /** * Executes a [HttpClient] POST request, with the specified [url] as URL and * an optional [block] receiving an [HttpRequestBuilder] for further configuring the request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.post) */ public suspend fun HttpClient.post( url: URL, @@ -51,6 +57,8 @@ public suspend fun HttpClient.post( /** * Executes a [HttpClient] PUT request, with the specified [url] as URL and * an optional [block] receiving an [HttpRequestBuilder] for further configuring the request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.put) */ public suspend fun HttpClient.put( url: URL, @@ -63,6 +71,8 @@ public suspend fun HttpClient.put( /** * Executes a [HttpClient] PATCH request, with the specified [url] as URL and * an optional [block] receiving an [HttpRequestBuilder] for further configuring the request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.patch) */ public suspend fun HttpClient.patch( url: URL, @@ -75,6 +85,8 @@ public suspend fun HttpClient.patch( /** * Executes a [HttpClient] OPTIONS request, with the specified [url] as URL and * an optional [block] receiving an [HttpRequestBuilder] for further configuring the request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.options) */ public suspend fun HttpClient.options( url: URL, @@ -87,6 +99,8 @@ public suspend fun HttpClient.options( /** * Executes a [HttpClient] HEAD request, with the specified [url] as URL and * an optional [block] receiving an [HttpRequestBuilder] for further configuring the request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.head) */ public suspend fun HttpClient.head( url: URL, @@ -99,6 +113,8 @@ public suspend fun HttpClient.head( /** * Executes a [HttpClient] HEAD request, with the specified [url] as URL and * an optional [block] receiving an [HttpRequestBuilder] for further configuring the request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.delete) */ public suspend fun HttpClient.delete( url: URL, @@ -111,6 +127,8 @@ public suspend fun HttpClient.delete( /** * Prepares a [HttpClient] request, with the specified [url] as URL and * an optional [block] receiving an [HttpRequestBuilder] for further configuring the request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.prepareRequest) */ public suspend fun HttpClient.prepareRequest( url: URL, @@ -125,6 +143,8 @@ public suspend fun HttpClient.prepareRequest( * an optional [block] receiving an [HttpRequestBuilder] for further configuring the request. * * Tries to receive a specific type [T], if fails, an exception is thrown. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.prepareGet) */ public suspend fun HttpClient.prepareGet( url: URL, @@ -137,6 +157,8 @@ public suspend fun HttpClient.prepareGet( /** * Prepares a [HttpClient] POST request, with the specified [url] as URL and * an optional [block] receiving an [HttpRequestBuilder] for further configuring the request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.preparePost) */ public suspend fun HttpClient.preparePost( url: URL, @@ -149,6 +171,8 @@ public suspend fun HttpClient.preparePost( /** * Prepares a [HttpClient] PUT request, with the specified [url] as URL and * an optional [block] receiving an [HttpRequestBuilder] for further configuring the request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.preparePut) */ public suspend fun HttpClient.preparePut( url: URL, @@ -161,6 +185,8 @@ public suspend fun HttpClient.preparePut( /** * Prepares a [HttpClient] PATCH request, with the specified [url] as URL and * an optional [block] receiving an [HttpRequestBuilder] for further configuring the request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.preparePatch) */ public suspend fun HttpClient.preparePatch( url: URL, @@ -173,6 +199,8 @@ public suspend fun HttpClient.preparePatch( /** * Prepares a [HttpClient] OPTIONS request, with the specified [url] as URL and * an optional [block] receiving an [HttpRequestBuilder] for further configuring the request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.prepareOptions) */ public suspend fun HttpClient.prepareOptions( url: URL, @@ -185,6 +213,8 @@ public suspend fun HttpClient.prepareOptions( /** * Prepares a [HttpClient] HEAD request, with the specified [url] as URL and * an optional [block] receiving an [HttpRequestBuilder] for further configuring the request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.prepareHead) */ public suspend fun HttpClient.prepareHead( url: URL, @@ -197,6 +227,8 @@ public suspend fun HttpClient.prepareHead( /** * Prepares a [HttpClient] HEAD request, with the specified [url] as URL and * an optional [block] receiving an [HttpRequestBuilder] for further configuring the request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.request.prepareDelete) */ public suspend fun HttpClient.prepareDelete( url: URL, diff --git a/ktor-client/ktor-client-core/jvm/src/io/ktor/client/utils/CIOJvm.kt b/ktor-client/ktor-client-core/jvm/src/io/ktor/client/utils/CIOJvm.kt index 2b55fe619a3..27ecb3b3f89 100644 --- a/ktor-client/ktor-client-core/jvm/src/io/ktor/client/utils/CIOJvm.kt +++ b/ktor-client/ktor-client-core/jvm/src/io/ktor/client/utils/CIOJvm.kt @@ -11,5 +11,7 @@ import java.nio.* /** * Singleton pool of [ByteBuffer] objects used for [HttpClient]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.utils.HttpClientDefaultPool) */ public val HttpClientDefaultPool: ByteBufferPool = ByteBufferPool() diff --git a/ktor-client/ktor-client-core/jvm/src/io/ktor/client/utils/CoroutineDispatcherUtils.kt b/ktor-client/ktor-client-core/jvm/src/io/ktor/client/utils/CoroutineDispatcherUtils.kt index 4fbc4397caf..662f73f4dac 100644 --- a/ktor-client/ktor-client-core/jvm/src/io/ktor/client/utils/CoroutineDispatcherUtils.kt +++ b/ktor-client/ktor-client-core/jvm/src/io/ktor/client/utils/CoroutineDispatcherUtils.kt @@ -9,6 +9,8 @@ import kotlinx.coroutines.* /** * Creates [CoroutineDispatcher] based on thread pool of [threadCount] threads. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.utils.clientDispatcher) */ @InternalAPI public actual fun Dispatchers.clientDispatcher( diff --git a/ktor-client/ktor-client-core/jvm/src/io/ktor/client/utils/ExceptionUtilsJvm.kt b/ktor-client/ktor-client-core/jvm/src/io/ktor/client/utils/ExceptionUtilsJvm.kt index 2f01ecee8ba..feb96470847 100644 --- a/ktor-client/ktor-client-core/jvm/src/io/ktor/client/utils/ExceptionUtilsJvm.kt +++ b/ktor-client/ktor-client-core/jvm/src/io/ktor/client/utils/ExceptionUtilsJvm.kt @@ -8,6 +8,8 @@ import io.ktor.utils.io.* /** * If the exception contains cause that differs from [CancellationException] returns it otherwise returns itself. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.utils.unwrapCancellationException) */ public actual fun Throwable.unwrapCancellationException(): Throwable { var exception: Throwable? = this diff --git a/ktor-client/ktor-client-core/nonJvm/src/io/ktor/client/engine/Loader.kt b/ktor-client/ktor-client-core/nonJvm/src/io/ktor/client/engine/Loader.kt index 72624131872..85ea26ac035 100644 --- a/ktor-client/ktor-client-core/nonJvm/src/io/ktor/client/engine/Loader.kt +++ b/ktor-client/ktor-client-core/nonJvm/src/io/ktor/client/engine/Loader.kt @@ -13,12 +13,16 @@ private typealias EngineFactory = HttpClientEngineFactory { private val head = atomic(null) /** * Add engine to head. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.engines.append) */ public fun append(item: EngineFactory) { while (true) { @@ -30,6 +34,9 @@ public object engines : Iterable { } /** + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.engines.iterator) + * * @return unfrozen collection iterator. */ override fun iterator(): Iterator = object : Iterator { diff --git a/ktor-client/ktor-client-core/posix/src/io/ktor/client/HttpClient.kt b/ktor-client/ktor-client-core/posix/src/io/ktor/client/HttpClient.kt index 0695c91c5ce..d84734b68d9 100644 --- a/ktor-client/ktor-client-core/posix/src/io/ktor/client/HttpClient.kt +++ b/ktor-client/ktor-client-core/posix/src/io/ktor/client/HttpClient.kt @@ -12,6 +12,8 @@ import io.ktor.utils.io.* * * The [HttpClientEngine] is selected from the dependencies. * https://ktor.io/docs/http-client-engines.html + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.HttpClient) */ @KtorDsl public actual fun HttpClient( diff --git a/ktor-client/ktor-client-core/posix/src/io/ktor/client/engine/ProxyConfigNative.kt b/ktor-client/ktor-client-core/posix/src/io/ktor/client/engine/ProxyConfigNative.kt index 92f67fc9783..75d4fedddfc 100644 --- a/ktor-client/ktor-client-core/posix/src/io/ktor/client/engine/ProxyConfigNative.kt +++ b/ktor-client/ktor-client-core/posix/src/io/ktor/client/engine/ProxyConfigNative.kt @@ -12,6 +12,9 @@ import io.ktor.util.network.* * * See [ProxyBuilder] to create proxy. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.ProxyConfig) + * * @param url: proxy url address. */ public actual class ProxyConfig(public val url: Url) { @@ -37,15 +40,21 @@ public actual class ProxyConfig(public val url: Url) { * Resolve remote address of [ProxyConfig]. * * This operation can block. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.resolveAddress) */ public actual fun ProxyConfig.resolveAddress(): NetworkAddress = NetworkAddress(url.host, url.port) /** * [ProxyConfig] factory. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.ProxyBuilder) */ public actual object ProxyBuilder { /** * Create http proxy from [url]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.ProxyBuilder.http) */ public actual fun http(url: Url): ProxyConfig { require(url.protocol.name.equals(URLProtocol.HTTP.name, ignoreCase = true)) @@ -55,6 +64,8 @@ public actual object ProxyBuilder { /** * Create socks proxy from [host] and [port]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.ProxyBuilder.socks) */ public actual fun socks(host: String, port: Int): ProxyConfig = ProxyConfig( URLBuilder().apply { @@ -68,6 +79,8 @@ public actual object ProxyBuilder { /** * Type of configured proxy. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.type) */ public actual val ProxyConfig.type: ProxyType get() = when (url.protocol) { diff --git a/ktor-client/ktor-client-core/posix/src/io/ktor/client/network/sockets/TimeoutExceptions.posix.kt b/ktor-client/ktor-client-core/posix/src/io/ktor/client/network/sockets/TimeoutExceptions.posix.kt index ee08f14a876..2585e49b020 100644 --- a/ktor-client/ktor-client-core/posix/src/io/ktor/client/network/sockets/TimeoutExceptions.posix.kt +++ b/ktor-client/ktor-client-core/posix/src/io/ktor/client/network/sockets/TimeoutExceptions.posix.kt @@ -8,6 +8,8 @@ import kotlinx.io.IOException /** * This exception is thrown in case connect timeout exceeded. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.network.sockets.ConnectTimeoutException) */ public actual class ConnectTimeoutException actual constructor( message: String, @@ -18,6 +20,8 @@ public actual open class InterruptedIOException : IOException() /** * This exception is thrown in case socket timeout (read or write) exceeded. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.network.sockets.SocketTimeoutException) */ public actual class SocketTimeoutException internal constructor( override val message: String?, diff --git a/ktor-client/ktor-client-core/posix/src/io/ktor/client/utils/CoroutineUtilsPosix.kt b/ktor-client/ktor-client-core/posix/src/io/ktor/client/utils/CoroutineUtilsPosix.kt index a0fa55d0eb0..a0d74476999 100644 --- a/ktor-client/ktor-client-core/posix/src/io/ktor/client/utils/CoroutineUtilsPosix.kt +++ b/ktor-client/ktor-client-core/posix/src/io/ktor/client/utils/CoroutineUtilsPosix.kt @@ -10,6 +10,8 @@ import kotlinx.coroutines.* /** * Creates [CoroutineDispatcher] for client with fixed [threadCount] and specified [dispatcherName]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.utils.clientDispatcher) */ @InternalAPI public actual fun Dispatchers.clientDispatcher( diff --git a/ktor-client/ktor-client-core/posix/src/io/ktor/client/utils/ExceptionUtilsNative.kt b/ktor-client/ktor-client-core/posix/src/io/ktor/client/utils/ExceptionUtilsNative.kt index 2f01ecee8ba..feb96470847 100644 --- a/ktor-client/ktor-client-core/posix/src/io/ktor/client/utils/ExceptionUtilsNative.kt +++ b/ktor-client/ktor-client-core/posix/src/io/ktor/client/utils/ExceptionUtilsNative.kt @@ -8,6 +8,8 @@ import io.ktor.utils.io.* /** * If the exception contains cause that differs from [CancellationException] returns it otherwise returns itself. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.utils.unwrapCancellationException) */ public actual fun Throwable.unwrapCancellationException(): Throwable { var exception: Throwable? = this diff --git a/ktor-client/ktor-client-core/wasmJs/src/io/ktor/client/engine/js/Js.kt b/ktor-client/ktor-client-core/wasmJs/src/io/ktor/client/engine/js/Js.kt index c134605f869..73411ceef29 100644 --- a/ktor-client/ktor-client-core/wasmJs/src/io/ktor/client/engine/js/Js.kt +++ b/ktor-client/ktor-client-core/wasmJs/src/io/ktor/client/engine/js/Js.kt @@ -21,13 +21,19 @@ import io.ktor.utils.io.* * ``` * * You can learn more about client engines from [Engines](https://ktor.io/docs/http-client-engines.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.js.Js) */ public actual data object Js : HttpClientEngineFactory { override fun create(block: JsClientEngineConfig.() -> Unit): HttpClientEngine = JsClientEngine(JsClientEngineConfig().apply(block)) } -/** Configuration for the [Js] client. */ +/** + * Configuration for the [Js] client. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.js.JsClientEngineConfig) + */ public actual open class JsClientEngineConfig : HttpClientEngineConfig() { /** * An `Object` which can contain additional configuration options that should get passed to node-fetch. @@ -44,6 +50,8 @@ public actual open class JsClientEngineConfig : HttpClientEngineConfig() { * } * } * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.js.JsClientEngineConfig.nodeOptions) */ public var nodeOptions: JsAny = makeJsObject() } diff --git a/ktor-client/ktor-client-core/wasmJs/src/io/ktor/client/engine/js/WasmJsClientEngine.kt b/ktor-client/ktor-client-core/wasmJs/src/io/ktor/client/engine/js/WasmJsClientEngine.kt index 6435738a8ae..799a58932f8 100644 --- a/ktor-client/ktor-client-core/wasmJs/src/io/ktor/client/engine/js/WasmJsClientEngine.kt +++ b/ktor-client/ktor-client-core/wasmJs/src/io/ktor/client/engine/js/WasmJsClientEngine.kt @@ -182,6 +182,9 @@ internal fun org.w3c.fetch.Headers.mapToKtor(method: HttpMethod, attributes: Att /** * Wrapper for javascript `error` objects. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.js.JsError) + * * @property origin: fail reason */ @Suppress("MemberVisibilityCanBePrivate") diff --git a/ktor-client/ktor-client-core/wasmJs/src/io/ktor/client/engine/js/browser/BrowserFetch.kt b/ktor-client/ktor-client-core/wasmJs/src/io/ktor/client/engine/js/browser/BrowserFetch.kt index 3c449fa9ccf..37faaa5390d 100644 --- a/ktor-client/ktor-client-core/wasmJs/src/io/ktor/client/engine/js/browser/BrowserFetch.kt +++ b/ktor-client/ktor-client-core/wasmJs/src/io/ktor/client/engine/js/browser/BrowserFetch.kt @@ -1,5 +1,5 @@ /* - * Copyright 2014-2023 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. + * Copyright 2014-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ package io.ktor.client.engine.js.browser @@ -8,10 +8,13 @@ import io.ktor.client.engine.js.* import io.ktor.client.fetch.* import io.ktor.client.utils.* import io.ktor.utils.io.* -import kotlinx.coroutines.* +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.await import org.khronos.webgl.Uint8Array import org.w3c.fetch.Response -import kotlin.coroutines.* +import kotlin.coroutines.resume +import kotlin.coroutines.resumeWithException +import kotlin.coroutines.suspendCoroutine internal fun CoroutineScope.readBodyBrowser(response: Response): ByteReadChannel { val stream: ReadableStream = response.body?.unsafeCast() ?: return ByteReadChannel.Empty @@ -22,24 +25,24 @@ internal fun CoroutineScope.channelFromStream( stream: ReadableStream ): ByteReadChannel = writer { val reader: ReadableStreamDefaultReader = stream.getReader() - while (true) { - try { + try { + while (true) { val chunk = reader.readChunk() ?: break channel.writeFully(chunk.asByteArray()) channel.flush() - } catch (cause: Throwable) { - reader.cancel(cause.toJsReference()) - throw cause } + } catch (cause: Throwable) { + reader.cancel(cause.toJsReference()).catch { null }.await() + throw cause } }.channel internal suspend fun ReadableStreamDefaultReader.readChunk(): Uint8Array? = - suspendCancellableCoroutine { continuation -> + suspendCoroutine { continuation -> read().then { stream: ReadableStreamReadResult -> val chunk = stream.value val result = if (stream.done || chunk == null) null else chunk - continuation.resumeWith(Result.success(result)) + continuation.resume(result) null }.catch { cause: JsAny -> continuation.resumeWithException(JsError(cause)) diff --git a/ktor-client/ktor-client-core/wasmJs/src/io/ktor/client/engine/js/compatibility/Utils.kt b/ktor-client/ktor-client-core/wasmJs/src/io/ktor/client/engine/js/compatibility/Utils.kt index 579c5eab7dd..fa24ccd641c 100644 --- a/ktor-client/ktor-client-core/wasmJs/src/io/ktor/client/engine/js/compatibility/Utils.kt +++ b/ktor-client/ktor-client-core/wasmJs/src/io/ktor/client/engine/js/compatibility/Utils.kt @@ -14,6 +14,8 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.InternalCoroutinesApi import kotlinx.coroutines.Job import kotlinx.coroutines.suspendCancellableCoroutine +import kotlin.coroutines.resume +import kotlin.coroutines.resumeWithException import kotlin.js.Promise @OptIn(InternalCoroutinesApi::class) @@ -26,9 +28,7 @@ internal suspend fun commonFetch( val controller = AbortController() init.signal = controller.signal - val abortOnCallCompletion = callJob.invokeOnCompletion(onCancelling = true) { - controller.abort() - } + callJob.invokeOnCompletion(onCancelling = true) { controller.abort() } val promise: Promise = when { PlatformUtils.IS_BROWSER -> fetch(input, init) @@ -45,14 +45,14 @@ internal suspend fun commonFetch( promise.then( onFulfilled = { x: JsAny -> - continuation.resumeWith(Result.success(x.unsafeCast())) + continuation.resume(x.unsafeCast()) null }, onRejected = { it: JsAny -> - continuation.resumeWith(Result.failure(Error("Fail to fetch", JsError(it)))) + continuation.resumeWithException(Error("Fail to fetch", JsError(it))) null } - ).finally { abortOnCallCompletion.dispose() } + ) } private fun AbortController(): AbortController { diff --git a/ktor-client/ktor-client-curl/desktop/src/io/ktor/client/engine/curl/Curl.kt b/ktor-client/ktor-client-curl/desktop/src/io/ktor/client/engine/curl/Curl.kt index d6400bff781..8a6af547241 100644 --- a/ktor-client/ktor-client-curl/desktop/src/io/ktor/client/engine/curl/Curl.kt +++ b/ktor-client/ktor-client-curl/desktop/src/io/ktor/client/engine/curl/Curl.kt @@ -44,6 +44,8 @@ private val initHook = Curl * ``` * * You can learn more about client engines from [Engines](https://ktor.io/docs/http-client-engines.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.curl.Curl) */ @OptIn(InternalAPI::class) public data object Curl : HttpClientEngineFactory { diff --git a/ktor-client/ktor-client-curl/desktop/src/io/ktor/client/engine/curl/CurlClientEngineConfig.kt b/ktor-client/ktor-client-curl/desktop/src/io/ktor/client/engine/curl/CurlClientEngineConfig.kt index 6899e374c33..ab74d02b34f 100644 --- a/ktor-client/ktor-client-curl/desktop/src/io/ktor/client/engine/curl/CurlClientEngineConfig.kt +++ b/ktor-client/ktor-client-curl/desktop/src/io/ktor/client/engine/curl/CurlClientEngineConfig.kt @@ -8,6 +8,8 @@ import io.ktor.client.engine.* /** * A configuration for the [Curl] client engine. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.curl.CurlClientEngineConfig) */ public class CurlClientEngineConfig : HttpClientEngineConfig() { /** @@ -17,11 +19,15 @@ public class CurlClientEngineConfig : HttpClientEngineConfig() { /** * Sets path to Certificate Authority (CA) bundle using `CURLOPT_CAINFO`. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.curl.CurlClientEngineConfig.caInfo) */ public var caInfo: String? = null /** * Sets directory that holds Certificate Authority (CA) certificates using `CURLOPT_CAPATH`. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.curl.CurlClientEngineConfig.caPath) */ public var caPath: String? = null @@ -31,6 +37,8 @@ public class CurlClientEngineConfig : HttpClientEngineConfig() { * Similar to `-k/--insecure` curl option. * * Setting this property to `false` is recommended only for testing purposes. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.curl.CurlClientEngineConfig.sslVerify) */ public var sslVerify: Boolean = true } diff --git a/ktor-client/ktor-client-curl/desktop/test/io/ktor/client/engine/curl/test/CurlProxyTest.kt b/ktor-client/ktor-client-curl/desktop/test/io/ktor/client/engine/curl/test/CurlProxyTest.kt index 12a8729b635..e81a041c2c9 100644 --- a/ktor-client/ktor-client-curl/desktop/test/io/ktor/client/engine/curl/test/CurlProxyTest.kt +++ b/ktor-client/ktor-client-curl/desktop/test/io/ktor/client/engine/curl/test/CurlProxyTest.kt @@ -22,6 +22,8 @@ private const val TEST_SERVER_HTTPS = "https://localhost:8089/" /** * This is a temporary tests that should be moved to the general test suite * once we support TLS options in client configs to connect to the local test TLS server. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.curl.test.CurlProxyTest) */ class CurlProxyTest : ClientEngineTest(Curl) { diff --git a/ktor-client/ktor-client-darwin-legacy/darwin/src/io/ktor/client/engine/darwin/DarwinLegacy.kt b/ktor-client/ktor-client-darwin-legacy/darwin/src/io/ktor/client/engine/darwin/DarwinLegacy.kt index 21303503fe7..0fa30ab4b69 100644 --- a/ktor-client/ktor-client-darwin-legacy/darwin/src/io/ktor/client/engine/darwin/DarwinLegacy.kt +++ b/ktor-client/ktor-client-darwin-legacy/darwin/src/io/ktor/client/engine/darwin/DarwinLegacy.kt @@ -30,6 +30,8 @@ private val initHook = DarwinLegacy * ``` * * You can learn more about client engines from [Engines](https://ktor.io/docs/http-client-engines.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.DarwinLegacy) */ @OptIn(InternalAPI::class) public data object DarwinLegacy : HttpClientEngineFactory { diff --git a/ktor-client/ktor-client-darwin-legacy/darwin/src/io/ktor/client/engine/darwin/DarwinLegacyClientEngineConfig.kt b/ktor-client/ktor-client-darwin-legacy/darwin/src/io/ktor/client/engine/darwin/DarwinLegacyClientEngineConfig.kt index 14e3c9c1c26..16eccd03ba8 100644 --- a/ktor-client/ktor-client-darwin-legacy/darwin/src/io/ktor/client/engine/darwin/DarwinLegacyClientEngineConfig.kt +++ b/ktor-client/ktor-client-darwin-legacy/darwin/src/io/ktor/client/engine/darwin/DarwinLegacyClientEngineConfig.kt @@ -10,6 +10,8 @@ import platform.Foundation.* /** * A challenge handler type for [NSURLSession]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.ChallengeHandler) */ @OptIn(UnsafeNumber::class) public typealias ChallengeHandler = ( @@ -21,10 +23,14 @@ public typealias ChallengeHandler = ( /** * A configuration for the [DarwinLegacy] client engine. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.DarwinLegacyClientEngineConfig) */ public class DarwinLegacyClientEngineConfig : HttpClientEngineConfig() { /** * A request configuration. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.DarwinLegacyClientEngineConfig.requestConfig) */ public var requestConfig: NSMutableURLRequest.() -> Unit = {} @Deprecated( @@ -36,6 +42,8 @@ public class DarwinLegacyClientEngineConfig : HttpClientEngineConfig() { /** * A session configuration. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.DarwinLegacyClientEngineConfig.sessionConfig) */ public var sessionConfig: NSURLSessionConfiguration.() -> Unit = {} @Deprecated( @@ -47,6 +55,8 @@ public class DarwinLegacyClientEngineConfig : HttpClientEngineConfig() { /** * Handles the challenge of HTTP responses [NSURLSession]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.DarwinLegacyClientEngineConfig.challengeHandler) */ @OptIn(UnsafeNumber::class) public var challengeHandler: ChallengeHandler? = null @@ -54,6 +64,8 @@ public class DarwinLegacyClientEngineConfig : HttpClientEngineConfig() { /** * Specifies a session to use for making HTTP requests. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.DarwinLegacyClientEngineConfig.preconfiguredSession) */ public var preconfiguredSession: NSURLSession? = null private set @@ -65,6 +77,8 @@ public class DarwinLegacyClientEngineConfig : HttpClientEngineConfig() { /** * Appends a block with the [NSMutableURLRequest] configuration to [requestConfig]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.DarwinLegacyClientEngineConfig.configureRequest) */ public fun configureRequest(block: NSMutableURLRequest.() -> Unit) { val old = requestConfig @@ -78,6 +92,8 @@ public class DarwinLegacyClientEngineConfig : HttpClientEngineConfig() { /** * Appends a block with the [NSURLSessionConfiguration] configuration to [sessionConfig]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.DarwinLegacyClientEngineConfig.configureSession) */ public fun configureSession(block: NSURLSessionConfiguration.() -> Unit) { val old = sessionConfig @@ -92,6 +108,8 @@ public class DarwinLegacyClientEngineConfig : HttpClientEngineConfig() { /** * Set a [session] to be used to make HTTP requests, [null] to create default session. * If the preconfigured session is set, [configureSession] block will be ignored. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.DarwinLegacyClientEngineConfig.usePreconfiguredSession) */ @Deprecated("Please use method with delegate parameter", level = DeprecationLevel.ERROR) public fun usePreconfiguredSession(session: NSURLSession?) { @@ -103,6 +121,9 @@ public class DarwinLegacyClientEngineConfig : HttpClientEngineConfig() { * If the preconfigured session is set, [configureSession] and [handleChallenge] blocks will be ignored. * * The [session] must be created with [KtorLegacyNSURLSessionDelegate] as a delegate. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.DarwinLegacyClientEngineConfig.usePreconfiguredSession) + * * @see [KtorLegacyNSURLSessionDelegate] for details. */ public fun usePreconfiguredSession(session: NSURLSession, delegate: KtorLegacyNSURLSessionDelegate) { @@ -111,6 +132,8 @@ public class DarwinLegacyClientEngineConfig : HttpClientEngineConfig() { /** * Sets the [block] as an HTTP request challenge handler replacing the old one. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.DarwinLegacyClientEngineConfig.handleChallenge) */ @OptIn(UnsafeNumber::class) public fun handleChallenge(block: ChallengeHandler) { diff --git a/ktor-client/ktor-client-darwin-legacy/darwin/src/io/ktor/client/engine/darwin/KtorLegacyNSURLSessionDelegate.kt b/ktor-client/ktor-client-darwin-legacy/darwin/src/io/ktor/client/engine/darwin/KtorLegacyNSURLSessionDelegate.kt index 8c11ea0bbdb..8a3afc6f6c7 100644 --- a/ktor-client/ktor-client-darwin-legacy/darwin/src/io/ktor/client/engine/darwin/KtorLegacyNSURLSessionDelegate.kt +++ b/ktor-client/ktor-client-darwin-legacy/darwin/src/io/ktor/client/engine/darwin/KtorLegacyNSURLSessionDelegate.kt @@ -15,6 +15,8 @@ import kotlin.coroutines.* /** * Creates an instance of [KtorLegacyNSURLSessionDelegate] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.KtorLegacyNSURLSessionDelegate) */ @OptIn(UnsafeNumber::class) public fun KtorLegacyNSURLSessionDelegate(): KtorLegacyNSURLSessionDelegate { @@ -33,6 +35,8 @@ public fun KtorLegacyNSURLSessionDelegate(): KtorLegacyNSURLSessionDelegate { * * URLSession:dataTask:didReceiveData: * * URLSession:task:didCompleteWithError: * * URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler: + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.KtorLegacyNSURLSessionDelegate) */ @OptIn(UnsafeNumber::class) public class KtorLegacyNSURLSessionDelegate( @@ -65,6 +69,8 @@ public class KtorLegacyNSURLSessionDelegate( /** * Disable embedded redirects. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.KtorLegacyNSURLSessionDelegate.URLSession) */ override fun URLSession( session: NSURLSession, @@ -78,6 +84,8 @@ public class KtorLegacyNSURLSessionDelegate( /** * Handle challenge. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.KtorLegacyNSURLSessionDelegate.URLSession) */ override fun URLSession( session: NSURLSession, diff --git a/ktor-client/ktor-client-darwin-legacy/darwin/src/io/ktor/client/engine/darwin/certificates/LegacyCertificatePinner.kt b/ktor-client/ktor-client-darwin-legacy/darwin/src/io/ktor/client/engine/darwin/certificates/LegacyCertificatePinner.kt index 7ba1cfea407..6a51772253e 100644 --- a/ktor-client/ktor-client-darwin-legacy/darwin/src/io/ktor/client/engine/darwin/certificates/LegacyCertificatePinner.kt +++ b/ktor-client/ktor-client-darwin-legacy/darwin/src/io/ktor/client/engine/darwin/certificates/LegacyCertificatePinner.kt @@ -106,6 +106,8 @@ import platform.Security.* * This class was heavily inspired by OkHttp, which is a great Http library for Android * https://square.github.io/okhttp/4.x/okhttp/okhttp3/-certificate-pinner/ * https://github.com/square/okhttp/blob/master/okhttp/src/main/java/okhttp3/CertificatePinner.kt + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.certificates.LegacyCertificatePinner) */ @OptIn(UnsafeNumber::class) public data class LegacyCertificatePinner( @@ -393,6 +395,8 @@ public data class LegacyCertificatePinner( /** * Builds a configured [LegacyCertificatePinner]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.certificates.LegacyCertificatePinner.Builder) */ public data class Builder( private val pinnedCertificates: MutableList = mutableListOf(), @@ -401,6 +405,9 @@ public data class LegacyCertificatePinner( /** * Pins certificates for `pattern`. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.certificates.LegacyCertificatePinner.Builder.add) + * * @param pattern lower-case host name or wildcard pattern such as `*.example.com`. * @param pins SHA-256 or SHA-1 hashes. Each pin is a hash of a certificate's * Subject Public Key Info, base64-encoded and prefixed with either `sha256/` or `sha1/`. @@ -420,6 +427,9 @@ public data class LegacyCertificatePinner( /** * Whether to valid the trust of the server * https://developer.apple.com/documentation/security/2980705-sectrustevaluatewitherror + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.certificates.LegacyCertificatePinner.Builder.validateTrust) + * * @param validateTrust * @return The [Builder] so calls can be chained */ @@ -429,6 +439,9 @@ public data class LegacyCertificatePinner( /** * Build into a [LegacyCertificatePinner] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.certificates.LegacyCertificatePinner.Builder.build) + * * @return [LegacyCertificatePinner] */ public fun build(): LegacyCertificatePinner = LegacyCertificatePinner( diff --git a/ktor-client/ktor-client-darwin-legacy/darwin/src/io/ktor/client/engine/darwin/certificates/LegacyPinnedCertificate.kt b/ktor-client/ktor-client-darwin-legacy/darwin/src/io/ktor/client/engine/darwin/certificates/LegacyPinnedCertificate.kt index df754f64fa1..475b9b5abbd 100644 --- a/ktor-client/ktor-client-darwin-legacy/darwin/src/io/ktor/client/engine/darwin/certificates/LegacyPinnedCertificate.kt +++ b/ktor-client/ktor-client-darwin-legacy/darwin/src/io/ktor/client/engine/darwin/certificates/LegacyPinnedCertificate.kt @@ -11,6 +11,8 @@ import io.ktor.client.engine.darwin.certificates.LegacyCertificatesInfo.HASH_ALG /** * Represents a pinned certificate. Recommended using [Builder.add] to construct * [LegacyCertificatePinner] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.certificates.LegacyPinnedCertificate) */ public data class LegacyPinnedCertificate( /** @@ -66,6 +68,9 @@ public data class LegacyPinnedCertificate( public companion object { /** * Create a new Pin + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.certificates.LegacyPinnedCertificate.Companion.new) + * * @param pattern The hostname pattern * @param pin The hash to pin * @return [LegacyPinnedCertificate] The new pin diff --git a/ktor-client/ktor-client-darwin/darwin/src/io/ktor/client/engine/darwin/Darwin.kt b/ktor-client/ktor-client-darwin/darwin/src/io/ktor/client/engine/darwin/Darwin.kt index 8e76e3e0ec3..0b34fa1020d 100644 --- a/ktor-client/ktor-client-darwin/darwin/src/io/ktor/client/engine/darwin/Darwin.kt +++ b/ktor-client/ktor-client-darwin/darwin/src/io/ktor/client/engine/darwin/Darwin.kt @@ -30,6 +30,8 @@ private val initHook = Darwin * ``` * * You can learn more about client engines from [Engines](https://ktor.io/docs/http-client-engines.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.Darwin) */ @OptIn(InternalAPI::class) public data object Darwin : HttpClientEngineFactory { diff --git a/ktor-client/ktor-client-darwin/darwin/src/io/ktor/client/engine/darwin/DarwinClientEngineConfig.kt b/ktor-client/ktor-client-darwin/darwin/src/io/ktor/client/engine/darwin/DarwinClientEngineConfig.kt index 1f798e332c4..c6ed3c31a8b 100644 --- a/ktor-client/ktor-client-darwin/darwin/src/io/ktor/client/engine/darwin/DarwinClientEngineConfig.kt +++ b/ktor-client/ktor-client-darwin/darwin/src/io/ktor/client/engine/darwin/DarwinClientEngineConfig.kt @@ -11,6 +11,8 @@ import platform.Foundation.* /** * A challenge handler type for [NSURLSession]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.ChallengeHandler) */ @OptIn(UnsafeNumber::class) public typealias ChallengeHandler = ( @@ -22,10 +24,14 @@ public typealias ChallengeHandler = ( /** * A configuration for the [Darwin] client engine. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.DarwinClientEngineConfig) */ public class DarwinClientEngineConfig : HttpClientEngineConfig() { /** * A request configuration. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.DarwinClientEngineConfig.requestConfig) */ public var requestConfig: NSMutableURLRequest.() -> Unit = {} @Deprecated( @@ -37,6 +43,8 @@ public class DarwinClientEngineConfig : HttpClientEngineConfig() { /** * A session configuration. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.DarwinClientEngineConfig.sessionConfig) */ public var sessionConfig: NSURLSessionConfiguration.() -> Unit = {} @Deprecated( @@ -48,6 +56,8 @@ public class DarwinClientEngineConfig : HttpClientEngineConfig() { /** * Handles the challenge of HTTP responses [NSURLSession]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.DarwinClientEngineConfig.challengeHandler) */ @OptIn(UnsafeNumber::class) public var challengeHandler: ChallengeHandler? = null @@ -55,6 +65,8 @@ public class DarwinClientEngineConfig : HttpClientEngineConfig() { /** * Specifies a session to use for making HTTP requests. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.DarwinClientEngineConfig.preconfiguredSession) */ public var preconfiguredSession: NSURLSession? = null private set @@ -66,6 +78,8 @@ public class DarwinClientEngineConfig : HttpClientEngineConfig() { /** * Appends a block with the [NSMutableURLRequest] configuration to [requestConfig]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.DarwinClientEngineConfig.configureRequest) */ public fun configureRequest(block: NSMutableURLRequest.() -> Unit) { val old = requestConfig @@ -79,6 +93,8 @@ public class DarwinClientEngineConfig : HttpClientEngineConfig() { /** * Appends a block with the [NSURLSessionConfiguration] configuration to [sessionConfig]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.DarwinClientEngineConfig.configureSession) */ public fun configureSession(block: NSURLSessionConfiguration.() -> Unit) { val old = sessionConfig @@ -93,6 +109,8 @@ public class DarwinClientEngineConfig : HttpClientEngineConfig() { /** * Set a [session] to be used to make HTTP requests, [null] to create default session. * If the preconfigured session is set, [configureSession] block will be ignored. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.DarwinClientEngineConfig.usePreconfiguredSession) */ @Deprecated("Please use method with delegate parameter", level = DeprecationLevel.ERROR) public fun usePreconfiguredSession(session: NSURLSession?) { @@ -116,6 +134,9 @@ public class DarwinClientEngineConfig : HttpClientEngineConfig() { * usePreconfiguredSession(session, delegate) * ``` * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.DarwinClientEngineConfig.usePreconfiguredSession) + * * @see [KtorNSURLSessionDelegate] for details. */ public fun usePreconfiguredSession(session: NSURLSession, delegate: KtorNSURLSessionDelegate) { @@ -134,6 +155,8 @@ public class DarwinClientEngineConfig : HttpClientEngineConfig() { /** * Sets the [block] as an HTTP request challenge handler replacing the old one. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.DarwinClientEngineConfig.handleChallenge) */ @OptIn(UnsafeNumber::class) public fun handleChallenge(block: ChallengeHandler) { diff --git a/ktor-client/ktor-client-darwin/darwin/src/io/ktor/client/engine/darwin/KtorNSURLSessionDelegate.kt b/ktor-client/ktor-client-darwin/darwin/src/io/ktor/client/engine/darwin/KtorNSURLSessionDelegate.kt index e5daebab7f8..7ae5a81d514 100644 --- a/ktor-client/ktor-client-darwin/darwin/src/io/ktor/client/engine/darwin/KtorNSURLSessionDelegate.kt +++ b/ktor-client/ktor-client-darwin/darwin/src/io/ktor/client/engine/darwin/KtorNSURLSessionDelegate.kt @@ -19,6 +19,8 @@ private const val WS_REQUESTS_INITIAL_CAPACITY = 16 /** * Creates an instance of [KtorNSURLSessionDelegate] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.KtorNSURLSessionDelegate) */ @OptIn(UnsafeNumber::class) public fun KtorNSURLSessionDelegate(): KtorNSURLSessionDelegate { @@ -41,6 +43,8 @@ public fun KtorNSURLSessionDelegate(): KtorNSURLSessionDelegate { * For WebSockets to work, it's important that users call these functions: * * URLSession:webSocketTask:didOpenWithProtocol: * * URLSession:webSocketTask:didCloseWithCode:reason: + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.KtorNSURLSessionDelegate) */ @OptIn(UnsafeNumber::class) public class KtorNSURLSessionDelegate( @@ -112,6 +116,8 @@ public class KtorNSURLSessionDelegate( /** * Disable embedded redirects. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.KtorNSURLSessionDelegate.URLSession) */ override fun URLSession( session: NSURLSession, @@ -125,6 +131,8 @@ public class KtorNSURLSessionDelegate( /** * Handle challenge. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.KtorNSURLSessionDelegate.URLSession) */ override fun URLSession( session: NSURLSession, diff --git a/ktor-client/ktor-client-darwin/darwin/src/io/ktor/client/engine/darwin/certificates/CertificatePinner.kt b/ktor-client/ktor-client-darwin/darwin/src/io/ktor/client/engine/darwin/certificates/CertificatePinner.kt index a2df4b7db53..c5ccc905c30 100644 --- a/ktor-client/ktor-client-darwin/darwin/src/io/ktor/client/engine/darwin/certificates/CertificatePinner.kt +++ b/ktor-client/ktor-client-darwin/darwin/src/io/ktor/client/engine/darwin/certificates/CertificatePinner.kt @@ -105,6 +105,8 @@ import platform.Security.* * This class was heavily inspired by OkHttp, which is a great Http library for Android * https://square.github.io/okhttp/4.x/okhttp/okhttp3/-certificate-pinner/ * https://github.com/square/okhttp/blob/master/okhttp/src/main/java/okhttp3/CertificatePinner.kt + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.certificates.CertificatePinner) */ @OptIn(UnsafeNumber::class) public data class CertificatePinner( @@ -392,6 +394,8 @@ public data class CertificatePinner( /** * Builds a configured [CertificatePinner]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.certificates.CertificatePinner.Builder) */ public data class Builder( private val pinnedCertificates: MutableList = mutableListOf(), @@ -400,6 +404,9 @@ public data class CertificatePinner( /** * Pins certificates for `pattern`. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.certificates.CertificatePinner.Builder.add) + * * @param pattern lower-case host name or wildcard pattern such as `*.example.com`. * @param pins SHA-256 or SHA-1 hashes. Each pin is a hash of a certificate's * Subject Public Key Info, base64-encoded and prefixed with either `sha256/` or `sha1/`. @@ -419,6 +426,9 @@ public data class CertificatePinner( /** * Whether to valid the trust of the server * https://developer.apple.com/documentation/security/2980705-sectrustevaluatewitherror + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.certificates.CertificatePinner.Builder.validateTrust) + * * @param validateTrust * @return The [Builder] so calls can be chained */ @@ -428,6 +438,9 @@ public data class CertificatePinner( /** * Build into a [CertificatePinner] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.certificates.CertificatePinner.Builder.build) + * * @return [CertificatePinner] */ public fun build(): CertificatePinner = CertificatePinner( diff --git a/ktor-client/ktor-client-darwin/darwin/src/io/ktor/client/engine/darwin/certificates/PinnedCertificate.kt b/ktor-client/ktor-client-darwin/darwin/src/io/ktor/client/engine/darwin/certificates/PinnedCertificate.kt index 5ea8379aa08..5e7714b6f16 100644 --- a/ktor-client/ktor-client-darwin/darwin/src/io/ktor/client/engine/darwin/certificates/PinnedCertificate.kt +++ b/ktor-client/ktor-client-darwin/darwin/src/io/ktor/client/engine/darwin/certificates/PinnedCertificate.kt @@ -11,6 +11,8 @@ import io.ktor.client.engine.darwin.certificates.CertificatesInfo.HASH_ALGORITHM /** * Represents a pinned certificate. Recommended using [Builder.add] to construct * [CertificatePinner] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.certificates.PinnedCertificate) */ public data class PinnedCertificate( /** @@ -66,6 +68,9 @@ public data class PinnedCertificate( public companion object { /** * Create a new Pin + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.darwin.certificates.PinnedCertificate.Companion.new) + * * @param pattern The hostname pattern * @param pin The hash to pin * @return [PinnedCertificate] The new pin diff --git a/ktor-client/ktor-client-java/jvm/src/io/ktor/client/engine/java/Java.kt b/ktor-client/ktor-client-java/jvm/src/io/ktor/client/engine/java/Java.kt index 753a6362e54..ec684a54c80 100644 --- a/ktor-client/ktor-client-java/jvm/src/io/ktor/client/engine/java/Java.kt +++ b/ktor-client/ktor-client-java/jvm/src/io/ktor/client/engine/java/Java.kt @@ -24,6 +24,8 @@ import io.ktor.client.engine.* * ``` * * You can learn more about client engines from [Engines](https://ktor.io/docs/http-client-engines.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.java.Java) */ public data object Java : HttpClientEngineFactory { override fun create(block: JavaHttpConfig.() -> Unit): HttpClientEngine = diff --git a/ktor-client/ktor-client-java/jvm/src/io/ktor/client/engine/java/JavaHttpConfig.kt b/ktor-client/ktor-client-java/jvm/src/io/ktor/client/engine/java/JavaHttpConfig.kt index 13a2dbdc166..a4d8523dc02 100644 --- a/ktor-client/ktor-client-java/jvm/src/io/ktor/client/engine/java/JavaHttpConfig.kt +++ b/ktor-client/ktor-client-java/jvm/src/io/ktor/client/engine/java/JavaHttpConfig.kt @@ -9,11 +9,15 @@ import java.net.http.* /** * A configuration for the [Java] client engine. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.java.JavaHttpConfig) */ public class JavaHttpConfig : HttpClientEngineConfig() { /** * An HTTP version to use. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.java.JavaHttpConfig.protocolVersion) */ public var protocolVersion: HttpClient.Version = HttpClient.Version.HTTP_1_1 @@ -23,6 +27,8 @@ public class JavaHttpConfig : HttpClientEngineConfig() { /** * Configure [HttpClient] using [HttpClient.Builder]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.java.JavaHttpConfig.config) */ public fun config(block: HttpClient.Builder.() -> Unit) { val oldConfig = config diff --git a/ktor-client/ktor-client-jetty-jakarta/jvm/src/io/ktor/client/engine/jetty/jakarta/Jetty.kt b/ktor-client/ktor-client-jetty-jakarta/jvm/src/io/ktor/client/engine/jetty/jakarta/Jetty.kt index 2b5d62be189..83fc83f1bbb 100644 --- a/ktor-client/ktor-client-jetty-jakarta/jvm/src/io/ktor/client/engine/jetty/jakarta/Jetty.kt +++ b/ktor-client/ktor-client-jetty-jakarta/jvm/src/io/ktor/client/engine/jetty/jakarta/Jetty.kt @@ -25,6 +25,8 @@ import io.ktor.utils.io.* * ``` * * You can learn more about client engines from [Engines](https://ktor.io/docs/http-client-engines.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.jetty.jakarta.Jetty) */ public data object Jetty : HttpClientEngineFactory { override fun create(block: JettyEngineConfig.() -> Unit): HttpClientEngine = diff --git a/ktor-client/ktor-client-jetty-jakarta/jvm/src/io/ktor/client/engine/jetty/jakarta/JettyEngineConfig.kt b/ktor-client/ktor-client-jetty-jakarta/jvm/src/io/ktor/client/engine/jetty/jakarta/JettyEngineConfig.kt index 556b82eb3e7..fce97c38ada 100644 --- a/ktor-client/ktor-client-jetty-jakarta/jvm/src/io/ktor/client/engine/jetty/jakarta/JettyEngineConfig.kt +++ b/ktor-client/ktor-client-jetty-jakarta/jvm/src/io/ktor/client/engine/jetty/jakarta/JettyEngineConfig.kt @@ -10,22 +10,30 @@ import org.eclipse.jetty.util.ssl.* /** * A configuration for the [Jetty] client engine. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.jetty.jakarta.JettyEngineConfig) */ public class JettyEngineConfig : HttpClientEngineConfig() { internal var config: (HTTP2Client) -> Unit = {} /** * Allows you to configure [SSL](https://ktor.io/docs/client-ssl.html) settings for this engine. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.jetty.jakarta.JettyEngineConfig.sslContextFactory) */ public var sslContextFactory: SslContextFactory = SslContextFactory.Client() /** * Specifies the size of cache that keeps recently used [JettyHttp2Engine] instances. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.jetty.jakarta.JettyEngineConfig.clientCacheSize) */ public var clientCacheSize: Int = 10 /** * Configures a raw Jetty client. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.jetty.jakarta.JettyEngineConfig.configureClient) */ public fun configureClient(block: (HTTP2Client) -> Unit) { val current = config diff --git a/ktor-client/ktor-client-jetty/jvm/src/io/ktor/client/engine/jetty/Jetty.kt b/ktor-client/ktor-client-jetty/jvm/src/io/ktor/client/engine/jetty/Jetty.kt index d61b64a6576..ed597fdd0bf 100644 --- a/ktor-client/ktor-client-jetty/jvm/src/io/ktor/client/engine/jetty/Jetty.kt +++ b/ktor-client/ktor-client-jetty/jvm/src/io/ktor/client/engine/jetty/Jetty.kt @@ -25,6 +25,8 @@ import io.ktor.utils.io.* * ``` * * You can learn more about client engines from [Engines](https://ktor.io/docs/http-client-engines.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.jetty.Jetty) */ public data object Jetty : HttpClientEngineFactory { override fun create(block: JettyEngineConfig.() -> Unit): HttpClientEngine = diff --git a/ktor-client/ktor-client-jetty/jvm/src/io/ktor/client/engine/jetty/JettyEngineConfig.kt b/ktor-client/ktor-client-jetty/jvm/src/io/ktor/client/engine/jetty/JettyEngineConfig.kt index 0928baec242..065a3f9990a 100644 --- a/ktor-client/ktor-client-jetty/jvm/src/io/ktor/client/engine/jetty/JettyEngineConfig.kt +++ b/ktor-client/ktor-client-jetty/jvm/src/io/ktor/client/engine/jetty/JettyEngineConfig.kt @@ -10,22 +10,30 @@ import org.eclipse.jetty.util.ssl.* /** * A configuration for the [Jetty] client engine. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.jetty.JettyEngineConfig) */ public class JettyEngineConfig : HttpClientEngineConfig() { internal var config: (HTTP2Client) -> Unit = {} /** * Allows you to configure [SSL](https://ktor.io/docs/client-ssl.html) settings for this engine. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.jetty.JettyEngineConfig.sslContextFactory) */ public var sslContextFactory: SslContextFactory = SslContextFactory.Client() /** * Specifies the size of cache that keeps recently used [JettyHttp2Engine] instances. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.jetty.JettyEngineConfig.clientCacheSize) */ public var clientCacheSize: Int = 10 /** * Configures a raw Jetty client. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.jetty.JettyEngineConfig.configureClient) */ public fun configureClient(block: (HTTP2Client) -> Unit) { val current = config diff --git a/ktor-client/ktor-client-mock/common/src/io/ktor/client/engine/mock/MockEngine.kt b/ktor-client/ktor-client-mock/common/src/io/ktor/client/engine/mock/MockEngine.kt index 120b091f39b..f4456b08f85 100644 --- a/ktor-client/ktor-client-mock/common/src/io/ktor/client/engine/mock/MockEngine.kt +++ b/ktor-client/ktor-client-mock/common/src/io/ktor/client/engine/mock/MockEngine.kt @@ -14,6 +14,8 @@ import kotlinx.coroutines.* /** * [HttpClientEngine] for writing tests without network. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.mock.MockEngine) */ public class MockEngine(override val config: MockEngineConfig) : HttpClientEngineBase("ktor-mock") { override val supportedCapabilities: Set> = setOf( @@ -38,11 +40,15 @@ public class MockEngine(override val config: MockEngineConfig) : HttpClientEngin /** * History of executed requests. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.mock.MockEngine.requestHistory) */ public val requestHistory: List get() = _requestHistory /** * History of sent responses. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.mock.MockEngine.responseHistory) */ public val responseHistory: List get() = _responseHistory @@ -88,6 +94,8 @@ public class MockEngine(override val config: MockEngineConfig) : HttpClientEngin /** * Create [MockEngine] instance with single request handler. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.mock.MockEngine.Companion.invoke) */ public operator fun invoke( handler: suspend MockRequestHandleScope.(HttpRequestData) -> HttpResponseData diff --git a/ktor-client/ktor-client-mock/common/src/io/ktor/client/engine/mock/MockEngineConfig.kt b/ktor-client/ktor-client-mock/common/src/io/ktor/client/engine/mock/MockEngineConfig.kt index 748cacc7e92..e8efa08d987 100644 --- a/ktor-client/ktor-client-mock/common/src/io/ktor/client/engine/mock/MockEngineConfig.kt +++ b/ktor-client/ktor-client-mock/common/src/io/ktor/client/engine/mock/MockEngineConfig.kt @@ -13,32 +13,44 @@ import kotlin.coroutines.* /** * Single [HttpClientCall] to [HttpResponse] mapper. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.mock.MockRequestHandler) */ public typealias MockRequestHandler = suspend MockRequestHandleScope.(request: HttpRequestData) -> HttpResponseData /** * Scope for [MockRequestHandler]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.mock.MockRequestHandleScope) */ public class MockRequestHandleScope(internal val callContext: CoroutineContext) /** * [HttpClientEngineConfig] for [MockEngine]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.mock.MockEngineConfig) */ public class MockEngineConfig : HttpClientEngineConfig() { /** * Request handlers. * Responses are given back in order they were added to [requestHandlers]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.mock.MockEngineConfig.requestHandlers) */ public val requestHandlers: MutableList = mutableListOf() /** * Should engine reuse handlers. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.mock.MockEngineConfig.reuseHandlers) */ public var reuseHandlers: Boolean = true /** * Add request handler to [MockEngine] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.mock.MockEngineConfig.addHandler) */ public fun addHandler(handler: MockRequestHandler) { requestHandlers += handler diff --git a/ktor-client/ktor-client-mock/common/src/io/ktor/client/engine/mock/MockUtils.kt b/ktor-client/ktor-client-mock/common/src/io/ktor/client/engine/mock/MockUtils.kt index 3c5f56e8473..5d137f730e5 100644 --- a/ktor-client/ktor-client-mock/common/src/io/ktor/client/engine/mock/MockUtils.kt +++ b/ktor-client/ktor-client-mock/common/src/io/ktor/client/engine/mock/MockUtils.kt @@ -50,6 +50,8 @@ public suspend fun OutgoingContent.toByteReadPacket(): Source = when (this) { /** * Send error response. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.mock.respondError) */ public fun MockRequestHandleScope.respondError( status: HttpStatusCode, @@ -59,6 +61,8 @@ public fun MockRequestHandleScope.respondError( /** * Send ok response. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.mock.respondOk) */ public fun MockRequestHandleScope.respondOk( content: String = "" @@ -66,6 +70,8 @@ public fun MockRequestHandleScope.respondOk( /** * Respond redirect with [location] in Location header. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.mock.respondRedirect) */ public fun MockRequestHandleScope.respondRedirect( location: String = "" @@ -73,12 +79,16 @@ public fun MockRequestHandleScope.respondRedirect( /** * Send [HttpStatusCode.BadRequest] response. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.mock.respondBadRequest) */ public fun MockRequestHandleScope.respondBadRequest(): HttpResponseData = respond("Bad Request", HttpStatusCode.BadRequest) /** * Send response with specified string [content], [status] and [headers]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.mock.respond) */ public fun MockRequestHandleScope.respond( content: String, @@ -89,6 +99,8 @@ public fun MockRequestHandleScope.respond( /** * Send response with specified bytes [content], [status] and [headers]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.mock.respond) */ public fun MockRequestHandleScope.respond( content: ByteArray, @@ -98,6 +110,8 @@ public fun MockRequestHandleScope.respond( /** * Send response with specified [ByteReadChannel] [content], [status] and [headers]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.mock.respond) */ public fun MockRequestHandleScope.respond( content: ByteReadChannel, diff --git a/ktor-client/ktor-client-okhttp/jvm/src/io/ktor/client/engine/okhttp/OkHttp.kt b/ktor-client/ktor-client-okhttp/jvm/src/io/ktor/client/engine/okhttp/OkHttp.kt index d36221c4020..1dafcf5d174 100644 --- a/ktor-client/ktor-client-okhttp/jvm/src/io/ktor/client/engine/okhttp/OkHttp.kt +++ b/ktor-client/ktor-client-okhttp/jvm/src/io/ktor/client/engine/okhttp/OkHttp.kt @@ -25,6 +25,8 @@ import io.ktor.client.engine.* * ``` * * You can learn more about client engines from [Engines](https://ktor.io/docs/http-client-engines.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.okhttp.OkHttp) */ public data object OkHttp : HttpClientEngineFactory { override fun create(block: OkHttpConfig.() -> Unit): HttpClientEngine = diff --git a/ktor-client/ktor-client-okhttp/jvm/src/io/ktor/client/engine/okhttp/OkHttpConfig.kt b/ktor-client/ktor-client-okhttp/jvm/src/io/ktor/client/engine/okhttp/OkHttpConfig.kt index b72ce716b30..75af6ddcd38 100644 --- a/ktor-client/ktor-client-okhttp/jvm/src/io/ktor/client/engine/okhttp/OkHttpConfig.kt +++ b/ktor-client/ktor-client-okhttp/jvm/src/io/ktor/client/engine/okhttp/OkHttpConfig.kt @@ -9,6 +9,8 @@ import okhttp3.* /** * A configuration for the [OkHttp] client engine. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.okhttp.OkHttpConfig) */ public class OkHttpConfig : HttpClientEngineConfig() { @@ -21,23 +23,31 @@ public class OkHttpConfig : HttpClientEngineConfig() { /** * Allows you to specify a preconfigured [OkHttpClient] instance. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.okhttp.OkHttpConfig.preconfigured) */ public var preconfigured: OkHttpClient? = null /** * Specifies the size of cache that keeps recently used [OkHttpClient] instances. * Set this property to `0` to disable caching. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.okhttp.OkHttpConfig.clientCacheSize) */ public var clientCacheSize: Int = 10 /** * Specifies the [WebSocket.Factory] used to create a [WebSocket] instance. * Otherwise, [OkHttpClient] is used directly. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.okhttp.OkHttpConfig.webSocketFactory) */ public var webSocketFactory: WebSocket.Factory? = null /** * Configures [OkHttpClient] using [OkHttpClient.Builder]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.okhttp.OkHttpConfig.config) */ public fun config(block: OkHttpClient.Builder.() -> Unit) { val oldConfig = config @@ -49,6 +59,8 @@ public class OkHttpConfig : HttpClientEngineConfig() { /** * Adds an [Interceptor] to the [OkHttp] client. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.okhttp.OkHttpConfig.addInterceptor) */ public fun addInterceptor(interceptor: Interceptor) { config { @@ -58,6 +70,8 @@ public class OkHttpConfig : HttpClientEngineConfig() { /** * Adds a network [Interceptor] to the [OkHttp] client. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.okhttp.OkHttpConfig.addNetworkInterceptor) */ public fun addNetworkInterceptor(interceptor: Interceptor) { config { diff --git a/ktor-client/ktor-client-plugins/ktor-client-auth/common/src/io/ktor/client/plugins/auth/Auth.kt b/ktor-client/ktor-client-plugins/ktor-client-auth/common/src/io/ktor/client/plugins/auth/Auth.kt index d0dd0bdf4cd..38c99f893cb 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-auth/common/src/io/ktor/client/plugins/auth/Auth.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-auth/common/src/io/ktor/client/plugins/auth/Auth.kt @@ -25,11 +25,15 @@ private class AtomicCounter { /** * Configuration used by [Auth] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.AuthConfig) */ @KtorDsl public class AuthConfig { /** * [AuthProvider] list to use. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.AuthConfig.providers) */ public val providers: MutableList = mutableListOf() @@ -39,6 +43,8 @@ public class AuthConfig { * By default checks against HTTP status 401. * * You can set this value via [reAuthorizeOnResponse]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.AuthConfig.isUnauthorizedResponse) */ @InternalAPI public var isUnauthorizedResponse: suspend (HttpResponse) -> Boolean = { it.status == HttpStatusCode.Unauthorized } @@ -48,6 +54,8 @@ public class AuthConfig { * Sets a custom function to control whether a response is unauthorized and should trigger a refresh / re-auth. * * Use this to change the value of [isUnauthorizedResponse]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.AuthConfig.reAuthorizeOnResponse) */ public fun reAuthorizeOnResponse(block: suspend (HttpResponse) -> Boolean) { @OptIn(InternalAPI::class) @@ -57,6 +65,8 @@ public class AuthConfig { /** * Shows that request should skip auth and refresh token procedure. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.AuthCircuitBreaker) */ public val AuthCircuitBreaker: AttributeKey = AttributeKey("auth-request") @@ -66,6 +76,9 @@ public val AuthCircuitBreaker: AttributeKey = AttributeKey("auth-request") * * You can learn more from [Authentication and authorization](https://ktor.io/docs/auth.html). * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.Auth) + * * @see [AuthConfig] for configuration options. */ @OptIn(InternalAPI::class) @@ -181,6 +194,8 @@ public val Auth: ClientPlugin = createClientPlugin("Auth", ::AuthCon /** * Install [Auth] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.Auth) */ @Suppress("FunctionName") public fun HttpClientConfig<*>.Auth(block: AuthConfig.() -> Unit) { diff --git a/ktor-client/ktor-client-plugins/ktor-client-auth/common/src/io/ktor/client/plugins/auth/AuthProvider.kt b/ktor-client/ktor-client-plugins/ktor-client-auth/common/src/io/ktor/client/plugins/auth/AuthProvider.kt index 3dda8f14bf2..5f077433716 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-auth/common/src/io/ktor/client/plugins/auth/AuthProvider.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-auth/common/src/io/ktor/client/plugins/auth/AuthProvider.kt @@ -12,10 +12,14 @@ import io.ktor.http.auth.* /** * An authentication provider. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.AuthProvider) */ public interface AuthProvider { /** * Waits for [HttpStatusCode.Unauthorized] to send credentials. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.AuthProvider.sendWithoutRequest) */ @Deprecated("Please use sendWithoutRequest function instead", level = DeprecationLevel.ERROR) public val sendWithoutRequest: Boolean @@ -25,11 +29,16 @@ public interface AuthProvider { /** * Checks if the current provider is applicable to a request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.AuthProvider.isApplicable) */ public fun isApplicable(auth: HttpAuthHeader): Boolean /** * Adds an authentication method headers and credentials. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.AuthProvider.addRequestHeaders) + * * @param authHeader value of `WWW-Authenticate` header from failed response, if exists * @param request builder for an authenticated request */ @@ -38,6 +47,9 @@ public interface AuthProvider { /** * Refreshes a token if required. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.AuthProvider.refreshToken) + * * @param call - response triggered token refresh. * @return if the token was successfully refreshed. */ diff --git a/ktor-client/ktor-client-plugins/ktor-client-auth/common/src/io/ktor/client/plugins/auth/providers/BasicAuthProvider.kt b/ktor-client/ktor-client-plugins/ktor-client-auth/common/src/io/ktor/client/plugins/auth/providers/BasicAuthProvider.kt index 1e62ef8e70c..31313aa91ec 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-auth/common/src/io/ktor/client/plugins/auth/providers/BasicAuthProvider.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-auth/common/src/io/ktor/client/plugins/auth/providers/BasicAuthProvider.kt @@ -16,6 +16,8 @@ import io.ktor.utils.io.core.* /** * Installs the client's [BasicAuthProvider]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.providers.basic) */ @KtorDsl public fun AuthConfig.basic(block: BasicAuthConfig.() -> Unit) { @@ -26,29 +28,39 @@ public fun AuthConfig.basic(block: BasicAuthConfig.() -> Unit) { /** * A configuration for [BasicAuthProvider]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.providers.BasicAuthConfig) */ @KtorDsl public class BasicAuthConfig { /** * Required: The username of the basic auth. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.providers.BasicAuthConfig.username) */ @Deprecated("Please use `credentials {}` function instead", level = DeprecationLevel.ERROR) public lateinit var username: String /** * Required: The password of the basic auth. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.providers.BasicAuthConfig.password) */ @Deprecated("Please use `credentials {}` function instead", level = DeprecationLevel.ERROR) public lateinit var password: String /** * Send credentials in without waiting for [HttpStatusCode.Unauthorized]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.providers.BasicAuthConfig.sendWithoutRequest) */ @Deprecated("Please use `sendWithoutRequest {}` function instead", level = DeprecationLevel.ERROR) public var sendWithoutRequest: Boolean = false /** * (Optional) Specifies the realm of the current provider. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.providers.BasicAuthConfig.realm) */ public var realm: String? = null @@ -62,6 +74,8 @@ public class BasicAuthConfig { /** * Sends credentials without waiting for [HttpStatusCode.Unauthorized]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.providers.BasicAuthConfig.sendWithoutRequest) */ public fun sendWithoutRequest(block: (HttpRequestBuilder) -> Boolean) { _sendWithoutRequest = block @@ -69,6 +83,8 @@ public class BasicAuthConfig { /** * Allows you to specify authentication credentials. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.providers.BasicAuthConfig.credentials) */ public fun credentials(block: suspend () -> BasicAuthCredentials?) { credentials = block @@ -77,6 +93,8 @@ public class BasicAuthConfig { /** * Contains credentials for [BasicAuthProvider]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.providers.BasicAuthCredentials) */ public class BasicAuthCredentials( public val username: String, @@ -88,6 +106,8 @@ public class BasicAuthCredentials( * The Basic authentication scheme can be used for logging in users. * * You can learn more from [Basic authentication](https://ktor.io/docs/basic-client.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.providers.BasicAuthProvider) */ public class BasicAuthProvider( private val credentials: suspend () -> BasicAuthCredentials?, diff --git a/ktor-client/ktor-client-plugins/ktor-client-auth/common/src/io/ktor/client/plugins/auth/providers/BearerAuthProvider.kt b/ktor-client/ktor-client-plugins/ktor-client-auth/common/src/io/ktor/client/plugins/auth/providers/BearerAuthProvider.kt index 879cb47929d..d0470fb9c86 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-auth/common/src/io/ktor/client/plugins/auth/providers/BearerAuthProvider.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-auth/common/src/io/ktor/client/plugins/auth/providers/BearerAuthProvider.kt @@ -14,6 +14,8 @@ import io.ktor.utils.io.* /** * Installs the client's [BearerAuthProvider]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.providers.bearer) */ public fun AuthConfig.bearer(block: BearerAuthConfig.() -> Unit) { with(BearerAuthConfig().apply(block)) { @@ -28,6 +30,8 @@ public class BearerTokens( /** * Parameters to be passed to [BearerAuthConfig.refreshTokens] lambda. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.providers.RefreshTokensParams) */ public class RefreshTokensParams( public val client: HttpClient, @@ -37,6 +41,8 @@ public class RefreshTokensParams( /** * Marks that this request is for refreshing auth tokens, resulting in a special handling of it. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.providers.RefreshTokensParams.markAsRefreshTokenRequest) */ public fun HttpRequestBuilder.markAsRefreshTokenRequest() { attributes.put(AuthCircuitBreaker, Unit) @@ -45,6 +51,8 @@ public class RefreshTokensParams( /** * A configuration for [BearerAuthProvider]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.providers.BearerAuthConfig) */ @KtorDsl public class BearerAuthConfig { @@ -56,6 +64,8 @@ public class BearerAuthConfig { /** * Configures a callback that refreshes a token when the 401 status code is received. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.providers.BearerAuthConfig.refreshTokens) */ public fun refreshTokens(block: suspend RefreshTokensParams.() -> BearerTokens?) { refreshTokens = block @@ -64,6 +74,8 @@ public class BearerAuthConfig { /** * Configures a callback that loads a cached token from a local storage. * Note: Using the same client instance here to make a request will result in a deadlock. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.providers.BearerAuthConfig.loadTokens) */ public fun loadTokens(block: suspend () -> BearerTokens?) { loadTokens = block @@ -71,6 +83,8 @@ public class BearerAuthConfig { /** * Sends credentials without waiting for [HttpStatusCode.Unauthorized]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.providers.BearerAuthConfig.sendWithoutRequest) */ public fun sendWithoutRequest(block: (HttpRequestBuilder) -> Boolean) { sendWithoutRequest = block @@ -84,6 +98,8 @@ public class BearerAuthConfig { * by using external providers, such as Google, Facebook, Twitter, and so on. * * You can learn more from [Bearer authentication](https://ktor.io/docs/bearer-client.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.providers.BearerAuthProvider) */ public class BearerAuthProvider( private val refreshTokens: suspend RefreshTokensParams.() -> BearerTokens?, @@ -103,6 +119,8 @@ public class BearerAuthProvider( /** * Checks if current provider is applicable to the request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.providers.BearerAuthProvider.isApplicable) */ override fun isApplicable(auth: HttpAuthHeader): Boolean { if (auth.authScheme != AuthScheme.Bearer) { @@ -122,6 +140,8 @@ public class BearerAuthProvider( /** * Adds an authentication method headers and credentials. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.providers.BearerAuthProvider.addRequestHeaders) */ override suspend fun addRequestHeaders(request: HttpRequestBuilder, authHeader: HttpAuthHeader?) { val token = tokensHolder.loadToken() ?: return diff --git a/ktor-client/ktor-client-plugins/ktor-client-auth/common/src/io/ktor/client/plugins/auth/providers/DigestAuthProvider.kt b/ktor-client/ktor-client-plugins/ktor-client-auth/common/src/io/ktor/client/plugins/auth/providers/DigestAuthProvider.kt index 6e1e5001dc3..89db02de2d8 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-auth/common/src/io/ktor/client/plugins/auth/providers/DigestAuthProvider.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-auth/common/src/io/ktor/client/plugins/auth/providers/DigestAuthProvider.kt @@ -17,6 +17,8 @@ import kotlinx.atomicfu.* /** * Installs the client's [DigestAuthProvider]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.providers.digest) */ public fun AuthConfig.digest(block: DigestAuthConfig.() -> Unit) { val config = DigestAuthConfig().apply(block) @@ -27,6 +29,8 @@ public fun AuthConfig.digest(block: DigestAuthConfig.() -> Unit) { /** * A configuration for [DigestAuthProvider]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.providers.DigestAuthConfig) */ @KtorDsl public class DigestAuthConfig { @@ -35,18 +39,24 @@ public class DigestAuthConfig { /** * Required: The username of the basic auth. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.providers.DigestAuthConfig.username) */ @Deprecated("Please use `credentials {}` function instead", level = DeprecationLevel.ERROR) public var username: String = "" /** * Required: The password of the basic auth. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.providers.DigestAuthConfig.password) */ @Deprecated("Please use `credentials {}` function instead", level = DeprecationLevel.ERROR) public var password: String = "" /** * (Optional) Specifies the realm of the current provider. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.providers.DigestAuthConfig.realm) */ public var realm: String? = null @@ -57,6 +67,8 @@ public class DigestAuthConfig { /** * Allows you to specify authentication credentials. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.providers.DigestAuthConfig.credentials) */ public fun credentials(block: suspend () -> DigestAuthCredentials?) { credentials = block @@ -65,6 +77,8 @@ public class DigestAuthConfig { /** * Contains credentials for [DigestAuthProvider]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.providers.DigestAuthCredentials) */ public class DigestAuthCredentials( public val username: String, @@ -75,6 +89,8 @@ public class DigestAuthCredentials( * An authentication provider for the Digest HTTP authentication scheme. * * You can learn more from [Digest authentication](https://ktor.io/docs/digest-client.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.auth.providers.DigestAuthProvider) */ public class DigestAuthProvider( private val credentials: suspend () -> DigestAuthCredentials?, diff --git a/ktor-client/ktor-client-plugins/ktor-client-bom-remover/common/src/io/ktor/client/plugins/bomremover/BOMRemover.kt b/ktor-client/ktor-client-plugins/ktor-client-bom-remover/common/src/io/ktor/client/plugins/bomremover/BOMRemover.kt index 9d2061a126b..4cbfe3651b7 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-bom-remover/common/src/io/ktor/client/plugins/bomremover/BOMRemover.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-bom-remover/common/src/io/ktor/client/plugins/bomremover/BOMRemover.kt @@ -22,6 +22,8 @@ import kotlinx.coroutines.* * install(BOMRemover) * } * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.bomremover.BOMRemover) */ public val BOMRemover: ClientPlugin = createClientPlugin( name = "BOMRemover", diff --git a/ktor-client/ktor-client-plugins/ktor-client-call-id/common/src/io/ktor/client/plugins/callid/CallId.kt b/ktor-client/ktor-client-plugins/ktor-client-call-id/common/src/io/ktor/client/plugins/callid/CallId.kt index 90093e11589..55c9baab06c 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-call-id/common/src/io/ktor/client/plugins/callid/CallId.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-call-id/common/src/io/ktor/client/plugins/callid/CallId.kt @@ -15,6 +15,8 @@ internal typealias CallIdInterceptor = (request: HttpRequestBuilder, callId: Str /** * A configuration for [CallId] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.callid.CallIdConfig) */ public class CallIdConfig { @@ -24,6 +26,9 @@ public class CallIdConfig { /** * If set to `true`, adds a default generator that uses current [CoroutineContext] to retrieve a call ID. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.callid.CallIdConfig.useCoroutineContext) + * * @see withCallId * @see KtorCallIdContextElement */ @@ -33,6 +38,8 @@ public class CallIdConfig { * Allows you to generate a call ID for an outgoing request. * Generates `null` if it is impossible to generate a call ID for some reason. * You can add multiple generators, and the first non-null value will be used. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.callid.CallIdConfig.generate) */ public fun generate(block: suspend (HttpRequestBuilder) -> String?) { generators.add(block) @@ -41,6 +48,9 @@ public class CallIdConfig { /** * Allows you to add a call ID to the request. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.callid.CallIdConfig.intercept) + * * @see [addToHeader] */ public fun intercept(block: CallIdInterceptor) { @@ -50,6 +60,9 @@ public class CallIdConfig { /** * Adds a call ID to specified header named [header]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.callid.CallIdConfig.addToHeader) + * * @see [intercept] */ public fun addToHeader(header: String = HttpHeaders.XRequestId) { @@ -70,6 +83,8 @@ public class CallIdConfig { * and add it to the [HttpHeaders.XRequestId]. See [CallIdConfig] if you want to change it. * * You can learn more from [CallId](https://ktor.io/docs/call-id.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.callid.CallId) */ public val CallId: ClientPlugin = createClientPlugin("CallId", ::CallIdConfig) { diff --git a/ktor-client/ktor-client-plugins/ktor-client-content-negotiation/common/src/io/ktor/client/plugins/contentnegotiation/ContentNegotiation.kt b/ktor-client/ktor-client-plugins/ktor-client-content-negotiation/common/src/io/ktor/client/plugins/contentnegotiation/ContentNegotiation.kt index 21edbe71305..476a8b0eb7e 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-content-negotiation/common/src/io/ktor/client/plugins/contentnegotiation/ContentNegotiation.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-content-negotiation/common/src/io/ktor/client/plugins/contentnegotiation/ContentNegotiation.kt @@ -38,6 +38,8 @@ internal val ExcludedContentTypes: AttributeKey> = AttributeKe /** * A [ContentNegotiation] configuration that is used during installation. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.contentnegotiation.ContentNegotiationConfig) */ @KtorDsl public class ContentNegotiationConfig : Configuration { @@ -56,11 +58,15 @@ public class ContentNegotiationConfig : Configuration { /** * By default, `Accept` headers for registered content types will have no q value (implicit 1.0). Set this to * change that behavior. This is useful to override the preferred `Accept` content types on a per-request basis. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.contentnegotiation.ContentNegotiationConfig.defaultAcceptHeaderQValue) */ public var defaultAcceptHeaderQValue: Double? = null /** * Registers a [contentType] to a specified [converter] with an optional [configuration] script for a converter. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.contentnegotiation.ContentNegotiationConfig.register) */ public override fun register( contentType: ContentType, @@ -77,6 +83,8 @@ public class ContentNegotiationConfig : Configuration { /** * Registers a [contentTypeToSend] and [contentTypeMatcher] to a specified [converter] with * an optional [configuration] script for a converter. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.contentnegotiation.ContentNegotiationConfig.register) */ public fun register( contentTypeToSend: ContentType, @@ -96,6 +104,8 @@ public class ContentNegotiationConfig : Configuration { * Adds a type to the list of types that should be ignored by [ContentNegotiation]. * * The list contains the [HttpStatusCode], [ByteArray], [String] and streaming types by default. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.contentnegotiation.ContentNegotiationConfig.ignoreType) */ public inline fun ignoreType() { ignoreType(T::class) @@ -103,6 +113,8 @@ public class ContentNegotiationConfig : Configuration { /** * Remove [T] from the list of types that should be ignored by [ContentNegotiation]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.contentnegotiation.ContentNegotiationConfig.removeIgnoredType) */ public inline fun removeIgnoredType() { removeIgnoredType(T::class) @@ -110,6 +122,8 @@ public class ContentNegotiationConfig : Configuration { /** * Remove [type] from the list of types that should be ignored by [ContentNegotiation]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.contentnegotiation.ContentNegotiationConfig.removeIgnoredType) */ public fun removeIgnoredType(type: KClass<*>) { ignoredTypes.remove(type) @@ -119,6 +133,8 @@ public class ContentNegotiationConfig : Configuration { * Adds a [type] to the list of types that should be ignored by [ContentNegotiation]. * * The list contains the [HttpStatusCode], [ByteArray], [String] and streaming types by default. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.contentnegotiation.ContentNegotiationConfig.ignoreType) */ public fun ignoreType(type: KClass<*>) { ignoredTypes.add(type) @@ -126,6 +142,8 @@ public class ContentNegotiationConfig : Configuration { /** * Clear all configured ignored types including defaults. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.contentnegotiation.ContentNegotiationConfig.clearIgnoredTypes) */ public fun clearIgnoredTypes() { ignoredTypes.clear() @@ -143,6 +161,8 @@ public class ContentNegotiationConfig : Configuration { * Ktor supports the following formats out-of-the-box: `JSON`, `XML`, and `CBOR`. * * You can learn more from [Content negotiation and serialization](https://ktor.io/docs/serialization-client.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.contentnegotiation.ContentNegotiation) */ @OptIn(InternalAPI::class) public val ContentNegotiation: ClientPlugin = createClientPlugin( @@ -284,6 +304,8 @@ public class ContentConverterException(message: String) : Exception(message) * the [ContentNegotiation] plugin. Can be used to not accept specific types for particular requests. * This can be called multiple times to exclude multiple content types, or multiple content types can * be passed in a single call. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.contentnegotiation.exclude) */ public fun HttpRequestBuilder.exclude(vararg contentType: ContentType) { val excludedContentTypes = attributes.getOrNull(ExcludedContentTypes).orEmpty() diff --git a/ktor-client/ktor-client-plugins/ktor-client-content-negotiation/common/src/io/ktor/client/plugins/contentnegotiation/JsonContentTypeMatcher.kt b/ktor-client/ktor-client-plugins/ktor-client-content-negotiation/common/src/io/ktor/client/plugins/contentnegotiation/JsonContentTypeMatcher.kt index 0e0ec736efd..25c79af4172 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-content-negotiation/common/src/io/ktor/client/plugins/contentnegotiation/JsonContentTypeMatcher.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-content-negotiation/common/src/io/ktor/client/plugins/contentnegotiation/JsonContentTypeMatcher.kt @@ -8,6 +8,8 @@ import io.ktor.http.* /** * Matcher that accepts all extended json content types + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.contentnegotiation.JsonContentTypeMatcher) */ public object JsonContentTypeMatcher : ContentTypeMatcher { override fun contains(contentType: ContentType): Boolean { diff --git a/ktor-client/ktor-client-plugins/ktor-client-content-negotiation/ktor-client-content-negotiation-tests/jvm/src/io/ktor/client/plugins/contentnegotiation/tests/AbstractClientContentNegotiationTest.kt b/ktor-client/ktor-client-plugins/ktor-client-content-negotiation/ktor-client-content-negotiation-tests/jvm/src/io/ktor/client/plugins/contentnegotiation/tests/AbstractClientContentNegotiationTest.kt index 841f3b53fe6..4e43379298f 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-content-negotiation/ktor-client-content-negotiation-tests/jvm/src/io/ktor/client/plugins/contentnegotiation/tests/AbstractClientContentNegotiationTest.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-content-negotiation/ktor-client-content-negotiation-tests/jvm/src/io/ktor/client/plugins/contentnegotiation/tests/AbstractClientContentNegotiationTest.kt @@ -30,7 +30,11 @@ import kotlinx.serialization.* import kotlinx.serialization.builtins.ListSerializer import kotlin.test.* -/** Base class for [ContentNegotiation] tests. */ +/** + * Base class for [ContentNegotiation] tests. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.contentnegotiation.tests.AbstractClientContentNegotiationTest) + */ abstract class AbstractClientContentNegotiationTest : TestWithKtor() { private val widget = Widget("Foo", 1000, listOf("a", "b", "c")) diff --git a/ktor-client/ktor-client-plugins/ktor-client-encoding/common/src/ContentEncoding.kt b/ktor-client/ktor-client-plugins/ktor-client-encoding/common/src/ContentEncoding.kt index 322f9e457e2..1c6bda86750 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-encoding/common/src/ContentEncoding.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-encoding/common/src/ContentEncoding.kt @@ -21,6 +21,8 @@ private val LOGGER = KtorSimpleLogger("io.ktor.client.plugins.compression.Conten /** * A configuration for the [ContentEncoding] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.compression.ContentEncodingConfig) */ @KtorDsl public class ContentEncodingConfig { @@ -40,6 +42,9 @@ public class ContentEncodingConfig { /** * Installs the `gzip` encoder. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.compression.ContentEncodingConfig.gzip) + * * @param quality a priority value to use in the `Accept-Encoding` header. */ public fun gzip(quality: Float? = null) { @@ -49,6 +54,9 @@ public class ContentEncodingConfig { /** * Installs the `deflate` encoder. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.compression.ContentEncodingConfig.deflate) + * * @param quality a priority value to use in the `Accept-Encoding` header. */ public fun deflate(quality: Float? = null) { @@ -57,6 +65,9 @@ public class ContentEncodingConfig { /** * Installs the `identity` encoder. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.compression.ContentEncodingConfig.identity) + * * @param quality a priority value to use in the `Accept-Encoding` header. */ public fun identity(quality: Float? = null) { @@ -66,6 +77,9 @@ public class ContentEncodingConfig { /** * Installs a custom encoder. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.compression.ContentEncodingConfig.customEncoder) + * * @param encoder a custom encoder to use. * @param quality a priority value to use in the `Accept-Encoding` header. */ @@ -88,6 +102,8 @@ public class ContentEncodingConfig { * - Decodes content received from a server to obtain the original payload. * * You can learn more from [Content encoding](https://ktor.io/docs/content-encoding.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.compression.ContentEncoding) */ @OptIn(InternalAPI::class) public val ContentEncoding: ClientPlugin = createClientPlugin( @@ -222,6 +238,9 @@ internal object ReceiveStateHook : ClientHook HttpResp /** * Installs or configures the [ContentEncoding] plugin. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.compression.ContentEncoding) + * * @param block: a [ContentEncoding] configuration. */ @Suppress("FunctionName") @@ -248,6 +267,9 @@ internal val DecompressionListAttribute: AttributeKey> = AttributeK /** * Compresses request body using [ContentEncoding] plugin. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.compression.compress) + * * @param contentEncoderName names of compression encoders to use, such as "gzip", "deflate", etc */ public fun HttpRequestBuilder.compress(vararg contentEncoderName: String) { @@ -257,6 +279,9 @@ public fun HttpRequestBuilder.compress(vararg contentEncoderName: String) { /** * Compress request body using [ContentEncoding] plugin. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.compression.compress) + * * @param contentEncoderNames names of compression encoders to use, such as "gzip", "deflate", etc */ public fun HttpRequestBuilder.compress(contentEncoderNames: List) { @@ -265,6 +290,8 @@ public fun HttpRequestBuilder.compress(contentEncoderNames: List) { /** * List of [ContentEncoder] names that were used to decode response body. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.compression.appliedDecoders) */ public val HttpResponse.appliedDecoders: List get() = call.attributes.getOrNull(DecompressionListAttribute) ?: emptyList() diff --git a/ktor-client/ktor-client-plugins/ktor-client-json/common/src/io/ktor/client/plugins/json/JsonPlugin.kt b/ktor-client/ktor-client-plugins/ktor-client-json/common/src/io/ktor/client/plugins/json/JsonPlugin.kt index 0830659513c..c037bcde963 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-json/common/src/io/ktor/client/plugins/json/JsonPlugin.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-json/common/src/io/ktor/client/plugins/json/JsonPlugin.kt @@ -34,6 +34,8 @@ internal expect val DefaultIgnoredTypes: Set> * Consider to add one of the following dependencies: * - ktor-client-gson * - ktor-client-json + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.json.defaultSerializer) */ public expect fun defaultSerializer(): JsonSerializer @@ -48,6 +50,9 @@ public expect fun defaultSerializer(): JsonSerializer * Note: It will de-serialize the body response if the specified type is a public accessible class * and the Content-Type is one of [acceptContentTypes] list (`application/json` by default). * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.json.JsonPlugin) + * * @property serializer that is used to serialize and deserialize request/response bodies * @property acceptContentTypes that are allowed when receiving content */ @@ -69,6 +74,8 @@ public class JsonPlugin internal constructor( /** * [JsonPlugin] configuration that is used during installation + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.json.JsonPlugin.Config) */ @KtorDsl public class Config { @@ -80,6 +87,8 @@ public class JsonPlugin internal constructor( * Serializer that will be used for serializing requests and deserializing response bodies. * * Default value for [serializer] is [defaultSerializer]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.json.JsonPlugin.Config.serializer) */ public var serializer: JsonSerializer? = null @@ -94,6 +103,8 @@ public class JsonPlugin internal constructor( * List of content types that are handled by this plugin. * It also affects `Accept` request header value. * Please note that wildcard content types are supported but no quality specification provided. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.json.JsonPlugin.Config.acceptContentTypes) */ public var acceptContentTypes: List set(value) { @@ -107,6 +118,8 @@ public class JsonPlugin internal constructor( /** * List of content type matchers that are handled by this plugin. * Please note that wildcard content types are supported but no quality specification provided. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.json.JsonPlugin.Config.receiveContentTypeMatchers) */ public var receiveContentTypeMatchers: List set(value) { @@ -120,6 +133,8 @@ public class JsonPlugin internal constructor( * Adds accepted content types. Be aware that [ContentType.Application.Json] accepted by default is removed from * the list if you use this function to provide accepted content types. * It also affects `Accept` request header value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.json.JsonPlugin.Config.accept) */ public fun accept(vararg contentTypes: ContentType) { _acceptContentTypes += contentTypes @@ -127,6 +142,8 @@ public class JsonPlugin internal constructor( /** * Adds accepted content types. Existing content types will not be removed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.json.JsonPlugin.Config.receive) */ public fun receive(matcher: ContentTypeMatcher) { _receiveContentTypeMatchers += matcher @@ -136,6 +153,8 @@ public class JsonPlugin internal constructor( * Adds a type to the list of types that should be ignored by [ContentNegotiation]. * * The list contains the [HttpStatusCode], [ByteArray], [String] and streaming types by default. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.json.JsonPlugin.Config.ignoreType) */ public inline fun ignoreType() { ignoreType(T::class) @@ -143,6 +162,8 @@ public class JsonPlugin internal constructor( /** * Remove [T] from the list of types that should be ignored by [ContentNegotiation]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.json.JsonPlugin.Config.removeIgnoredType) */ public inline fun removeIgnoredType() { removeIgnoredType(T::class) @@ -150,6 +171,8 @@ public class JsonPlugin internal constructor( /** * Remove [type] from the list of types that should be ignored by [ContentNegotiation]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.json.JsonPlugin.Config.removeIgnoredType) */ public fun removeIgnoredType(type: KClass<*>) { ignoredTypes.remove(type) @@ -159,6 +182,8 @@ public class JsonPlugin internal constructor( * Adds a [type] to the list of types that should be ignored by [ContentNegotiation]. * * The list contains the [HttpStatusCode], [ByteArray], [String] and streaming types by default. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.json.JsonPlugin.Config.ignoreType) */ public fun ignoreType(type: KClass<*>) { ignoredTypes.add(type) @@ -166,6 +191,8 @@ public class JsonPlugin internal constructor( /** * Clear all configured ignored types including defaults. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.json.JsonPlugin.Config.clearIgnoredTypes) */ public fun clearIgnoredTypes() { ignoredTypes.clear() @@ -181,6 +208,8 @@ public class JsonPlugin internal constructor( /** * Companion object for plugin installation + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.json.JsonPlugin.Plugin) */ public companion object Plugin : HttpClientPlugin { override val key: AttributeKey = AttributeKey("Json") @@ -231,6 +260,8 @@ public class JsonPlugin internal constructor( /** * Install [JsonPlugin]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.json.Json) */ @Suppress("FunctionName") @Deprecated( diff --git a/ktor-client/ktor-client-plugins/ktor-client-json/common/src/io/ktor/client/plugins/json/JsonSerializer.kt b/ktor-client/ktor-client-plugins/ktor-client-json/common/src/io/ktor/client/plugins/json/JsonSerializer.kt index 4ed1badd3f8..0684cf4cd1b 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-json/common/src/io/ktor/client/plugins/json/JsonSerializer.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-json/common/src/io/ktor/client/plugins/json/JsonSerializer.kt @@ -11,6 +11,8 @@ import io.ktor.utils.io.core.* /** * Client json serializer. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.json.JsonSerializer) */ @Suppress("ktlint:standard:max-line-length") @Deprecated( @@ -20,16 +22,22 @@ import io.ktor.utils.io.core.* public interface JsonSerializer { /** * Convert data object to [OutgoingContent]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.json.JsonSerializer.write) */ public fun write(data: Any, contentType: ContentType): OutgoingContent /** * Convert data object to [OutgoingContent]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.json.JsonSerializer.write) */ public fun write(data: Any): OutgoingContent = write(data, ContentType.Application.Json) /** * Read content from response using information specified in [type]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.json.JsonSerializer.read) */ public fun read(type: TypeInfo, body: Input): Any diff --git a/ktor-client/ktor-client-plugins/ktor-client-json/jsAndWasmShared/src/io/ktor/client/plugins/json/DefaultJs.kt b/ktor-client/ktor-client-plugins/ktor-client-json/jsAndWasmShared/src/io/ktor/client/plugins/json/DefaultJs.kt index a8238409368..b6849f1f60f 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-json/jsAndWasmShared/src/io/ktor/client/plugins/json/DefaultJs.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-json/jsAndWasmShared/src/io/ktor/client/plugins/json/DefaultJs.kt @@ -10,6 +10,8 @@ import io.ktor.utils.io.* /** * Platform default serializer. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.json.defaultSerializer) */ @OptIn(InternalAPI::class) public actual fun defaultSerializer(): JsonSerializer = diff --git a/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-gson/jvm/src/io/ktor/client/plugins/gson/GsonSerializer.kt b/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-gson/jvm/src/io/ktor/client/plugins/gson/GsonSerializer.kt index a507a765a92..1cc4f6d6f61 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-gson/jvm/src/io/ktor/client/plugins/gson/GsonSerializer.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-gson/jvm/src/io/ktor/client/plugins/gson/GsonSerializer.kt @@ -14,6 +14,8 @@ import io.ktor.utils.io.core.* /** * [JsonSerializer] using [Gson] as backend. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.gson.GsonSerializer) */ @Suppress("ktlint:standard:max-line-length") @Deprecated( diff --git a/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-serialization/common/src/io/ktor/client/plugins/kotlinx/serializer/KotlinxSerializer.kt b/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-serialization/common/src/io/ktor/client/plugins/kotlinx/serializer/KotlinxSerializer.kt index 0822a6fbcd9..4ea9ab379bc 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-serialization/common/src/io/ktor/client/plugins/kotlinx/serializer/KotlinxSerializer.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-serialization/common/src/io/ktor/client/plugins/kotlinx/serializer/KotlinxSerializer.kt @@ -18,6 +18,8 @@ import kotlinx.serialization.modules.* /** * A [JsonSerializer] implemented for kotlinx [Serializable] classes. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.kotlinx.serializer.KotlinxSerializer) */ @Suppress("ktlint:standard:max-line-length") @Deprecated( @@ -47,6 +49,8 @@ public class KotlinxSerializer( public companion object { /** * Default [Json] configuration for [KotlinxSerializer]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.kotlinx.serializer.KotlinxSerializer.Companion.DefaultJson) */ public val DefaultJson: Json = Json { isLenient = false diff --git a/ktor-client/ktor-client-plugins/ktor-client-json/posix/src/io/ktor/client/plugins/json/DefaultPosix.kt b/ktor-client/ktor-client-plugins/ktor-client-json/posix/src/io/ktor/client/plugins/json/DefaultPosix.kt index 077bf5b3d14..ea8b157c75f 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-json/posix/src/io/ktor/client/plugins/json/DefaultPosix.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-json/posix/src/io/ktor/client/plugins/json/DefaultPosix.kt @@ -9,6 +9,8 @@ import io.ktor.utils.io.* /** * Platform default serializer. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.json.defaultSerializer) */ @OptIn(InternalAPI::class) diff --git a/ktor-client/ktor-client-plugins/ktor-client-logging/common/src/io/ktor/client/plugins/logging/LogLevel.kt b/ktor-client/ktor-client-plugins/ktor-client-logging/common/src/io/ktor/client/plugins/logging/LogLevel.kt index a45409714f6..53ee8d51108 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-logging/common/src/io/ktor/client/plugins/logging/LogLevel.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-logging/common/src/io/ktor/client/plugins/logging/LogLevel.kt @@ -6,6 +6,8 @@ package io.ktor.client.plugins.logging /** * [Logging] log level. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.logging.LogLevel) */ public enum class LogLevel( public val info: Boolean, diff --git a/ktor-client/ktor-client-plugins/ktor-client-logging/common/src/io/ktor/client/plugins/logging/Logger.kt b/ktor-client/ktor-client-plugins/ktor-client-logging/common/src/io/ktor/client/plugins/logging/Logger.kt index 7d2571676aa..95be80fe5b0 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-logging/common/src/io/ktor/client/plugins/logging/Logger.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-logging/common/src/io/ktor/client/plugins/logging/Logger.kt @@ -6,10 +6,14 @@ package io.ktor.client.plugins.logging /** * [HttpClient] Logger. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.logging.Logger) */ public interface Logger { /** * Add [message] to log. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.logging.Logger.log) */ public fun log(message: String) @@ -18,16 +22,22 @@ public interface Logger { /** * Default logger to use. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.logging.DEFAULT) */ public expect val Logger.Companion.DEFAULT: Logger /** * [Logger] using [println]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.logging.SIMPLE) */ public val Logger.Companion.SIMPLE: Logger get() = SimpleLogger() /** * Empty [Logger] for test purpose. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.logging.EMPTY) */ public val Logger.Companion.EMPTY: Logger get() = object : Logger { diff --git a/ktor-client/ktor-client-plugins/ktor-client-logging/common/src/io/ktor/client/plugins/logging/Logging.kt b/ktor-client/ktor-client-plugins/ktor-client-logging/common/src/io/ktor/client/plugins/logging/Logging.kt index 517a6f3386b..1aa803bcf8d 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-logging/common/src/io/ktor/client/plugins/logging/Logging.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-logging/common/src/io/ktor/client/plugins/logging/Logging.kt @@ -36,12 +36,16 @@ public enum class LoggingFormat { /** * [OkHttp logging format](https://github.com/square/okhttp/blob/parent-4.12.0/okhttp-logging-interceptor/src/main/kotlin/okhttp3/logging/HttpLoggingInterceptor.kt#L48-L105). * Writes only application-level logs because the low-level HTTP communication is hidden within the engine implementations. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.logging.LoggingFormat.OkHttp) */ OkHttp } /** * A configuration for the [Logging] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.logging.LoggingConfig) */ @KtorDsl public class LoggingConfig { @@ -50,11 +54,17 @@ public class LoggingConfig { private var _logger: Logger? = null - /** A general format for logging requests and responses. See [LoggingFormat]. */ + /** + * A general format for logging requests and responses. See [LoggingFormat]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.logging.LoggingConfig.format) + */ public var format: LoggingFormat = LoggingFormat.Default /** * Specifies a [Logger] instance. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.logging.LoggingConfig.logger) */ public var logger: Logger get() = _logger ?: Logger.DEFAULT @@ -64,11 +74,15 @@ public class LoggingConfig { /** * Specifies the logging level. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.logging.LoggingConfig.level) */ public var level: LogLevel = LogLevel.HEADERS /** * Allows you to filter log messages for calls matching a [predicate]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.logging.LoggingConfig.filter) */ public fun filter(predicate: (HttpRequestBuilder) -> Boolean) { filters.add(predicate) @@ -80,6 +94,8 @@ public class LoggingConfig { * ```kotlin * sanitizeHeader { header -> header == HttpHeaders.Authorization } * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.logging.LoggingConfig.sanitizeHeader) */ public fun sanitizeHeader(placeholder: String = "***", predicate: (String) -> Boolean) { sanitizedHeaders.add(SanitizedHeader(placeholder, predicate)) @@ -90,6 +106,8 @@ public class LoggingConfig { * A client's plugin that provides the capability to log HTTP calls. * * You can learn more from [Logging](https://ktor.io/docs/client-logging.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.logging.Logging) */ @OptIn(InternalAPI::class, DelicateCoroutinesApi::class) public val Logging: ClientPlugin = createClientPlugin("Logging", ::LoggingConfig) { @@ -650,6 +668,8 @@ private fun computeRequestBodySize(content: Any, headers: Headers): Long { /** * Configures and installs [Logging] in [HttpClient]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.logging.Logging) */ @Suppress("FunctionName") public fun HttpClientConfig<*>.Logging(block: LoggingConfig.() -> Unit = {}) { diff --git a/ktor-client/ktor-client-plugins/ktor-client-logging/jvm/src/io/ktor/client/plugins/logging/LoggerJvm.kt b/ktor-client/ktor-client-plugins/ktor-client-logging/jvm/src/io/ktor/client/plugins/logging/LoggerJvm.kt index d99e596dfaf..181046a497e 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-logging/jvm/src/io/ktor/client/plugins/logging/LoggerJvm.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-logging/jvm/src/io/ktor/client/plugins/logging/LoggerJvm.kt @@ -21,6 +21,8 @@ public actual val Logger.Companion.DEFAULT: Logger * Otherwise, uses the [Logger.Companion.DEFAULT]. * Breaks up long log messages that would be truncated by Android's max log * length of 4068 characters. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.logging.ANDROID) */ public val Logger.Companion.ANDROID: Logger by lazy { getAndroidLogger() } @@ -64,6 +66,9 @@ private class LogcatLogger(logClass: Class<*>, private val fallback: Logger) : L /** * A [Logger] that breaks up log messages into multiple logs no longer than [maxLength] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.logging.MessageLengthLimitingLogger) + * * @property maxLength max length allowed for a log message * @property minLength if log message is longer than [maxLength], attempt to break the log * message at a new line between [minLength] and [maxLength] if one exists diff --git a/ktor-client/ktor-client-plugins/ktor-client-resources/common/src/io/ktor/client/plugins/resources/Resources.kt b/ktor-client/ktor-client-plugins/ktor-client-resources/common/src/io/ktor/client/plugins/resources/Resources.kt index 575b0a96edb..19ddfb7cd7f 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-resources/common/src/io/ktor/client/plugins/resources/Resources.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-resources/common/src/io/ktor/client/plugins/resources/Resources.kt @@ -30,6 +30,9 @@ import io.ktor.resources.Resources as ResourcesCore * val addedUser = client.get(Users.ById(newUserId)) // "/user/123" * ``` * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.resources.Resources) + * * @see Resource */ public object Resources : HttpClientPlugin { @@ -50,6 +53,8 @@ public object Resources : HttpClientPlugin HttpClient.href(resource: T): String { return href(plugin(Resources).resourcesFormat, resource) @@ -59,6 +64,8 @@ public inline fun HttpClient.href(resource: T): String { * Constructs a URL for [resource]. * * The class of the [resource] instance **must** be annotated with [Resource]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.resources.href) */ public inline fun HttpClient.href(resource: T, urlBuilder: URLBuilder) { href(plugin(Resources).resourcesFormat, resource, urlBuilder) diff --git a/ktor-client/ktor-client-plugins/ktor-client-resources/common/src/io/ktor/client/plugins/resources/builders.kt b/ktor-client/ktor-client-plugins/ktor-client-resources/common/src/io/ktor/client/plugins/resources/builders.kt index 420b5cd7469..0f3e6882510 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-resources/common/src/io/ktor/client/plugins/resources/builders.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-resources/common/src/io/ktor/client/plugins/resources/builders.kt @@ -28,6 +28,8 @@ import io.ktor.client.request.request as requestBuilder /** * Executes a [HttpClient] GET request, with a URL built from [resource] and the information from the [builder] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.resources.get) */ public suspend inline fun HttpClient.get( resource: T, @@ -42,6 +44,8 @@ public suspend inline fun HttpClient.get( /** * Executes a [HttpClient] POST request, with a URL built from [resource] and the information from the [builder] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.resources.post) */ public suspend inline fun HttpClient.post( resource: T, @@ -56,6 +60,8 @@ public suspend inline fun HttpClient.post( /** * Executes a [HttpClient] PUT request, with a URL built from [resource] and the information from the [builder] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.resources.put) */ public suspend inline fun HttpClient.put( resource: T, @@ -70,6 +76,8 @@ public suspend inline fun HttpClient.put( /** * Executes a [HttpClient] DELETE request, with a URL built from [resource] and the information from the [builder] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.resources.delete) */ public suspend inline fun HttpClient.delete( resource: T, @@ -84,6 +92,8 @@ public suspend inline fun HttpClient.delete( /** * Executes a [HttpClient] PATCH request, with a URL built from [resource] and the information from the [builder] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.resources.patch) */ public suspend inline fun HttpClient.patch( resource: T, @@ -98,6 +108,8 @@ public suspend inline fun HttpClient.patch( /** * Executes a [HttpClient] OPTIONS request, with a URL built from [resource] and the information from the [builder] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.resources.options) */ public suspend inline fun HttpClient.options( resource: T, @@ -112,6 +124,8 @@ public suspend inline fun HttpClient.options( /** * Executes a [HttpClient] HEAD request, with a URL built from [resource] and the information from the [builder] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.resources.head) */ public suspend inline fun HttpClient.head( resource: T, @@ -126,6 +140,8 @@ public suspend inline fun HttpClient.head( /** * Executes a [HttpClient] request, with a URL built from [resource] and the information from the [builder] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.resources.request) */ public suspend inline fun HttpClient.request( resource: T, @@ -140,6 +156,8 @@ public suspend inline fun HttpClient.request( /** * Prepares a [HttpClient] GET request, with a URL built from [resource] and the information from the [builder] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.resources.prepareGet) */ public suspend inline fun HttpClient.prepareGet( resource: T, @@ -154,6 +172,8 @@ public suspend inline fun HttpClient.prepareGet( /** * Prepares a [HttpClient] POST request, with a URL built from [resource] and the information from the [builder] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.resources.preparePost) */ public suspend inline fun HttpClient.preparePost( resource: T, @@ -168,6 +188,8 @@ public suspend inline fun HttpClient.preparePost( /** * Prepares a [HttpClient] PUT request, with a URL built from [resource] and the information from the [builder] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.resources.preparePut) */ public suspend inline fun HttpClient.preparePut( resource: T, @@ -182,6 +204,8 @@ public suspend inline fun HttpClient.preparePut( /** * Prepares a [HttpClient] DELETE request, with a URL built from [resource] and the information from the [builder] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.resources.prepareDelete) */ public suspend inline fun HttpClient.prepareDelete( resource: T, @@ -196,6 +220,8 @@ public suspend inline fun HttpClient.prepareDelete( /** * Prepares a [HttpClient] PATCH request, with a URL built from [resource] and the information from the [builder] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.resources.preparePatch) */ public suspend inline fun HttpClient.preparePatch( resource: T, @@ -210,6 +236,8 @@ public suspend inline fun HttpClient.preparePatch( /** * Prepares a [HttpClient] OPTIONS request, with a URL built from [resource] and the information from the [builder] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.resources.prepareOptions) */ public suspend inline fun HttpClient.prepareOptions( resource: T, @@ -224,6 +252,8 @@ public suspend inline fun HttpClient.prepareOptions( /** * Prepares a [HttpClient] HEAD request, with a URL built from [resource] and the information from the [builder] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.resources.prepareHead) */ public suspend inline fun HttpClient.prepareHead( resource: T, @@ -238,6 +268,8 @@ public suspend inline fun HttpClient.prepareHead( /** * Prepares a [HttpClient] request, with a URL built from [resource] and the information from the [builder] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.resources.prepareRequest) */ public suspend inline fun HttpClient.prepareRequest( resource: T, diff --git a/ktor-client/ktor-client-plugins/ktor-client-tracing/common/src/EngineWIthTracer.kt b/ktor-client/ktor-client-plugins/ktor-client-tracing/common/src/EngineWIthTracer.kt index ff363dd66b4..1a39f2f0e8c 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-tracing/common/src/EngineWIthTracer.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-tracing/common/src/EngineWIthTracer.kt @@ -17,6 +17,8 @@ import io.ktor.utils.io.* /** * Engine with tracer that wraps request execution into tracing functionality. Calls correspondent [tracer] method on * every important processing event. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugin.tracing.EngineWithTracer) */ @InternalAPI class EngineWithTracer( diff --git a/ktor-client/ktor-client-plugins/ktor-client-tracing/common/src/Tracer.kt b/ktor-client/ktor-client-plugins/ktor-client-tracing/common/src/Tracer.kt index 11242db3664..1ca867a027f 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-tracing/common/src/Tracer.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-tracing/common/src/Tracer.kt @@ -11,45 +11,63 @@ import io.ktor.websocket.* * Tracer interface invoked at crucial points of the request processing to handle important events such as a start of * the request processing, a receiving of response headers, a receiving of data and so on. Implementations of this * interface are responsible for saving and presenting these events. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugin.tracing.Tracer) */ interface Tracer { /** * Indicates that the request processing has been start and request will be sent soon. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugin.tracing.Tracer.requestWillBeSent) */ fun requestWillBeSent(requestId: String, requestData: HttpRequestData) /** * Indicates that the response processing has been started and headers were read. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugin.tracing.Tracer.responseHeadersReceived) */ fun responseHeadersReceived(requestId: String, requestData: HttpRequestData, responseData: HttpResponseData) /** * Wraps input channel to pass it to underlying implementation. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugin.tracing.Tracer.interpretResponse) */ fun interpretResponse(requestId: String, contentType: String?, contentEncoding: String?, body: Any?): Any? /** * Indicates that communication with the server has failed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugin.tracing.Tracer.httpExchangeFailed) */ fun httpExchangeFailed(requestId: String, message: String) /** * Indicates that communication with the server has finished. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugin.tracing.Tracer.responseReadFinished) */ fun responseReadFinished(requestId: String) /** * Invoked when a socket is created. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugin.tracing.Tracer.webSocketCreated) */ fun webSocketCreated(requestId: String, url: String) /** * Invoked specifically for websockets to communicate the WebSocket upgrade messages. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugin.tracing.Tracer.webSocketWillSendHandshakeRequest) */ fun webSocketWillSendHandshakeRequest(requestId: String, requestData: HttpRequestData) /** * Delivers the reply from the peer in response to the WebSocket upgrade request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugin.tracing.Tracer.webSocketHandshakeResponseReceived) */ fun webSocketHandshakeResponseReceived( requestId: String, @@ -59,16 +77,22 @@ interface Tracer { /** * Send a "websocket" frame from our app to the remote peer. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugin.tracing.Tracer.webSocketFrameSent) */ fun webSocketFrameSent(requestId: String, frame: Frame) /** * The receive side of {@link #webSocketFrameSent}. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugin.tracing.Tracer.webSocketFrameReceived) */ fun webSocketFrameReceived(requestId: String, frame: Frame) /** * Socket has been closed for unknown reasons. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugin.tracing.Tracer.webSocketClosed) */ fun webSocketClosed(requestId: String) } diff --git a/ktor-client/ktor-client-plugins/ktor-client-tracing/common/src/TracingWrapper.kt b/ktor-client/ktor-client-plugins/ktor-client-tracing/common/src/TracingWrapper.kt index a5883c6ef6d..e63f27a4d1c 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-tracing/common/src/TracingWrapper.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-tracing/common/src/TracingWrapper.kt @@ -8,6 +8,8 @@ import io.ktor.client.engine.* /** * Tracing wrapper that wraps [HttpClientEngineFactory] and creates [EngineWithTracer] instead of original engine. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugin.tracing.TracingWrapper) */ class TracingWrapper( private val delegate: HttpClientEngineFactory, diff --git a/ktor-client/ktor-client-plugins/ktor-client-tracing/ktor-client-tracing-stetho/android/src/io/ktor/client/features/tracing/StethoTracer.kt b/ktor-client/ktor-client-plugins/ktor-client-tracing/ktor-client-tracing-stetho/android/src/io/ktor/client/features/tracing/StethoTracer.kt index cd5ef018eec..9b985fffa0b 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-tracing/ktor-client-tracing-stetho/android/src/io/ktor/client/features/tracing/StethoTracer.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-tracing/ktor-client-tracing-stetho/android/src/io/ktor/client/features/tracing/StethoTracer.kt @@ -15,12 +15,16 @@ import io.ktor.utils.io.jvm.javaio.* /** * Shortcut that allows to easily wrap engine factory into Stetho tracer. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugin.tracing.Stetho) */ fun Context.Stetho(delegate: HttpClientEngineFactory): HttpClientEngineFactory = TracingWrapper(delegate, StethoTracer(this)) /** * Implementation of [Tracer] based on Stetho Android library. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugin.tracing.StethoTracer) */ class StethoTracer(context: Context) : Tracer { /** diff --git a/ktor-client/ktor-client-test-base/common/src/io/ktor/client/test/base/ClientEngineTest.kt b/ktor-client/ktor-client-test-base/common/src/io/ktor/client/test/base/ClientEngineTest.kt index fab48a70a93..ced54eff082 100644 --- a/ktor-client/ktor-client-test-base/common/src/io/ktor/client/test/base/ClientEngineTest.kt +++ b/ktor-client/ktor-client-test-base/common/src/io/ktor/client/test/base/ClientEngineTest.kt @@ -11,7 +11,11 @@ import kotlin.time.Duration.Companion.minutes abstract class ClientEngineTest(private val factory: HttpClientEngineFactory) { - /** Perform test against the client specified in the test constructor. */ + /** + * Perform test against the client specified in the test constructor. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.test.base.ClientEngineTest.testClient) + */ fun testClient( timeout: Duration = 1.minutes, retries: Int = DEFAULT_RETRIES, diff --git a/ktor-client/ktor-client-test-base/common/src/io/ktor/client/test/base/ClientLoader.kt b/ktor-client/ktor-client-test-base/common/src/io/ktor/client/test/base/ClientLoader.kt index b8925b6997a..f2602391e3b 100644 --- a/ktor-client/ktor-client-test-base/common/src/io/ktor/client/test/base/ClientLoader.kt +++ b/ktor-client/ktor-client-test-base/common/src/io/ktor/client/test/base/ClientLoader.kt @@ -21,10 +21,14 @@ private typealias ClientTestFailure = TestFailure> /** * Helper interface to test clients. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.test.base.ClientLoader) */ abstract class ClientLoader(private val timeout: Duration = 1.minutes) { /** * Perform test against all clients from dependencies. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.test.base.ClientLoader.clientTests) */ fun clientTests( rule: EngineSelectionRule = EngineSelectionRule { true }, @@ -68,6 +72,8 @@ abstract class ClientLoader(private val timeout: Duration = 1.minutes) { /** * Print coroutines in debug mode. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.test.base.ClientLoader.dumpCoroutines) */ fun dumpCoroutines(): Unit = platformDumpCoroutines() @@ -77,22 +83,38 @@ abstract class ClientLoader(private val timeout: Duration = 1.minutes) { // @After fun waitForAllCoroutines(): Unit = platformWaitForAllCoroutines() - /** Defines that test should be executed only with the specified [engine]. */ + /** + * Defines that test should be executed only with the specified [engine]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.test.base.ClientLoader.only) + */ fun only(engine: String): EngineSelectionRule { val pattern = EnginePattern.parse(engine) return EngineSelectionRule { pattern.matches(it) } } - /** Includes the set of [engines] for the test */ + /** + * Includes the set of [engines] for the test + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.test.base.ClientLoader.only) + */ fun only(vararg engines: String): EngineSelectionRule { val includePatterns = engines.map(EnginePattern::parse) return EngineSelectionRule { engineName -> includePatterns.any { it.matches(engineName) } } } - /** Excludes the specified [engines] from test execution. */ + /** + * Excludes the specified [engines] from test execution. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.test.base.ClientLoader.except) + */ fun except(vararg engines: String): EngineSelectionRule = except(engines.asList()) - /** Excludes the specified [engines] from test execution. */ + /** + * Excludes the specified [engines] from test execution. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.test.base.ClientLoader.except) + */ fun except(engines: List): EngineSelectionRule { val skipPatterns = engines.map(EnginePattern::parse) return EngineSelectionRule { engineName -> skipPatterns.none { it.matches(engineName) } } @@ -175,6 +197,9 @@ internal val HttpClientEngineFactory<*>.engineName: String /** * Decides whether an engine should be tested or not. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.test.base.EngineSelectionRule) + * * @see ClientLoader.except * @see ClientLoader.only */ diff --git a/ktor-client/ktor-client-test-base/common/src/io/ktor/client/test/base/CommonClientTestUtils.kt b/ktor-client/ktor-client-test-base/common/src/io/ktor/client/test/base/CommonClientTestUtils.kt index 1c8928ed5f5..330afd104c5 100644 --- a/ktor-client/ktor-client-test-base/common/src/io/ktor/client/test/base/CommonClientTestUtils.kt +++ b/ktor-client/ktor-client-test-base/common/src/io/ktor/client/test/base/CommonClientTestUtils.kt @@ -13,21 +13,29 @@ import kotlin.time.Duration.Companion.minutes /** * Web url for tests. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.test.base.TEST_SERVER) */ const val TEST_SERVER: String = "http://127.0.0.1:8080" /** * Websocket server url for tests. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.test.base.TEST_WEBSOCKET_SERVER) */ const val TEST_WEBSOCKET_SERVER: String = "ws://127.0.0.1:8080" /** * Proxy server url for tests. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.test.base.TCP_SERVER) */ const val TCP_SERVER: String = "http://127.0.0.1:8082" /** * Perform test with selected client [engine]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.test.base.testWithEngine) */ fun testWithEngine( engine: HttpClientEngine, @@ -63,6 +71,8 @@ private fun testWithClient( /** * Perform test with selected client engine [factory]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.test.base.testWithEngine) */ fun testWithEngine( factory: HttpClientEngineFactory, diff --git a/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/ContentTest.kt b/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/ContentTest.kt index 7d53209b38b..e1619c58133 100644 --- a/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/ContentTest.kt +++ b/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/ContentTest.kt @@ -394,6 +394,8 @@ class ContentTest : ClientLoader() { /** * This is a bit of an edge case where the initial content reader fails to read the response body * before a second reader comes in. When this happens, we simply cancel the initial reader. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.tests.ContentTest.testSaveBody) */ @OptIn(InternalAPI::class) @Test diff --git a/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/MultiPartFormDataTest.kt b/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/MultiPartFormDataTest.kt index 2067fecfecc..ebbbe910045 100644 --- a/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/MultiPartFormDataTest.kt +++ b/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/MultiPartFormDataTest.kt @@ -19,6 +19,8 @@ import kotlin.test.fail /** * Tests client request with multi-part form data. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.tests.MultiPartFormDataTest) */ class MultiPartFormDataTest : ClientLoader() { diff --git a/ktor-client/ktor-client-tests/jvm/test/io/ktor/client/tests/CookiesAndRedirectMockedTest.kt b/ktor-client/ktor-client-tests/jvm/test/io/ktor/client/tests/CookiesAndRedirectMockedTest.kt index 5ccaf413ef6..ed26e9ef2a9 100644 --- a/ktor-client/ktor-client-tests/jvm/test/io/ktor/client/tests/CookiesAndRedirectMockedTest.kt +++ b/ktor-client/ktor-client-tests/jvm/test/io/ktor/client/tests/CookiesAndRedirectMockedTest.kt @@ -18,6 +18,8 @@ import kotlin.test.* * This test class demonstrates how request cookies behave in a client * when expired and redirected by server (session log out); * and how [HttpCookies] feature manages request cookies in this context. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.tests.CookiesAndRedirectMockedTest) */ class CookiesAndRedirectMockedTest { @Test @@ -41,6 +43,8 @@ class CookiesAndRedirectMockedTest { * the client will ignore (session) cookie expiration from server in a log-out-and-redirect scenario. * This kinda makes sense due to [HttpRequestBuilder.cookie] being a fairly simple and direct way to add cookie to request; * but this result behaviour may or may not be desirable. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.tests.CookiesAndRedirectMockedTest.testRequestCookieCannotBeExpiredAndIsSentWhenRedirectedWithoutCookiesFeature) */ @Test fun testRequestCookieCannotBeExpiredAndIsSentWhenRedirectedWithoutCookiesFeature() = testWithEngine(MockEngine) { @@ -70,6 +74,8 @@ class CookiesAndRedirectMockedTest { /** * [HttpCookies] feature should respect (additional) request cookies + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.tests.CookiesAndRedirectMockedTest.testRequestCookieIsSentWithCookiesFeature) */ @Test fun testRequestCookieIsSentWithCookiesFeature() = testWithEngine(MockEngine) { @@ -97,6 +103,8 @@ class CookiesAndRedirectMockedTest { /** * [HttpCookies] feature should manage request cookies and its expiration properly, * and not send it in redirection if it's expired by server. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.tests.CookiesAndRedirectMockedTest.testRequestCookieCanBeExpiredAndIsNotSentWhenRedirectedWithCookiesFeature) */ @Test fun testRequestCookieCanBeExpiredAndIsNotSentWhenRedirectedWithCookiesFeature() = testWithEngine(MockEngine) { diff --git a/ktor-client/ktor-client-winhttp/windows/src/io/ktor/client/engine/winhttp/WinHttp.kt b/ktor-client/ktor-client-winhttp/windows/src/io/ktor/client/engine/winhttp/WinHttp.kt index 793084c1639..61bca710fe8 100644 --- a/ktor-client/ktor-client-winhttp/windows/src/io/ktor/client/engine/winhttp/WinHttp.kt +++ b/ktor-client/ktor-client-winhttp/windows/src/io/ktor/client/engine/winhttp/WinHttp.kt @@ -28,6 +28,8 @@ private val initHook = WinHttp * ``` * * You can learn more about client engines from [Engines](https://ktor.io/docs/http-client-engines.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.winhttp.WinHttp) */ @OptIn(InternalAPI::class) public data object WinHttp : HttpClientEngineFactory { diff --git a/ktor-client/ktor-client-winhttp/windows/src/io/ktor/client/engine/winhttp/WinHttpClientEngineConfig.kt b/ktor-client/ktor-client-winhttp/windows/src/io/ktor/client/engine/winhttp/WinHttpClientEngineConfig.kt index 4a1b7c1ceed..782df8ebbf8 100644 --- a/ktor-client/ktor-client-winhttp/windows/src/io/ktor/client/engine/winhttp/WinHttpClientEngineConfig.kt +++ b/ktor-client/ktor-client-winhttp/windows/src/io/ktor/client/engine/winhttp/WinHttpClientEngineConfig.kt @@ -12,17 +12,23 @@ public class WinHttpClientEngineConfig : HttpClientEngineConfig() { /** * A value indicating whether HTTP 2.0 protocol is enabled in WinHTTP. * The default value is true. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.winhttp.WinHttpClientEngineConfig.protocolVersion) */ public var protocolVersion: HttpProtocolVersion = HttpProtocolVersion.HTTP_2_0 /** * A value that allows to set required security protocol versions. * By default will be used system setting. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.winhttp.WinHttpClientEngineConfig.securityProtocols) */ public var securityProtocols: WinHttpSecurityProtocol = WinHttpSecurityProtocol.Default /** * A value that disables TLS verification for outgoing requests. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.winhttp.WinHttpClientEngineConfig.sslVerify) */ public var sslVerify: Boolean = true } diff --git a/ktor-client/ktor-client-winhttp/windows/src/io/ktor/client/engine/winhttp/WinHttpSecurityProtocol.kt b/ktor-client/ktor-client-winhttp/windows/src/io/ktor/client/engine/winhttp/WinHttpSecurityProtocol.kt index 7404f239a6e..8acb2a9250b 100644 --- a/ktor-client/ktor-client-winhttp/windows/src/io/ktor/client/engine/winhttp/WinHttpSecurityProtocol.kt +++ b/ktor-client/ktor-client-winhttp/windows/src/io/ktor/client/engine/winhttp/WinHttpSecurityProtocol.kt @@ -6,6 +6,8 @@ package io.ktor.client.engine.winhttp /** * Defines which transport security protocol should be used during establishing connection. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.winhttp.WinHttpSecurityProtocol) */ public enum class WinHttpSecurityProtocol(internal val value: Int) { Default(0), diff --git a/ktor-client/ktor-client-winhttp/windows/test/io/ktor/client/engine/winhttp/WinHttpProxyTest.kt b/ktor-client/ktor-client-winhttp/windows/test/io/ktor/client/engine/winhttp/WinHttpProxyTest.kt index 3af3e9964d4..8ded07c6ac3 100644 --- a/ktor-client/ktor-client-winhttp/windows/test/io/ktor/client/engine/winhttp/WinHttpProxyTest.kt +++ b/ktor-client/ktor-client-winhttp/windows/test/io/ktor/client/engine/winhttp/WinHttpProxyTest.kt @@ -17,6 +17,8 @@ private const val HTTP_PROXY_SERVER: String = TCP_SERVER /** * This is a temporary tests that should be moved to the general test suite * once we support TLS options in client configs to connect to the local test TLS server. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.engine.winhttp.WinHttpProxyTest) */ class WinHttpProxyTest : ClientEngineTest(WinHttp) { diff --git a/ktor-http/common/src/io/ktor/http/ApplicationResponseProperties.kt b/ktor-http/common/src/io/ktor/http/ApplicationResponseProperties.kt index 307e7c1d281..1d01433d062 100644 --- a/ktor-http/common/src/io/ktor/http/ApplicationResponseProperties.kt +++ b/ktor-http/common/src/io/ktor/http/ApplicationResponseProperties.kt @@ -6,5 +6,7 @@ package io.ktor.http /** * Set `E-Tag` header + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.etag) */ public fun HeadersBuilder.etag(entityTag: String): Unit = set(HttpHeaders.ETag, entityTag) diff --git a/ktor-http/common/src/io/ktor/http/CacheControl.kt b/ktor-http/common/src/io/ktor/http/CacheControl.kt index 42ad209273f..f517ef0c543 100644 --- a/ktor-http/common/src/io/ktor/http/CacheControl.kt +++ b/ktor-http/common/src/io/ktor/http/CacheControl.kt @@ -7,27 +7,38 @@ package io.ktor.http /** * Represents a value for a `Cache-Control` header * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.CacheControl) + * * @param visibility specifies an optional visibility such as private or public */ public abstract class CacheControl(public val visibility: Visibility?) { /** * Controls caching by proxies + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.CacheControl.Visibility) */ public enum class Visibility(internal val headerValue: String) { /** * Specifies that the response is cacheable by clients and shared (proxy) caches. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.CacheControl.Visibility.Public) */ Public("public"), /** * Specifies that the response is cacheable only on the client and not by shared (proxy server) caches. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.CacheControl.Visibility.Private) */ Private("private") } /** * Represents a no-cache cache control value + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.CacheControl.NoCache) */ public class NoCache(visibility: Visibility?) : CacheControl(visibility) { override fun toString(): String = if (visibility == null) { @@ -47,6 +58,8 @@ public abstract class CacheControl(public val visibility: Visibility?) { /** * Represents a no-store cache control value + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.CacheControl.NoStore) */ public class NoStore(visibility: Visibility?) : CacheControl(visibility) { override fun toString(): String = if (visibility == null) { @@ -66,6 +79,9 @@ public abstract class CacheControl(public val visibility: Visibility?) { /** * Represents a cache control value with the specified max ages and re-validation strategies + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.CacheControl.MaxAge) + * * @property maxAgeSeconds max-age in seconds * @property proxyMaxAgeSeconds max-age in seconds for caching proxies * @property mustRevalidate `true` if a client must validate in spite of age diff --git a/ktor-http/common/src/io/ktor/http/Codecs.kt b/ktor-http/common/src/io/ktor/http/Codecs.kt index 9730c50b140..8173028c8b2 100644 --- a/ktor-http/common/src/io/ktor/http/Codecs.kt +++ b/ktor-http/common/src/io/ktor/http/Codecs.kt @@ -46,6 +46,8 @@ private val SPECIAL_SYMBOLS = listOf('-', '.', '_', '~').map { it.code.toByte() /** * Encode url part as specified in * https://tools.ietf.org/html/rfc3986#section-2 + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.encodeURLQueryComponent) */ public fun String.encodeURLQueryComponent( encodeFull: Boolean = false, @@ -64,6 +66,8 @@ public fun String.encodeURLQueryComponent( /** * Encodes URL path segment. It escapes all illegal or ambiguous characters + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.encodeURLPathPart) */ public fun String.encodeURLPathPart(): String = encodeURLPath(encodeSlash = true) @@ -71,6 +75,9 @@ public fun String.encodeURLPathPart(): String = encodeURLPath(encodeSlash = true * Get the URL-encoding of this string, with options to skip / characters or to prevent * encoding already-encoded characters (%hh items). * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.encodeURLPath) + * * @see [RFC-3986](https://datatracker.ietf.org/doc/html/rfc3986#section-2.1) * @param encodeSlash / characters will be encoded as %2F; defaults to false * @param encodeEncoded %hh will be encoded as %25hh; defaults to true @@ -116,11 +123,15 @@ public fun String.encodeURLPath( /** * Encode [this] in percent encoding specified here: * https://tools.ietf.org/html/rfc5849#section-3.6 + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.encodeOAuth) */ public fun String.encodeOAuth(): String = encodeURLParameter() /** * Encode [this] as query parameter key. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.encodeURLParameter) */ public fun String.encodeURLParameter( spaceToPlus: Boolean = false @@ -171,6 +182,8 @@ internal fun String.encodeURLParameterValue(): String = encodeURLParameter(space /** * Decode URL query component + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.decodeURLQueryComponent) */ public fun String.decodeURLQueryComponent( start: Int = 0, @@ -182,6 +195,8 @@ public fun String.decodeURLQueryComponent( /** * Decode percent encoded URL part within the specified range [[start], [end]). * This function is not intended to decode urlencoded forms so it doesn't decode plus character to space. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.decodeURLPart) */ public fun String.decodeURLPart( start: Int = 0, @@ -270,6 +285,8 @@ private fun CharSequence.decodeImpl( /** * URL decoder exception + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.URLDecodeException) */ public class URLDecodeException(message: String) : Exception(message) diff --git a/ktor-http/common/src/io/ktor/http/ContentDisposition.kt b/ktor-http/common/src/io/ktor/http/ContentDisposition.kt index e523faa9ef1..eaa68004d5d 100644 --- a/ktor-http/common/src/io/ktor/http/ContentDisposition.kt +++ b/ktor-http/common/src/io/ktor/http/ContentDisposition.kt @@ -6,6 +6,8 @@ package io.ktor.http /** * Represents `Content-Disposition` header value + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.ContentDisposition) */ public class ContentDisposition( disposition: String, @@ -13,17 +15,23 @@ public class ContentDisposition( ) : HeaderValueWithParameters(disposition, parameters) { /** * Content disposition value without parameters + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.ContentDisposition.disposition) */ public val disposition: String get() = content /** * Content disposition name (from parameter named `name`) + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.ContentDisposition.name) */ public val name: String? get() = parameter(Parameters.Name) /** * Creates new with parameter appended. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.ContentDisposition.withParameter) */ public fun withParameter(key: String, value: String, encodeValue: Boolean = true): ContentDisposition { val encodedValue = if (encodeValue) { @@ -37,6 +45,8 @@ public class ContentDisposition( /** * Creates new with parameters appended + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.ContentDisposition.withParameters) */ public fun withParameters(newParameters: List): ContentDisposition = ContentDisposition(disposition, parameters + newParameters) @@ -52,32 +62,44 @@ public class ContentDisposition( public companion object { /** * `Content-Disposition: file` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.ContentDisposition.Companion.File) */ public val File: ContentDisposition = ContentDisposition("file") /** * `Content-Disposition: mixed` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.ContentDisposition.Companion.Mixed) */ public val Mixed: ContentDisposition = ContentDisposition("mixed") /** * `Content-Disposition: attachment` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.ContentDisposition.Companion.Attachment) */ public val Attachment: ContentDisposition = ContentDisposition("attachment") /** * `Content-Disposition: inline` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.ContentDisposition.Companion.Inline) */ public val Inline: ContentDisposition = ContentDisposition("inline") /** * Parse `Content-Disposition` header [value] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.ContentDisposition.Companion.parse) */ public fun parse(value: String): ContentDisposition = parse(value) { v, p -> ContentDisposition(v, p) } } /** * Frequently used content disposition parameter names + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.ContentDisposition.Parameters) */ @Suppress("KDocMissingDocumentation", "unused", "PublicApiImplicitType") public object Parameters { diff --git a/ktor-http/common/src/io/ktor/http/ContentRange.kt b/ktor-http/common/src/io/ktor/http/ContentRange.kt index 406175c3403..0c2dba7f0fb 100644 --- a/ktor-http/common/src/io/ktor/http/ContentRange.kt +++ b/ktor-http/common/src/io/ktor/http/ContentRange.kt @@ -8,6 +8,8 @@ import io.ktor.util.* /** * Format `Content-Range` header value + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.contentRangeHeaderValue) */ public fun contentRangeHeaderValue( range: LongRange?, @@ -18,6 +20,8 @@ public fun contentRangeHeaderValue( /** * Format `Content-Range` header value + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.contentRangeHeaderValue) */ public fun contentRangeHeaderValue( range: LongRange?, diff --git a/ktor-http/common/src/io/ktor/http/ContentTypeMatcher.kt b/ktor-http/common/src/io/ktor/http/ContentTypeMatcher.kt index fa4c6668376..a7584796bca 100644 --- a/ktor-http/common/src/io/ktor/http/ContentTypeMatcher.kt +++ b/ktor-http/common/src/io/ktor/http/ContentTypeMatcher.kt @@ -6,10 +6,14 @@ package io.ktor.http /** * Interface for any objects that can match a [ContentType]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.ContentTypeMatcher) */ public interface ContentTypeMatcher { /** * Checks if `this` type matches a [contentType] type. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.ContentTypeMatcher.contains) */ public fun contains(contentType: ContentType): Boolean } diff --git a/ktor-http/common/src/io/ktor/http/ContentTypes.kt b/ktor-http/common/src/io/ktor/http/ContentTypes.kt index ca02d62430f..ebee4024763 100644 --- a/ktor-http/common/src/io/ktor/http/ContentTypes.kt +++ b/ktor-http/common/src/io/ktor/http/ContentTypes.kt @@ -8,6 +8,9 @@ import io.ktor.utils.io.charsets.* /** * Represents a value for a `Content-Type` header. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.ContentType) + * * @property contentType represents a type part of the media type. * @property contentSubtype represents a subtype part of the media type. */ @@ -31,6 +34,8 @@ public class ContentType private constructor( /** * Creates a copy of `this` type with the added parameter with the [name] and [value]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.ContentType.withParameter) */ public fun withParameter(name: String, value: String): ContentType { if (hasParameter(name, value)) return this @@ -46,6 +51,8 @@ public class ContentType private constructor( /** * Creates a copy of `this` type without any parameters + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.ContentType.withoutParameters) */ public fun withoutParameters(): ContentType = when { parameters.isEmpty() -> this @@ -62,6 +69,8 @@ public class ContentType private constructor( * ContentType("a", "*").match(ContentType("a", "b")) === false * ContentType("a", "b").match(ContentType("a", "*")) === true * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.ContentType.match) */ public fun match(pattern: ContentType): Boolean { if (pattern.contentType != "*" && !pattern.contentType.equals(contentType, ignoreCase = true)) { @@ -99,6 +108,8 @@ public class ContentType private constructor( /** * Checks if `this` type matches a [pattern] type taking into account placeholder symbols `*` and parameters. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.ContentType.match) */ public fun match(pattern: String): Boolean = match(parse(pattern)) @@ -118,6 +129,8 @@ public class ContentType private constructor( public companion object { /** * Parses a string representing a `Content-Type` header into a [ContentType] instance. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.ContentType.Companion.parse) */ public fun parse(value: String): ContentType { if (value.isBlank()) return Any @@ -153,17 +166,23 @@ public class ContentType private constructor( /** * Represents a pattern `* / *` to match any content type. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.ContentType.Companion.Any) */ public val Any: ContentType = ContentType("*", "*") } /** * Provides a list of standard subtypes of an `application` content type. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.ContentType.Application) */ @Suppress("KDocMissingDocumentation", "unused") public object Application { /** * Represents a pattern `application / *` to match any application content type. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.ContentType.Application.Any) */ public val Any: ContentType = ContentType("application", "*") public val Atom: ContentType = ContentType("application", "atom+xml") @@ -204,6 +223,8 @@ public class ContentType private constructor( /** * Provides a list of standard subtypes of an `audio` content type. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.ContentType.Audio) */ @Suppress("KDocMissingDocumentation", "unused") public object Audio { @@ -215,6 +236,8 @@ public class ContentType private constructor( /** * Provides a list of standard subtypes of an `image` content type. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.ContentType.Image) */ @Suppress("KDocMissingDocumentation", "unused") public object Image { @@ -228,6 +251,8 @@ public class ContentType private constructor( /** * Provides a list of standard subtypes of a `message` content type. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.ContentType.Message) */ @Suppress("KDocMissingDocumentation", "unused") public object Message { @@ -237,6 +262,8 @@ public class ContentType private constructor( /** * Provides a list of standard subtypes of a `multipart` content type. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.ContentType.MultiPart) */ @Suppress("KDocMissingDocumentation", "unused") public object MultiPart { @@ -252,6 +279,8 @@ public class ContentType private constructor( /** * Provides a list of standard subtypes of a `text` content type. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.ContentType.Text) */ @Suppress("KDocMissingDocumentation", "unused") public object Text { @@ -268,6 +297,8 @@ public class ContentType private constructor( /** * Provides a list of standard subtypes of a `video` content type. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.ContentType.Video) */ @Suppress("KDocMissingDocumentation", "unused") public object Video { @@ -280,6 +311,8 @@ public class ContentType private constructor( /** * Provides a list of standard subtypes of a `font` content type. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.ContentType.Font) */ @Suppress("KDocMissingDocumentation", "unused") public object Font { @@ -295,11 +328,15 @@ public class ContentType private constructor( /** * Exception thrown when a content type string is malformed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.BadContentTypeFormatException) */ public class BadContentTypeFormatException(value: String) : Exception("Bad Content-Type format: $value") /** * Creates a copy of `this` type with the added charset parameter with [charset] value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.withCharset) */ public fun ContentType.withCharset(charset: Charset): ContentType = withParameter("charset", charset.name) @@ -307,6 +344,8 @@ public fun ContentType.withCharset(charset: Charset): ContentType = /** * Creates a copy of `this` type with the added charset parameter with [charset] value * if [ContentType] is not ignored + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.withCharsetIfNeeded) */ public fun ContentType.withCharsetIfNeeded(charset: Charset): ContentType = if (contentType.lowercase() != "text") { @@ -317,6 +356,8 @@ public fun ContentType.withCharsetIfNeeded(charset: Charset): ContentType = /** * Extracts a [Charset] value from the given `Content-Type`, `Content-Disposition` or similar header value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.charset) */ public fun HeaderValueWithParameters.charset(): Charset? = parameter("charset")?.let { try { diff --git a/ktor-http/common/src/io/ktor/http/Cookie.kt b/ktor-http/common/src/io/ktor/http/Cookie.kt index 6872c1d466a..ffabb2f1cda 100644 --- a/ktor-http/common/src/io/ktor/http/Cookie.kt +++ b/ktor-http/common/src/io/ktor/http/Cookie.kt @@ -16,6 +16,9 @@ import kotlin.jvm.* * Represents a cookie with name, content and a set of settings such as expiration, visibility and security. * A cookie with neither [expires] nor [maxAge] is a session cookie. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.Cookie) + * * @property name * @property value * @property encoding - cookie encoding type [CookieEncoding] @@ -54,25 +57,35 @@ internal object CookieJvmSerializer : JvmSerializer { /** * Cooke encoding strategy + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.CookieEncoding) */ public enum class CookieEncoding { /** * No encoding (could be dangerous) + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.CookieEncoding.RAW) */ RAW, /** * Double quotes with slash-escaping + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.CookieEncoding.DQUOTES) */ DQUOTES, /** * URI encoding + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.CookieEncoding.URI_ENCODING) */ URI_ENCODING, /** * BASE64 encoding + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.CookieEncoding.BASE64_ENCODING) */ BASE64_ENCODING } @@ -81,6 +94,8 @@ private val loweredPartNames = setOf("max-age", "expires", "domain", "path", "se /** * Parse server's `Set-Cookie` header value + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.parseServerSetCookieHeader) */ public fun parseServerSetCookieHeader(cookiesHeader: String): Cookie { val asMap = parseClientCookiesHeader(cookiesHeader, false) @@ -108,6 +123,8 @@ private val clientCookieHeaderPattern = """(^|;)\s*([^;=\{\}\s]+)\s*(=\s*("[^"]* /** * Parse client's `Cookie` header value + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.parseClientCookiesHeader) */ public fun parseClientCookiesHeader(cookiesHeader: String, skipEscaped: Boolean = true): Map = clientCookieHeaderPattern.findAll(cookiesHeader) @@ -124,6 +141,8 @@ public fun parseClientCookiesHeader(cookiesHeader: String, skipEscaped: Boolean /** * Format `Set-Cookie` header value + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.renderSetCookieHeader) */ public fun renderSetCookieHeader(cookie: Cookie): String = with(cookie) { renderSetCookieHeader( @@ -142,6 +161,8 @@ public fun renderSetCookieHeader(cookie: Cookie): String = with(cookie) { /** * Format `Cookie` header value + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.renderCookieHeader) */ public fun renderCookieHeader(cookie: Cookie): String = with(cookie) { "$name=${encodeCookieValue(value, encoding)}" @@ -149,6 +170,8 @@ public fun renderCookieHeader(cookie: Cookie): String = with(cookie) { /** * Format `Set-Cookie` header value + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.renderSetCookieHeader) */ public fun renderSetCookieHeader( name: String, @@ -179,6 +202,8 @@ public fun renderSetCookieHeader( /** * Encode cookie value using the specified [encoding] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.encodeCookieValue) */ public fun encodeCookieValue(value: String, encoding: CookieEncoding): String = when (encoding) { CookieEncoding.RAW -> value @@ -196,6 +221,8 @@ public fun encodeCookieValue(value: String, encoding: CookieEncoding): String = /** * Decode cookie value using the specified [encoding] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.decodeCookieValue) */ public fun decodeCookieValue(encodedValue: String, encoding: CookieEncoding): String = when (encoding) { CookieEncoding.RAW, CookieEncoding.DQUOTES -> when { diff --git a/ktor-http/common/src/io/ktor/http/DateUtils.kt b/ktor-http/common/src/io/ktor/http/DateUtils.kt index 04548d38161..7051fc2d211 100644 --- a/ktor-http/common/src/io/ktor/http/DateUtils.kt +++ b/ktor-http/common/src/io/ktor/http/DateUtils.kt @@ -25,6 +25,8 @@ private val HTTP_DATE_FORMATS = listOf( * Convert valid http date [String] to [GMTDate] trying various http date formats from [HTTP_DATE_FORMATS] * * Note that only GMT(UTC) date is valid http date. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.fromHttpToGmtDate) */ public fun String.fromHttpToGmtDate(): GMTDate = with(trim()) { for (format in HTTP_DATE_FORMATS) { @@ -41,6 +43,9 @@ public fun String.fromHttpToGmtDate(): GMTDate = with(trim()) { /** * Convert valid cookie date [String] to [GMTDate] trying first the RFC6265 standard, falling back on [fromHttpToGmtDate] * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.fromCookieToGmtDate) + * * @see [fromHttpToGmtDate] */ public fun String.fromCookieToGmtDate(): GMTDate = with(trim()) { @@ -55,6 +60,8 @@ public fun String.fromCookieToGmtDate(): GMTDate = with(trim()) { /** * Convert [GMTDate] to valid http date [String] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.toHttpDate) */ public fun GMTDate.toHttpDate(): String = buildString { append("${dayOfWeek.value}, ") diff --git a/ktor-http/common/src/io/ktor/http/FileContentType.kt b/ktor-http/common/src/io/ktor/http/FileContentType.kt index 9bb1327ed22..c3583f9d945 100644 --- a/ktor-http/common/src/io/ktor/http/FileContentType.kt +++ b/ktor-http/common/src/io/ktor/http/FileContentType.kt @@ -9,18 +9,24 @@ import io.ktor.utils.io.charsets.* /** * Default [ContentType] for [extension] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.defaultForFileExtension) */ public fun ContentType.Companion.defaultForFileExtension(extension: String): ContentType = ContentType.fromFileExtension(extension).selectDefault() /** * Default [ContentType] for file [path] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.defaultForFilePath) */ public fun ContentType.Companion.defaultForFilePath(path: String): ContentType = ContentType.fromFilePath(path).selectDefault() /** * Recommended content types by file [path] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.fromFilePath) */ public fun ContentType.Companion.fromFilePath(path: String): List { val slashIndex = path.lastIndexOfAny("/\\".toCharArray()) @@ -33,6 +39,8 @@ public fun ContentType.Companion.fromFilePath(path: String): List { /** * Recommended content type by file name extension + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.fromFileExtension) */ public fun ContentType.Companion.fromFileExtension(ext: String): List { var current = ext.removePrefix(".").toLowerCasePreservingASCIIRules() @@ -49,6 +57,8 @@ public fun ContentType.Companion.fromFileExtension(ext: String): List = extensionsByContentType[this] ?: extensionsByContentType[this.withoutParameters()] diff --git a/ktor-http/common/src/io/ktor/http/HeaderValueWithParameters.kt b/ktor-http/common/src/io/ktor/http/HeaderValueWithParameters.kt index 71ceb993f24..7e6dc89cac4 100644 --- a/ktor-http/common/src/io/ktor/http/HeaderValueWithParameters.kt +++ b/ktor-http/common/src/io/ktor/http/HeaderValueWithParameters.kt @@ -14,6 +14,9 @@ private val HeaderFieldValueSeparators = * Represents a header value that consist of [content] followed by [parameters]. * Useful for headers such as `Content-Type`, `Content-Disposition` and so on. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.HeaderValueWithParameters) + * * @property content header's content without parameters * @property parameters */ @@ -24,6 +27,8 @@ public abstract class HeaderValueWithParameters( /** * The first value for the parameter with [name] comparing case-insensitively or `null` if no such parameters found + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.HeaderValueWithParameters.parameter) */ public fun parameter(name: String): String? { for (index in 0..parameters.lastIndex) { @@ -58,6 +63,8 @@ public abstract class HeaderValueWithParameters( public companion object { /** * Parse header with parameter and pass it to [init] function to instantiate particular type + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.HeaderValueWithParameters.Companion.parse) */ public inline fun parse(value: String, init: (String, List) -> R): R { val headerValue = parseHeaderValue(value).last() @@ -68,6 +75,8 @@ public abstract class HeaderValueWithParameters( /** * Append formatted header value to the builder + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.append) */ public fun StringValuesBuilder.append(name: String, value: HeaderValueWithParameters) { append(name, value.toString()) @@ -75,6 +84,8 @@ public fun StringValuesBuilder.append(name: String, value: HeaderValueWithParame /** * Escape using double quotes if needed or keep as is if no dangerous strings found + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.escapeIfNeeded) */ public fun String.escapeIfNeeded(): String = when { needQuotes() -> quote() @@ -132,6 +143,8 @@ private fun String.isQuoted(): Boolean { /** * Escape string using double quotes + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.quote) */ public fun String.quote(): String = buildString { this@quote.quoteTo(this) } diff --git a/ktor-http/common/src/io/ktor/http/Headers.kt b/ktor-http/common/src/io/ktor/http/Headers.kt index 9a88abf7eee..114b3f2914f 100644 --- a/ktor-http/common/src/io/ktor/http/Headers.kt +++ b/ktor-http/common/src/io/ktor/http/Headers.kt @@ -8,16 +8,23 @@ import io.ktor.util.* /** * Represents HTTP headers as a map from case-insensitive names to collection of [String] values + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.Headers) */ public interface Headers : StringValues { public companion object { /** * Empty [Headers] instance + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.Headers.Companion.Empty) */ public val Empty: Headers = EmptyHeaders /** * Builds a [Headers] instance with the given [builder] function + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.Headers.Companion.build) + * * @param builder specifies a function to build a map */ public inline fun build(builder: HeadersBuilder.() -> Unit): Headers = HeadersBuilder().apply(builder).build() @@ -51,26 +58,37 @@ private object EmptyHeaders : Headers { /** * Returns empty headers + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.headersOf) */ public fun headersOf(): Headers = Headers.Empty /** * Returns [Headers] instance containing only one header with the specified [name] and [value] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.headersOf) */ public fun headersOf(name: String, value: String): Headers = HeadersSingleImpl(name, listOf(value)) /** * Returns [Headers] instance containing only one header with the specified [name] and [values] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.headersOf) */ public fun headersOf(name: String, values: List): Headers = HeadersSingleImpl(name, values) /** * Returns [Headers] instance from [pairs] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.headersOf) */ public fun headersOf(vararg pairs: Pair>): Headers = HeadersImpl(pairs.asList().toMap()) /** * Builds a [Headers] instance with the given [builder] function + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.headers) + * * @param builder specifies a function to build a map */ public fun headers(builder: HeadersBuilder.() -> Unit): Headers = Headers.build(builder) diff --git a/ktor-http/common/src/io/ktor/http/HttpHeaderValueParser.kt b/ktor-http/common/src/io/ktor/http/HttpHeaderValueParser.kt index 6fc3c210ee1..2c84068f0b8 100644 --- a/ktor-http/common/src/io/ktor/http/HttpHeaderValueParser.kt +++ b/ktor-http/common/src/io/ktor/http/HttpHeaderValueParser.kt @@ -6,6 +6,9 @@ package io.ktor.http /** * Represents a single value parameter + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.HeaderValueParam) + * * @property name of parameter * @property value of parameter * @property escapeValue specifies if the value should be escaped @@ -28,12 +31,17 @@ public data class HeaderValueParam(val name: String, val value: String, val esca /** * Represents a header value. Similar to [HeaderValueWithParameters] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.HeaderValue) + * * @property value * @property params for this value (could be empty) */ public data class HeaderValue(val value: String, val params: List = emptyList()) { /** * Value's quality according to `q` parameter or `1.0` if missing or invalid + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.HeaderValue.quality) */ val quality: Double = params.firstOrNull { it.name == "q" } ?.value @@ -44,12 +52,16 @@ public data class HeaderValue(val value: String, val params: List = parseHeaderValue(header).sortedByDescending { it.quality } /** * Parse `Content-Type` header values and sort them by quality and asterisks quantity + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.parseAndSortContentTypeHeader) */ public fun parseAndSortContentTypeHeader(header: String?): List = parseHeaderValue(header).sortedWith( compareByDescending { it.quality }.thenBy { @@ -67,6 +79,8 @@ public fun parseAndSortContentTypeHeader(header: String?): List = p /** * Parse header value respecting multi-values + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.parseHeaderValue) */ public fun parseHeaderValue(text: String?): List { return parseHeaderValue(text, false) @@ -74,6 +88,9 @@ public fun parseHeaderValue(text: String?): List { /** * Parse header value respecting multi-values + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.parseHeaderValue) + * * @param parametersOnly if no header value itself, only parameters */ public fun parseHeaderValue(text: String?, parametersOnly: Boolean): List { @@ -91,6 +108,8 @@ public fun parseHeaderValue(text: String?, parametersOnly: Boolean): List
>.toHeaderParamsList(): List = map { HeaderValueParam(it.first, it.second) } diff --git a/ktor-http/common/src/io/ktor/http/HttpHeaders.kt b/ktor-http/common/src/io/ktor/http/HttpHeaders.kt index fe6440bd646..be8e33a0e7b 100644 --- a/ktor-http/common/src/io/ktor/http/HttpHeaders.kt +++ b/ktor-http/common/src/io/ktor/http/HttpHeaders.kt @@ -126,6 +126,8 @@ public object HttpHeaders { /** * Check if [header] is unsafe. Header is unsafe if listed in [UnsafeHeadersList] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.HttpHeaders.isUnsafe) */ public fun isUnsafe(header: String): Boolean = UnsafeHeadersArray.any { it.equals(header, ignoreCase = true) } @@ -141,11 +143,15 @@ public object HttpHeaders { /** * A list of header names that are not safe to use unless it is low-level engine implementation. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.HttpHeaders.UnsafeHeadersList) */ public val UnsafeHeadersList: List = UnsafeHeadersArray.asList() /** * Validates header [name] throwing [IllegalHeaderNameException] when the name is not valid. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.HttpHeaders.checkHeaderName) */ public fun checkHeaderName(name: String) { name.forEachIndexed { index, ch -> @@ -157,6 +163,8 @@ public object HttpHeaders { /** * Validates header [value] throwing [IllegalHeaderValueException] when the value is not valid. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.HttpHeaders.checkHeaderValue) */ public fun checkHeaderValue(value: String) { value.forEachIndexed { index, ch -> @@ -169,6 +177,8 @@ public object HttpHeaders { /** * Thrown when an attempt to set unsafe header detected. A header is unsafe if listed in [HttpHeaders.UnsafeHeadersList]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.UnsafeHeaderException) */ public class UnsafeHeaderException(header: String) : IllegalArgumentException( "Header(s) $header are controlled by the engine and " + @@ -179,6 +189,9 @@ public class UnsafeHeaderException(header: String) : IllegalArgumentException( * Thrown when an illegal header name was used. * A header name should only consist from visible characters * without delimiters "double quote" and the following characters: `(),/:;<=>?@[\]{}`. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.IllegalHeaderNameException) + * * @property headerName that was tried to use * @property position at which validation failed */ @@ -191,6 +204,9 @@ public class IllegalHeaderNameException(public val headerName: String, public va /** * Thrown when an illegal header value was used. * A header value should only consist from visible characters, spaces and/or HTAB (0x09). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.IllegalHeaderValueException) + * * @property headerValue that was tried to use * @property position at which validation failed */ diff --git a/ktor-http/common/src/io/ktor/http/HttpMessage.kt b/ktor-http/common/src/io/ktor/http/HttpMessage.kt index 800e69f1da5..a915bb46a37 100644 --- a/ktor-http/common/src/io/ktor/http/HttpMessage.kt +++ b/ktor-http/common/src/io/ktor/http/HttpMessage.kt @@ -7,10 +7,14 @@ package io.ktor.http /** * A message either from the client or the server, * that has [headers] associated. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.HttpMessage) */ public interface HttpMessage { /** * Message [Headers] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.HttpMessage.headers) */ public val headers: Headers } @@ -18,10 +22,14 @@ public interface HttpMessage { /** * A builder message either for the client or the server, * that has a [headers] builder associated. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.HttpMessageBuilder) */ public interface HttpMessageBuilder { /** * MessageBuilder [HeadersBuilder] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.HttpMessageBuilder.headers) */ public val headers: HeadersBuilder } diff --git a/ktor-http/common/src/io/ktor/http/HttpMessageProperties.kt b/ktor-http/common/src/io/ktor/http/HttpMessageProperties.kt index 02e224b520a..d86232d26ae 100644 --- a/ktor-http/common/src/io/ktor/http/HttpMessageProperties.kt +++ b/ktor-http/common/src/io/ktor/http/HttpMessageProperties.kt @@ -10,43 +10,59 @@ import io.ktor.utils.io.charsets.* /** * Set `Content-Type` header. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.contentType) */ public fun HttpMessageBuilder.contentType(type: ContentType): Unit = headers.set(HttpHeaders.ContentType, type.toString()) /** * Append `Max-Age` header value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.maxAge) */ public fun HttpMessageBuilder.maxAge(seconds: Int): Unit = headers.append(HttpHeaders.CacheControl, "max-age=$seconds") /** * Set `If-None-Match` header value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.ifNoneMatch) */ public fun HttpMessageBuilder.ifNoneMatch(value: String): Unit = headers.set(HttpHeaders.IfNoneMatch, value) /** * Set `User-Agent` header value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.userAgent) */ public fun HttpMessageBuilder.userAgent(content: String): Unit = headers.set(HttpHeaders.UserAgent, content) /** * Parse `Content-Type` header value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.contentType) */ public fun HttpMessageBuilder.contentType(): ContentType? = headers[HttpHeaders.ContentType]?.let { ContentType.parse(it) } /** * Parse charset from `Content-Type` header value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.charset) */ public fun HttpMessageBuilder.charset(): Charset? = contentType()?.charset() /** * Parse `E-Tag` header value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.etag) */ public fun HttpMessageBuilder.etag(): String? = headers[HttpHeaders.ETag] /** * Parse `Vary` header value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.vary) */ public fun HttpMessageBuilder.vary(): List? = headers.getAll(HttpHeaders.Vary)?.flatMap { varyKeys -> varyKeys.split(",").map { it.trim() } @@ -54,26 +70,36 @@ public fun HttpMessageBuilder.vary(): List? = headers.getAll(HttpHeaders /** * Parse `Content-Length` header value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.contentLength) */ public fun HttpMessageBuilder.contentLength(): Long? = headers[HttpHeaders.ContentLength]?.toLong() /** * Parse `Content-Type` header value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.contentType) */ public fun HttpMessage.contentType(): ContentType? = headers[HttpHeaders.ContentType]?.let { ContentType.parse(it) } /** * Parse charset from `Content-Type` header value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.charset) */ public fun HttpMessage.charset(): Charset? = contentType()?.charset() /** * Parse `E-Tag` header value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.etag) */ public fun HttpMessage.etag(): String? = headers[HttpHeaders.ETag] /** * Parse `Vary` header value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.vary) */ public fun HttpMessage.vary(): List? = headers.getAll(HttpHeaders.Vary)?.flatMap { varyKeys -> varyKeys.split(",").map { it.trim() } @@ -81,11 +107,15 @@ public fun HttpMessage.vary(): List? = headers.getAll(HttpHeaders.Vary)? /** * Parse `Content-Length` header value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.contentLength) */ public fun HttpMessage.contentLength(): Long? = headers[HttpHeaders.ContentLength]?.toLong() /** * Parse `Set-Cookie` header value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.setCookie) */ public fun HttpMessage.setCookie(): List = headers.getAll(HttpHeaders.SetCookie) ?.flatMap { it.splitSetCookieHeader() } @@ -94,12 +124,16 @@ public fun HttpMessage.setCookie(): List = headers.getAll(HttpHeaders.Se /** * Parse `Set-Cookie` header value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cookies) */ public fun HttpMessageBuilder.cookies(): List = headers.getAll(HttpHeaders.SetCookie)?.map { parseServerSetCookieHeader(it) } ?: emptyList() /** * Parse `CacheControl` header. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cacheControl) */ public fun HttpMessage.cacheControl(): List = headers[HttpHeaders.CacheControl]?.let { parseHeaderValue(it) diff --git a/ktor-http/common/src/io/ktor/http/HttpMethod.kt b/ktor-http/common/src/io/ktor/http/HttpMethod.kt index 9e5cdf0b1be..048e2f34ce5 100644 --- a/ktor-http/common/src/io/ktor/http/HttpMethod.kt +++ b/ktor-http/common/src/io/ktor/http/HttpMethod.kt @@ -6,6 +6,9 @@ package io.ktor.http /** * Represents an HTTP method (verb) + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.HttpMethod) + * * @property value contains method name */ public data class HttpMethod(val value: String) { @@ -25,6 +28,8 @@ public data class HttpMethod(val value: String) { /** * Parse HTTP method by [method] string + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.HttpMethod.Companion.parse) */ public fun parse(method: String): HttpMethod { return when (method) { @@ -41,6 +46,8 @@ public data class HttpMethod(val value: String) { /** * A list of default HTTP methods + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.HttpMethod.Companion.DefaultMethods) */ public val DefaultMethods: List = listOf(Get, Post, Put, Patch, Delete, Head, Options) } diff --git a/ktor-http/common/src/io/ktor/http/HttpProtocolVersion.kt b/ktor-http/common/src/io/ktor/http/HttpProtocolVersion.kt index 97e5050e29d..6f2da629d43 100644 --- a/ktor-http/common/src/io/ktor/http/HttpProtocolVersion.kt +++ b/ktor-http/common/src/io/ktor/http/HttpProtocolVersion.kt @@ -6,6 +6,9 @@ package io.ktor.http /** * Represents an HTTP protocol version. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.HttpProtocolVersion) + * * @property name specifies name of the protocol, e.g. "HTTP". * @property major specifies protocol major version. * @property minor specifies protocol minor version. @@ -15,31 +18,43 @@ public data class HttpProtocolVersion(val name: String, val major: Int, val mino public companion object { /** * HTTP/2.0 version. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.HttpProtocolVersion.Companion.HTTP_2_0) */ public val HTTP_2_0: HttpProtocolVersion = HttpProtocolVersion("HTTP", 2, 0) /** * HTTP/1.1 version. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.HttpProtocolVersion.Companion.HTTP_1_1) */ public val HTTP_1_1: HttpProtocolVersion = HttpProtocolVersion("HTTP", 1, 1) /** * HTTP/1.0 version. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.HttpProtocolVersion.Companion.HTTP_1_0) */ public val HTTP_1_0: HttpProtocolVersion = HttpProtocolVersion("HTTP", 1, 0) /** * SPDY/3.0 version. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.HttpProtocolVersion.Companion.SPDY_3) */ public val SPDY_3: HttpProtocolVersion = HttpProtocolVersion("SPDY", 3, 0) /** * QUIC/1.0 version. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.HttpProtocolVersion.Companion.QUIC) */ public val QUIC: HttpProtocolVersion = HttpProtocolVersion("QUIC", 1, 0) /** * Creates an instance of [HttpProtocolVersion] from the given parameters. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.HttpProtocolVersion.Companion.fromValue) */ public fun fromValue(name: String, major: Int, minor: Int): HttpProtocolVersion = when { name == "HTTP" && major == 1 && minor == 0 -> HTTP_1_0 @@ -50,6 +65,8 @@ public data class HttpProtocolVersion(val name: String, val major: Int, val mino /** * Create an instance of [HttpProtocolVersion] from http string representation. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.HttpProtocolVersion.Companion.parse) */ public fun parse(value: CharSequence): HttpProtocolVersion { /** diff --git a/ktor-http/common/src/io/ktor/http/HttpStatusCode.kt b/ktor-http/common/src/io/ktor/http/HttpStatusCode.kt index 856a1d53b21..76f09112549 100644 --- a/ktor-http/common/src/io/ktor/http/HttpStatusCode.kt +++ b/ktor-http/common/src/io/ktor/http/HttpStatusCode.kt @@ -6,6 +6,9 @@ package io.ktor.http /** * Represents an HTTP status code and description. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.HttpStatusCode) + * * @param value is a numeric code. * @param description is free form description of a status. */ @@ -19,6 +22,8 @@ public data class HttpStatusCode(val value: Int, val description: String) : Comp /** * Returns a copy of `this` code with a description changed to [value]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.HttpStatusCode.description) */ public fun description(value: String): HttpStatusCode = copy(description = value) @@ -106,6 +111,8 @@ public data class HttpStatusCode(val value: Int, val description: String) : Comp /** * All known status codes + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.HttpStatusCode.Companion.allStatusCodes) */ public val allStatusCodes: List = allStatusCodes() @@ -113,6 +120,8 @@ public data class HttpStatusCode(val value: Int, val description: String) : Comp /** * Creates an instance of [HttpStatusCode] with the given numeric value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.HttpStatusCode.Companion.fromValue) */ public fun fromValue(value: Int): HttpStatusCode { return statusCodesMap[value] ?: HttpStatusCode(value, "Unknown Status Code") @@ -180,5 +189,7 @@ internal fun allStatusCodes(): List = listOf( * Checks if a given status code is a success code according to HTTP standards. * * Codes from 200 to 299 are considered to be successful. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.isSuccess) */ public fun HttpStatusCode.isSuccess(): Boolean = value in (200 until 300) diff --git a/ktor-http/common/src/io/ktor/http/HttpUrlEncoded.kt b/ktor-http/common/src/io/ktor/http/HttpUrlEncoded.kt index d650daedb91..c23a6f51b70 100644 --- a/ktor-http/common/src/io/ktor/http/HttpUrlEncoded.kt +++ b/ktor-http/common/src/io/ktor/http/HttpUrlEncoded.kt @@ -8,6 +8,8 @@ import io.ktor.utils.io.charsets.* /** * Parse URL query parameters. Shouldn't be used for urlencoded forms because of `+` character. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.parseUrlEncodedParameters) */ public fun String.parseUrlEncodedParameters(defaultEncoding: Charset = Charsets.UTF_8, limit: Int = 1000): Parameters { val parameters: List> = @@ -28,11 +30,15 @@ public fun String.parseUrlEncodedParameters(defaultEncoding: Charset = Charsets. /** * Encode form parameters from a list of pairs + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.formUrlEncode) */ public fun List>.formUrlEncode(): String = buildString { formUrlEncodeTo(this) } /** * Encode form parameters from a list of pairs to the specified [out] appendable + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.formUrlEncodeTo) */ public fun List>.formUrlEncodeTo(out: Appendable) { joinTo(out, "&") { @@ -48,6 +54,8 @@ public fun List>.formUrlEncodeTo(out: Appendable) { /** * Encode form parameters + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.formUrlEncode) */ public fun Parameters.formUrlEncode(): String = entries() .flatMap { e -> e.value.map { e.key to it } } @@ -55,6 +63,8 @@ public fun Parameters.formUrlEncode(): String = entries() /** * Encode form parameters to the specified [out] appendable + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.formUrlEncodeTo) */ public fun Parameters.formUrlEncodeTo(out: Appendable) { entries().formUrlEncodeTo(out) diff --git a/ktor-http/common/src/io/ktor/http/IpParser.kt b/ktor-http/common/src/io/ktor/http/IpParser.kt index 408aa2a04b3..694dfc1e787 100644 --- a/ktor-http/common/src/io/ktor/http/IpParser.kt +++ b/ktor-http/common/src/io/ktor/http/IpParser.kt @@ -9,6 +9,8 @@ import io.ktor.http.parsing.regex.* /** * Check if [host] is IPv4 or IPv6 address. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.hostIsIp) */ public fun hostIsIp(host: String): Boolean = IP_PARSER.match(host) diff --git a/ktor-http/common/src/io/ktor/http/LinkHeader.kt b/ktor-http/common/src/io/ktor/http/LinkHeader.kt index fd5953c6835..f00846bbbd0 100644 --- a/ktor-http/common/src/io/ktor/http/LinkHeader.kt +++ b/ktor-http/common/src/io/ktor/http/LinkHeader.kt @@ -6,6 +6,8 @@ package io.ktor.http /** * Represents a `Link` header value as per RFC 5988 + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.LinkHeader) */ public class LinkHeader( uri: String, @@ -35,12 +37,16 @@ public class LinkHeader( /** * Link URI part + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.LinkHeader.uri) */ public val uri: String get() = content.removePrefix("<").removeSuffix(">") /** * Known Link header parameters + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.LinkHeader.Parameters) */ @Suppress("unused", "KDocMissingDocumentation", "PublicApiImplicitType") public object Parameters { @@ -55,6 +61,8 @@ public class LinkHeader( /** * Known rel parameter values + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.LinkHeader.Rel) */ @Suppress("unused", "KDocMissingDocumentation", "PublicApiImplicitType") public object Rel { diff --git a/ktor-http/common/src/io/ktor/http/Parameters.kt b/ktor-http/common/src/io/ktor/http/Parameters.kt index 5107f9d1619..55e5a0f4eae 100644 --- a/ktor-http/common/src/io/ktor/http/Parameters.kt +++ b/ktor-http/common/src/io/ktor/http/Parameters.kt @@ -8,16 +8,23 @@ import io.ktor.util.* /** * Represents HTTP parameters as a map from case-insensitive names to collection of [String] values + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.Parameters) */ public interface Parameters : StringValues { public companion object { /** * Empty [Parameters] instance + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.Parameters.Companion.Empty) */ public val Empty: Parameters = EmptyParameters /** * Builds a [Parameters] instance with the given [builder] function + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.Parameters.Companion.build) + * * @param builder specifies a function to build a map */ public inline fun build(builder: ParametersBuilder.() -> Unit): Parameters = @@ -41,31 +48,44 @@ public class ParametersBuilderImpl( /** * Returns an empty [Parameters] instance + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.parametersOf) */ public fun parametersOf(): Parameters = Parameters.Empty /** * Creates a [Parameters] instance containing only single pair + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.parametersOf) */ public fun parametersOf(name: String, value: String): Parameters = ParametersSingleImpl(name, listOf(value)) /** * Creates a [Parameters] instance containing only single pair of [name] with multiple [values] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.parametersOf) */ public fun parametersOf(name: String, values: List): Parameters = ParametersSingleImpl(name, values) /** * Creates a [Parameters] instance from the entries of the given [map] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.parametersOf) */ public fun parametersOf(map: Map>): Parameters = ParametersImpl(map) /** * Creates a [Parameters] instance from the specified [pairs] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.parametersOf) */ public fun parametersOf(vararg pairs: Pair>): Parameters = ParametersImpl(pairs.asList().toMap()) /** * Builds a [Parameters] instance with the given [builder] function + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.parameters) + * * @param builder specifies a function to build a map */ public fun parameters(builder: ParametersBuilder.() -> Unit): Parameters = Parameters.build(builder) @@ -83,6 +103,8 @@ public class ParametersSingleImpl(name: String, values: List) : Paramete /** * Plus operator function that creates a new parameters instance from the original one concatenating with [other] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.plus) */ public operator fun Parameters.plus(other: Parameters): Parameters = when { caseInsensitiveName == other.caseInsensitiveName -> when { diff --git a/ktor-http/common/src/io/ktor/http/Query.kt b/ktor-http/common/src/io/ktor/http/Query.kt index 556506abe59..3c2b97d1869 100644 --- a/ktor-http/common/src/io/ktor/http/Query.kt +++ b/ktor-http/common/src/io/ktor/http/Query.kt @@ -6,6 +6,8 @@ package io.ktor.http /** * Parse query string withing starting at the specified [startIndex] but up to [limit] pairs + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.parseQueryString) */ public fun parseQueryString(query: String, startIndex: Int = 0, limit: Int = 1000, decode: Boolean = true): Parameters { return if (startIndex > query.lastIndex) { diff --git a/ktor-http/common/src/io/ktor/http/Ranges.kt b/ktor-http/common/src/io/ktor/http/Ranges.kt index 832f4cac87d..61945d97e04 100644 --- a/ktor-http/common/src/io/ktor/http/Ranges.kt +++ b/ktor-http/common/src/io/ktor/http/Ranges.kt @@ -9,26 +9,38 @@ import kotlin.math.* /** * Possible content range units: bytes and none + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.RangeUnits) + * * @property unitToken Lower-case unit name */ public enum class RangeUnits(public val unitToken: String) { /** * Range unit `bytes` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.RangeUnits.Bytes) */ Bytes("bytes"), /** * Range unit `none` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.RangeUnits.None) */ None("none") } /** * Represents a `Range` header's particular range + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.ContentRange) */ public sealed class ContentRange { /** * Represents a `Content-Range` bounded from both sides + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.ContentRange.Bounded) + * * @property from index from which the content should begin * @property to the last index the content should end at (inclusive) */ @@ -38,6 +50,9 @@ public sealed class ContentRange { /** * Represents a `Content-Range` bounded at the beginning (skip first bytes, show tail) + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.ContentRange.TailFrom) + * * @property from index from which the content should begin */ public data class TailFrom(val from: Long) : ContentRange() { @@ -46,6 +61,9 @@ public sealed class ContentRange { /** * Represents a `Content-Range` bounded by tail size + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.ContentRange.Suffix) + * * @property lastCount number of tail bytes */ public data class Suffix(val lastCount: Long) : ContentRange() { @@ -55,6 +73,8 @@ public sealed class ContentRange { /** * Parse `Range` header value + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.parseRangesSpecifier) */ public fun parseRangesSpecifier(rangeSpec: String): RangesSpecifier? { try { diff --git a/ktor-http/common/src/io/ktor/http/RangesSpecifier.kt b/ktor-http/common/src/io/ktor/http/RangesSpecifier.kt index f4b04230586..4183d76b2e2 100644 --- a/ktor-http/common/src/io/ktor/http/RangesSpecifier.kt +++ b/ktor-http/common/src/io/ktor/http/RangesSpecifier.kt @@ -6,6 +6,9 @@ package io.ktor.http /** * Range specifier for partial content requests (RFC 2616 sec 14.35.1) + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.RangesSpecifier) + * * @property unit range units, usually bytes * @property ranges a list of requested ranges (could be open or closed ranges) */ @@ -19,6 +22,8 @@ public data class RangesSpecifier(val unit: String = RangeUnits.Bytes.unitToken, /** * Verify ranges + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.RangesSpecifier.isValid) */ public fun isValid(rangeUnitPredicate: (String) -> Boolean = { it == RangeUnits.Bytes.unitToken }): Boolean = rangeUnitPredicate(unit) && @@ -32,6 +37,9 @@ public data class RangesSpecifier(val unit: String = RangeUnits.Bytes.unitToken, /** * Resolve and merge all overlapping and neighbours ranges + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.RangesSpecifier.merge) + * * @param length content length * @return a list of absolute long ranges */ @@ -46,11 +54,16 @@ public data class RangesSpecifier(val unit: String = RangeUnits.Bytes.unitToken, /** * Merges all overlapping and neighbours ranges. Currently gaps collapse is not supported but should be, one day. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.RangesSpecifier.merge) */ public fun merge(length: Long): List = ranges.toLongRanges(length).mergeRangesKeepOrder() /** * Merge all ranges into a single absolute long range + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.RangesSpecifier.mergeToSingle) + * * @param length content length */ public fun mergeToSingle(length: Long): LongRange? { diff --git a/ktor-http/common/src/io/ktor/http/RequestConnectionPoint.kt b/ktor-http/common/src/io/ktor/http/RequestConnectionPoint.kt index 1ffe546884c..ef76c065bba 100644 --- a/ktor-http/common/src/io/ktor/http/RequestConnectionPoint.kt +++ b/ktor-http/common/src/io/ktor/http/RequestConnectionPoint.kt @@ -8,20 +8,28 @@ package io.ktor.http * Represents request address information is used to make a call. * There are at least two possible instances: "local" is how we see request at the server application and * "actual" is what we can recover from proxy provided headers. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.RequestConnectionPoint) */ public interface RequestConnectionPoint { /** * Scheme, for example "http" or "https" + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.RequestConnectionPoint.scheme) */ public val scheme: String /** * Protocol version string + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.RequestConnectionPoint.version) */ public val version: String /** * Port, for example 80 or 443 + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.RequestConnectionPoint.port) */ @Deprecated( "Use localPort or serverPort instead", @@ -31,16 +39,22 @@ public interface RequestConnectionPoint { /** * Port on which the request was received, for example 80 or 443 + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.RequestConnectionPoint.localPort) */ public val localPort: Int /** * Port to which the request was sent, for example, 80 or 443 + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.RequestConnectionPoint.serverPort) */ public val serverPort: Int /** * Request host, useful for virtual hosts routing + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.RequestConnectionPoint.host) */ @Deprecated( "Use localHost or serverHost instead", @@ -50,26 +64,36 @@ public interface RequestConnectionPoint { /** * Host on which the request was received, is useful for virtual hosts routing + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.RequestConnectionPoint.localHost) */ public val localHost: String /** * Host to which the request was sent, is useful for virtual hosts routing + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.RequestConnectionPoint.serverHost) */ public val serverHost: String /** * IP address on which the request was received. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.RequestConnectionPoint.localAddress) */ public val localAddress: String /** * URI path with no host, port and no schema specification, but possibly with query + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.RequestConnectionPoint.uri) */ public val uri: String /** * Request HTTP method + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.RequestConnectionPoint.method) */ public val method: HttpMethod @@ -82,6 +106,8 @@ public interface RequestConnectionPoint { * If you are going to use it to create a back-connection, please do it with care as an offender can easily * use it to force you to connect to some host that is not intended to be connected to so that may cause * serious consequences. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.RequestConnectionPoint.remoteHost) */ public val remoteHost: String @@ -94,6 +120,8 @@ public interface RequestConnectionPoint { * If you are going to use it to create a back-connection, please do it with care as an offender can easily * use it to force you to connect to some host that is not intended to be connected to so that may cause * serious consequences. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.RequestConnectionPoint.remotePort) */ public val remotePort: Int @@ -106,6 +134,8 @@ public interface RequestConnectionPoint { * If you are going to use it to create a back-connection, please do it with care as an offender can easily * use it to force you to connect to some host that is not intended to be connected to so that may cause * serious consequences. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.RequestConnectionPoint.remoteAddress) */ public val remoteAddress: String } diff --git a/ktor-http/common/src/io/ktor/http/URLBuilder.kt b/ktor-http/common/src/io/ktor/http/URLBuilder.kt index e86ee95bbfb..c4aed2b8890 100644 --- a/ktor-http/common/src/io/ktor/http/URLBuilder.kt +++ b/ktor-http/common/src/io/ktor/http/URLBuilder.kt @@ -6,12 +6,17 @@ package io.ktor.http /** * Select default port value from protocol. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.DEFAULT_PORT) */ public const val DEFAULT_PORT: Int = 0 /** * A URL builder with all mutable components * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.URLBuilder) + * * @property protocol URL protocol (scheme) * @property host name without port (domain) * @property port port number @@ -89,6 +94,8 @@ public class URLBuilder( /** * Build a URL string + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.URLBuilder.buildString) */ public fun buildString(): String { applyOrigin() @@ -101,6 +108,8 @@ public class URLBuilder( /** * Build a [Url] instance (everything is copied to a new instance) + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.URLBuilder.build) */ public fun build(): Url { applyOrigin() @@ -204,11 +213,15 @@ private fun Appendable.appendTel(host: String) { * Hostname of current origin. * * It uses "http://localhost" for all platforms except js. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.origin) */ public expect val URLBuilder.Companion.origin: String /** * Create a copy of this builder. Modifications in a copy is not reflected in the original instance and vise-versa. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.clone) */ public fun URLBuilder.clone(): URLBuilder = URLBuilder().takeFrom(this) @@ -220,6 +233,9 @@ internal val URLBuilder.encodedUserAndPassword: String /** * Adds [segments] to current [encodedPath]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.appendPathSegments) + * * @param segments path items to append * @param encodeSlash `true` to encode the '/' character to allow it to be a part of a path segment; * `false` to use '/' as a separator between path segments. @@ -235,6 +251,9 @@ public fun URLBuilder.appendPathSegments(segments: List, encodeSlash: Bo /** * Adds [components] to current [encodedPath] * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.appendPathSegments) + * * @param components path items to append * @param encodeSlash `true` to encode the '/' character to allow it to be a part of a path segment; * `false` to use '/' as a separator between path segments. @@ -245,6 +264,9 @@ public fun URLBuilder.appendPathSegments(vararg components: String, encodeSlash: /** * Replace [components] in the current [encodedPath]. The [path] components will be escaped, except `/` character. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.path) + * * @param path path items to set */ public fun URLBuilder.path(vararg path: String) { @@ -253,6 +275,8 @@ public fun URLBuilder.path(vararg path: String) { /** * Adds [segments] to current [encodedPath] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.appendEncodedPathSegments) */ public fun URLBuilder.appendEncodedPathSegments(segments: List): URLBuilder { val endsWithSlash = @@ -270,12 +294,16 @@ public fun URLBuilder.appendEncodedPathSegments(segments: List): URLBuil /** * Adds [components] to current [encodedPath] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.appendEncodedPathSegments) */ public fun URLBuilder.appendEncodedPathSegments(vararg components: String): URLBuilder = appendEncodedPathSegments(components.toList()) /** * [URLBuilder] authority. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.authority) */ public val URLBuilder.authority: String get() = buildString { @@ -311,6 +339,8 @@ private fun List.joinPath(): String { /** * Sets the url parts using the specified [scheme], [host], [port] and [path]. * Pass `null` to keep existing value in the [URLBuilder]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.set) */ public fun URLBuilder.set( scheme: String? = null, diff --git a/ktor-http/common/src/io/ktor/http/URLParser.kt b/ktor-http/common/src/io/ktor/http/URLParser.kt index 3b03cadaffb..66ba9e451d9 100644 --- a/ktor-http/common/src/io/ktor/http/URLParser.kt +++ b/ktor-http/common/src/io/ktor/http/URLParser.kt @@ -11,6 +11,8 @@ internal val ROOT_PATH = listOf("") /** * Take url parts from [urlString] * throws [URLParserException] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.takeFrom) */ public fun URLBuilder.takeFrom(urlString: String): URLBuilder { if (urlString.isBlank()) return this @@ -24,6 +26,8 @@ public fun URLBuilder.takeFrom(urlString: String): URLBuilder { /** * Thrown when failed to parse URL + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.URLParserException) */ public class URLParserException(urlString: String, cause: Throwable) : IllegalStateException( "Fail to parse url: $urlString", diff --git a/ktor-http/common/src/io/ktor/http/URLProtocol.kt b/ktor-http/common/src/io/ktor/http/URLProtocol.kt index b6f9fc9e141..3882fa6b185 100644 --- a/ktor-http/common/src/io/ktor/http/URLProtocol.kt +++ b/ktor-http/common/src/io/ktor/http/URLProtocol.kt @@ -9,6 +9,9 @@ import io.ktor.utils.io.* /** * Represents URL protocol + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.URLProtocol) + * * @property name of protocol (schema) * @property defaultPort default port for protocol or `-1` if not known */ @@ -22,36 +25,50 @@ public data class URLProtocol(val name: String, val defaultPort: Int) : JvmSeria public companion object { /** * HTTP with port 80 + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.URLProtocol.Companion.HTTP) */ public val HTTP: URLProtocol = URLProtocol("http", 80) /** * secure HTTPS with port 443 + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.URLProtocol.Companion.HTTPS) */ public val HTTPS: URLProtocol = URLProtocol("https", 443) /** * Web socket over HTTP on port 80 + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.URLProtocol.Companion.WS) */ public val WS: URLProtocol = URLProtocol("ws", 80) /** * Web socket over secure HTTPS on port 443 + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.URLProtocol.Companion.WSS) */ public val WSS: URLProtocol = URLProtocol("wss", 443) /** * Socks proxy url protocol. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.URLProtocol.Companion.SOCKS) */ public val SOCKS: URLProtocol = URLProtocol("socks", 1080) /** * Protocols by names map + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.URLProtocol.Companion.byName) */ public val byName: Map = listOf(HTTP, HTTPS, WS, WSS, SOCKS).associateBy { it.name } /** * Create an instance by [name] or use already existing instance + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.URLProtocol.Companion.createOrDefault) */ public fun createOrDefault(name: String): URLProtocol = name.toLowerCasePreservingASCIIRules().let { byName[it] ?: URLProtocol(it, DEFAULT_PORT) @@ -61,10 +78,14 @@ public data class URLProtocol(val name: String, val defaultPort: Int) : JvmSeria /** * Check if the protocol is websocket + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.isWebsocket) */ public fun URLProtocol.isWebsocket(): Boolean = name == "ws" || name == "wss" /** * Check if the protocol is secure + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.isSecure) */ public fun URLProtocol.isSecure(): Boolean = name == "https" || name == "wss" diff --git a/ktor-http/common/src/io/ktor/http/URLUtils.kt b/ktor-http/common/src/io/ktor/http/URLUtils.kt index c8e5aac4bcc..6a25abd2b44 100644 --- a/ktor-http/common/src/io/ktor/http/URLUtils.kt +++ b/ktor-http/common/src/io/ktor/http/URLUtils.kt @@ -8,24 +8,33 @@ import io.ktor.util.* /** * Construct [Url] from [urlString]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.Url) */ @Suppress("FunctionName") public fun Url(urlString: String): Url = URLBuilder(urlString).build() /** * Construct [Url] from [builder] without building origin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.Url) */ @Suppress("FunctionName") public fun Url(builder: URLBuilder): Url = URLBuilder().takeFrom(builder).build() /** * Construct a [Url] by applying [block] an empty [UrlBuilder]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.buildUrl) */ public fun buildUrl(block: URLBuilder.() -> Unit): Url = URLBuilder().apply(block).build() /** * Parses the given URL string and returns a [Url] object if valid, otherwise, it returns `null`. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.parseUrl) + * * @param urlString The URL string to be parsed. * @return A [Url] object if the URL is valid or `null` otherwise. */ @@ -39,24 +48,32 @@ public fun parseUrl(urlString: String): Url? { /** * Construct [URLBuilder] from [urlString]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.URLBuilder) */ @Suppress("FunctionName") public fun URLBuilder(urlString: String): URLBuilder = URLBuilder().takeFrom(urlString) /** * Construct [URLBuilder] from [url]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.URLBuilder) */ @Suppress("FunctionName") public fun URLBuilder(url: Url): URLBuilder = URLBuilder().takeFrom(url) /** * Construct [URLBuilder] from [builder]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.URLBuilder) */ @Suppress("FunctionName") public fun URLBuilder(builder: URLBuilder): URLBuilder = URLBuilder().takeFrom(builder) /** * Take components from another [url] builder + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.takeFrom) */ public fun URLBuilder.takeFrom(url: URLBuilder): URLBuilder { protocolOrNull = url.protocolOrNull @@ -74,6 +91,8 @@ public fun URLBuilder.takeFrom(url: URLBuilder): URLBuilder { /** * Take components from another [url] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.takeFrom) */ public fun URLBuilder.takeFrom(url: Url): URLBuilder { protocolOrNull = url.protocolOrNull @@ -91,17 +110,23 @@ public fun URLBuilder.takeFrom(url: Url): URLBuilder { /** * Full encoded path with query string but without domain, port and schema + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.fullPath) */ public val Url.fullPath: String get() = buildString { appendUrlFullPath(encodedPath, encodedQuery, trailingQuery) } /** * Host:port pair, not normalized so port is always specified even if the port is schema's default + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.hostWithPort) */ public val Url.hostWithPort: String get() = "$host:$port" /** * Returns "host:port" when port is specified. Else, returns host. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.hostWithPortIfSpecified) */ public val Url.hostWithPortIfSpecified: String get() = when (specifiedPort) { @@ -159,21 +184,29 @@ public fun Appendable.appendUrlFullPath( /** * Checks if [Url] has absolute path. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.isAbsolutePath) */ public val Url.isAbsolutePath: Boolean get() = rawSegments.firstOrNull() == "" /** * Checks if [Url] has absolute path. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.isRelativePath) */ public val Url.isRelativePath: Boolean get() = !isAbsolutePath /** * Checks if [Url] has absolute path. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.isAbsolutePath) */ public val URLBuilder.isAbsolutePath: Boolean get() = pathSegments.firstOrNull() == "" /** * Checks if [Url] has absolute path. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.isRelativePath) */ public val URLBuilder.isRelativePath: Boolean get() = !isAbsolutePath diff --git a/ktor-http/common/src/io/ktor/http/Url.kt b/ktor-http/common/src/io/ktor/http/Url.kt index 8f492789b28..1748bf3b092 100644 --- a/ktor-http/common/src/io/ktor/http/Url.kt +++ b/ktor-http/common/src/io/ktor/http/Url.kt @@ -14,6 +14,9 @@ import kotlinx.serialization.encoding.* /** * Represents an immutable URL * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.Url) + * * @property protocol * @property host name without port (domain) * @property port the specified port or protocol default port @@ -77,6 +80,8 @@ public class Url internal constructor( * ``` * * To address this issue, the current [pathSegments] property will be renamed to [rawSegments]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.Url.pathSegments) */ @Deprecated( """ @@ -124,6 +129,8 @@ public class Url internal constructor( * val relative = Url("docs") * relative.segments == listOf("docs") * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.Url.rawSegments) */ public val rawSegments: List = pathSegments @@ -142,6 +149,8 @@ public class Url internal constructor( * ``` * * If you need to check for trailing slash and relative/absolute paths, please check the [rawSegments] property. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.Url.segments) **/ public val segments: List by lazy { if (pathSegments.isEmpty()) return@lazy emptyList() @@ -237,6 +246,8 @@ public class Url internal constructor( /** * [Url] authority. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.authority) */ public val Url.authority: String get() = buildString { @@ -246,6 +257,8 @@ public val Url.authority: String /** * A [Url] protocol and authority. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.protocolWithAuthority) */ public val Url.protocolWithAuthority: String get() = buildString { diff --git a/ktor-http/common/src/io/ktor/http/auth/AuthScheme.kt b/ktor-http/common/src/io/ktor/http/auth/AuthScheme.kt index 475c206d04c..ee6b8bdc9ef 100644 --- a/ktor-http/common/src/io/ktor/http/auth/AuthScheme.kt +++ b/ktor-http/common/src/io/ktor/http/auth/AuthScheme.kt @@ -6,6 +6,8 @@ package io.ktor.http.auth /** * Contains the standard auth schemes. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.auth.AuthScheme) */ public object AuthScheme { /** @@ -16,6 +18,8 @@ public object AuthScheme { * ``` * * see https://tools.ietf.org/html/rfc7617) + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.auth.AuthScheme.Basic) */ public const val Basic: String = "Basic" @@ -29,6 +33,8 @@ public object AuthScheme { * ``` * * see https://tools.ietf.org/html/rfc2069 + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.auth.AuthScheme.Digest) */ public const val Digest: String = "Digest" @@ -36,6 +42,8 @@ public object AuthScheme { * Described in the RFC-4599: * * see https://www.ietf.org/rfc/rfc4559.txt + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.auth.AuthScheme.Negotiate) */ public const val Negotiate: String = "Negotiate" @@ -43,6 +51,8 @@ public object AuthScheme { * OAuth Authentication described in the RFC-6749: * * see https://tools.ietf.org/html/rfc6749 + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.auth.AuthScheme.OAuth) */ public const val OAuth: String = "OAuth" @@ -51,6 +61,8 @@ public object AuthScheme { * * see https://tools.ietf.org/html/rfc6749 * & https://tools.ietf.org/html/rfc6750 + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.auth.AuthScheme.Bearer) */ public const val Bearer: String = "Bearer" } diff --git a/ktor-http/common/src/io/ktor/http/auth/HeaderValueEncoding.kt b/ktor-http/common/src/io/ktor/http/auth/HeaderValueEncoding.kt index bcda149ec19..87c3e64c0a7 100644 --- a/ktor-http/common/src/io/ktor/http/auth/HeaderValueEncoding.kt +++ b/ktor-http/common/src/io/ktor/http/auth/HeaderValueEncoding.kt @@ -6,15 +6,21 @@ package io.ktor.http.auth /** * Describes how a header should be encoded. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.auth.HeaderValueEncoding) */ public enum class HeaderValueEncoding { /** * The header will be quoted only when required. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.auth.HeaderValueEncoding.QUOTED_WHEN_REQUIRED) */ QUOTED_WHEN_REQUIRED, /** * The header will be quoted always. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.auth.HeaderValueEncoding.QUOTED_ALWAYS) */ QUOTED_ALWAYS, @@ -22,6 +28,8 @@ public enum class HeaderValueEncoding { * The header will be URI-encoded as described in the RFC-3986: * * see https://tools.ietf.org/html/rfc3986#page-12 + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.auth.HeaderValueEncoding.URI_ENCODE) */ URI_ENCODE } diff --git a/ktor-http/common/src/io/ktor/http/auth/HttpAuthHeader.kt b/ktor-http/common/src/io/ktor/http/auth/HttpAuthHeader.kt index b0ad55ff8be..7689404a817 100644 --- a/ktor-http/common/src/io/ktor/http/auth/HttpAuthHeader.kt +++ b/ktor-http/common/src/io/ktor/http/auth/HttpAuthHeader.kt @@ -17,6 +17,9 @@ private val escapeRegex: Regex = "\\\\.".toRegex() /** * Parses an authorization header [headerValue] into a [HttpAuthHeader]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.auth.parseAuthorizationHeader) + * * @return [HttpAuthHeader] or `null` if argument string is blank. * @throws [ParseException] on invalid header * @@ -62,6 +65,9 @@ public fun parseAuthorizationHeader(headerValue: String): HttpAuthHeader? { /** * Parses an authorization header [headerValue] into a list of [HttpAuthHeader]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.auth.parseAuthorizationHeaders) + * * @return a list of [HttpAuthHeader] * @throws [ParseException] on invalid header */ @@ -225,6 +231,9 @@ private fun matchToken68(headerValue: String, startIndex: Int): Int { * * This can be of type [HttpAuthHeader.Single] or [HttpAuthHeader.Parameterized]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.auth.HttpAuthHeader) + * * @property authScheme auth scheme, usually one of [AuthScheme] */ public sealed class HttpAuthHeader(public val authScheme: String) { @@ -236,6 +245,9 @@ public sealed class HttpAuthHeader(public val authScheme: String) { /** * Describes an authentication header that is represented by a single [blob]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.auth.HttpAuthHeader.Single) + * * @property blob contains single token 68, should consist from digits, letters and one of the following: `-._~+/` */ public class Single(authScheme: String, public val blob: String) : HttpAuthHeader(authScheme) { @@ -261,6 +273,9 @@ public sealed class HttpAuthHeader(public val authScheme: String) { /** * Describes a parameterized authentication header that is represented by a set of [parameters] encoded with [encoding]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.auth.HttpAuthHeader.Parameterized) + * * @property parameters a list of auth parameters * @property encoding parameters encoding method, one of [HeaderValueEncoding] */ @@ -285,6 +300,8 @@ public sealed class HttpAuthHeader(public val authScheme: String) { /** * Copies this [Parameterized] appending a new parameter [name] [value]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.auth.HttpAuthHeader.Parameterized.withParameter) */ public fun withParameter(name: String, value: String): Parameterized = Parameterized(authScheme, this.parameters + HeaderValueParam(name, value), encoding) @@ -294,6 +311,8 @@ public sealed class HttpAuthHeader(public val authScheme: String) { * or appending if no such parameters found. * If there were several pairs they will be reduced into a single pair * at position of first occurrence discarding following pairs with this [name]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.auth.HttpAuthHeader.Parameterized.withReplacedParameter) */ public fun withReplacedParameter(name: String, value: String): Parameterized { val firstIndex = parameters.indexOfFirst { it.name == name } @@ -322,6 +341,8 @@ public sealed class HttpAuthHeader(public val authScheme: String) { /** * Tries to extract the first value of a parameter [name]. Returns null when not found. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.auth.HttpAuthHeader.Parameterized.parameter) */ public fun parameter(name: String): String? = parameters.firstOrNull { it.name == name }?.value @@ -346,16 +367,22 @@ public sealed class HttpAuthHeader(public val authScheme: String) { /** * Encodes the header with a specified [encoding]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.auth.HttpAuthHeader.render) */ public abstract fun render(encoding: HeaderValueEncoding): String /** * Encodes the header with the default [HeaderValueEncoding] for this header. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.auth.HttpAuthHeader.render) */ public abstract fun render(): String /** * Encodes the header with the default [HeaderValueEncoding] for this header. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.auth.HttpAuthHeader.toString) */ override fun toString(): String { return render() @@ -364,6 +391,8 @@ public sealed class HttpAuthHeader(public val authScheme: String) { public companion object { /** * Generates an [AuthScheme.Basic] challenge as a [HttpAuthHeader]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.auth.HttpAuthHeader.Companion.basicAuthChallenge) */ public fun basicAuthChallenge(realm: String, charset: Charset?): Parameterized = Parameterized( AuthScheme.Basic, @@ -377,6 +406,8 @@ public sealed class HttpAuthHeader(public val authScheme: String) { /** * Generates an [AuthScheme.Bearer] challenge as a [HttpAuthHeader]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.auth.HttpAuthHeader.Companion.bearerAuthChallenge) */ public fun bearerAuthChallenge(scheme: String, realm: String? = null): HttpAuthHeader = Parameterized( authScheme = scheme, @@ -385,6 +416,8 @@ public sealed class HttpAuthHeader(public val authScheme: String) { /** * Generates an [AuthScheme.Digest] challenge as a [HttpAuthHeader]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.auth.HttpAuthHeader.Companion.digestAuthChallenge) */ public fun digestAuthChallenge( realm: String, @@ -415,6 +448,8 @@ public sealed class HttpAuthHeader(public val authScheme: String) { /** * Standard parameters for [Parameterized] [HttpAuthHeader]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.auth.HttpAuthHeader.Parameters) */ @Suppress("KDocMissingDocumentation", "PublicApiImplicitType") public object Parameters { diff --git a/ktor-http/common/src/io/ktor/http/content/ByteArrayContent.kt b/ktor-http/common/src/io/ktor/http/content/ByteArrayContent.kt index 1710ea1e6e6..c769458bb96 100644 --- a/ktor-http/common/src/io/ktor/http/content/ByteArrayContent.kt +++ b/ktor-http/common/src/io/ktor/http/content/ByteArrayContent.kt @@ -8,6 +8,8 @@ import io.ktor.http.* /** * Implementation of the [OutgoingContent.ByteArrayContent] for sending array of bytes + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.ByteArrayContent) */ public class ByteArrayContent( private val bytes: ByteArray, diff --git a/ktor-http/common/src/io/ktor/http/content/CachingOptions.kt b/ktor-http/common/src/io/ktor/http/content/CachingOptions.kt index 54499d228c7..5642b4adfe6 100644 --- a/ktor-http/common/src/io/ktor/http/content/CachingOptions.kt +++ b/ktor-http/common/src/io/ktor/http/content/CachingOptions.kt @@ -10,6 +10,9 @@ import io.ktor.util.date.* /** * Specifies caching properties for [OutgoingContent] such as `Cache-Control` or `Expires`. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.CachingOptions) + * * @property cacheControl header * @property expires header */ @@ -17,11 +20,15 @@ public data class CachingOptions(val cacheControl: CacheControl? = null, val exp /** * Specifies a key for the [CacheControl] extension property for [OutgoingContent]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.CachingProperty) */ public val CachingProperty: AttributeKey = AttributeKey("Caching") /** * Gets or sets the [CacheControl] instance as an extension property on this content. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.caching) */ public var OutgoingContent.caching: CachingOptions? get() = getProperty(CachingProperty) diff --git a/ktor-http/common/src/io/ktor/http/content/ChannelWriterContent.kt b/ktor-http/common/src/io/ktor/http/content/ChannelWriterContent.kt index 7f4bf9e8e8d..1063d81cd61 100644 --- a/ktor-http/common/src/io/ktor/http/content/ChannelWriterContent.kt +++ b/ktor-http/common/src/io/ktor/http/content/ChannelWriterContent.kt @@ -10,6 +10,8 @@ import io.ktor.utils.io.* /** * [OutgoingContent] to respond with [ByteWriteChannel]. * The stream would be automatically closed after [body] finish. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.ChannelWriterContent) */ public class ChannelWriterContent( private val body: suspend ByteWriteChannel.() -> Unit, diff --git a/ktor-http/common/src/io/ktor/http/content/CompressedContent.kt b/ktor-http/common/src/io/ktor/http/content/CompressedContent.kt index f73d6c79440..35bfa6dab65 100644 --- a/ktor-http/common/src/io/ktor/http/content/CompressedContent.kt +++ b/ktor-http/common/src/io/ktor/http/content/CompressedContent.kt @@ -13,6 +13,8 @@ import kotlin.coroutines.* /** * Returns [OutgoingContent] compressed with [contentEncoder] if possible. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.compressed) */ public fun OutgoingContent.compressed( contentEncoder: ContentEncoder, diff --git a/ktor-http/common/src/io/ktor/http/content/Multipart.kt b/ktor-http/common/src/io/ktor/http/content/Multipart.kt index ae6bbc8a899..252f9077fd4 100644 --- a/ktor-http/common/src/io/ktor/http/content/Multipart.kt +++ b/ktor-http/common/src/io/ktor/http/content/Multipart.kt @@ -12,12 +12,18 @@ import kotlinx.coroutines.flow.* /** * Represents a multipart/form-data entry. Could be a [FormItem] or [FileItem]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.PartData) + * * @property dispose to be invoked when this part is no longed needed * @property headers of this part, could be inaccurate on some engines */ public sealed class PartData(public val dispose: () -> Unit, public val headers: Headers) { /** * Represents a multipart form item. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.PartData.FormItem) + * * @property value of this field */ public class FormItem(public val value: String, dispose: () -> Unit, partHeaders: Headers) : @@ -25,6 +31,9 @@ public sealed class PartData(public val dispose: () -> Unit, public val headers: /** * Represents a file item. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.PartData.FileItem) + * * @property provider of content bytes */ @@ -35,12 +44,17 @@ public sealed class PartData(public val dispose: () -> Unit, public val headers: ) : PartData(dispose, partHeaders) { /** * Original file name if present + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.PartData.FileItem.originalFileName) */ public val originalFileName: String? = contentDisposition?.parameter(ContentDisposition.Parameters.FileName) } /** * Represents a binary item. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.PartData.BinaryItem) + * * @property provider of content bytes */ @@ -52,6 +66,9 @@ public sealed class PartData(public val dispose: () -> Unit, public val headers: /** * Represents a binary part with a provider that supplies [ByteReadChannel]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.PartData.BinaryChannelItem) + * * @property provider supplies a channel to read data from */ public class BinaryChannelItem( @@ -61,6 +78,8 @@ public sealed class PartData(public val dispose: () -> Unit, public val headers: /** * Parsed `Content-Disposition` header or `null` if missing. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.PartData.contentDisposition) */ public val contentDisposition: ContentDisposition? by lazy(LazyThreadSafetyMode.NONE) { headers[HttpHeaders.ContentDisposition]?.let { ContentDisposition.parse(it) } @@ -68,6 +87,8 @@ public sealed class PartData(public val dispose: () -> Unit, public val headers: /** * Parsed `Content-Type` header or `null` if missing. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.PartData.contentType) */ public val contentType: ContentType? by lazy(LazyThreadSafetyMode.NONE) { headers[HttpHeaders.ContentType]?.let { @@ -79,21 +100,29 @@ public sealed class PartData(public val dispose: () -> Unit, public val headers: /** * Optional part name based on `Content-Disposition` header. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.PartData.name) */ public val name: String? get() = contentDisposition?.name } /** * Represents a multipart data stream that could be received from a call. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.MultiPartData) */ public interface MultiPartData { /** * Reads next part data or `null` if the end of multipart stream encountered. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.MultiPartData.readPart) */ public suspend fun readPart(): PartData? /** * An empty multipart data stream. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.MultiPartData.Empty) */ public object Empty : MultiPartData { override suspend fun readPart(): PartData? { @@ -105,6 +134,9 @@ public interface MultiPartData { /** * Transforms the multipart data stream into a [Flow] of [PartData]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.asFlow) + * * @return a [Flow] emitting each part of the multipart data until the end of the stream. */ public fun MultiPartData.asFlow(): Flow = flow { @@ -116,6 +148,9 @@ public fun MultiPartData.asFlow(): Flow = flow { /** * Parse multipart data stream and invoke [partHandler] for each [PartData] encountered. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.forEachPart) + * * @param partHandler to be invoked for every part item */ public suspend fun MultiPartData.forEachPart(partHandler: suspend (PartData) -> Unit): Unit = @@ -123,6 +158,9 @@ public suspend fun MultiPartData.forEachPart(partHandler: suspend (PartData) -> /** * Parse multipart data stream and put all parts into a list. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.readAllParts) + * * @return a list of [PartData] */ @Deprecated("This method can deadlock on large requests. Use `forEachPart` instead.", level = DeprecationLevel.ERROR) diff --git a/ktor-http/common/src/io/ktor/http/content/OutgoingContent.kt b/ktor-http/common/src/io/ktor/http/content/OutgoingContent.kt index 79fd41fb34c..4e15037bc57 100644 --- a/ktor-http/common/src/io/ktor/http/content/OutgoingContent.kt +++ b/ktor-http/common/src/io/ktor/http/content/OutgoingContent.kt @@ -12,15 +12,21 @@ import kotlin.coroutines.* /** * A subject of pipeline when body of HTTP message is `null` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.NullBody) */ public object NullBody /** * Information about the content to be sent to the peer, recognized by a client or server engine + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.OutgoingContent) */ public sealed class OutgoingContent { /** * Specifies [ContentType] for this resource. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.OutgoingContent.contentType) */ public open val contentType: ContentType? get() = null @@ -28,17 +34,23 @@ public sealed class OutgoingContent { * Specifies content length in bytes for this resource. * * If null, the resources will be sent as `Transfer-Encoding: chunked` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.OutgoingContent.contentLength) */ public open val contentLength: Long? get() = null /** * Status code to set when sending this content + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.OutgoingContent.status) */ public open val status: HttpStatusCode? get() = null /** * Headers to set when sending this content + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.OutgoingContent.headers) */ public open val headers: Headers get() = Headers.Empty @@ -47,11 +59,15 @@ public sealed class OutgoingContent { /** * Gets an extension property for this content + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.OutgoingContent.getProperty) */ public open fun getProperty(key: AttributeKey): T? = extensionProperties?.getOrNull(key) /** * Sets an extension property for this content + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.OutgoingContent.setProperty) */ public open fun setProperty(key: AttributeKey, value: T?) { when { @@ -63,26 +79,36 @@ public sealed class OutgoingContent { /** * Trailers to set when sending this content, will be ignored if request is not in HTTP2 mode + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.OutgoingContent.trailers) */ public open fun trailers(): Headers? = null /** * Variant of a [OutgoingContent] without a payload + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.OutgoingContent.NoContent) */ public abstract class NoContent : OutgoingContent() /** * Variant of a [OutgoingContent] with payload read from [ByteReadChannel] * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.OutgoingContent.ReadChannelContent) */ public abstract class ReadChannelContent : OutgoingContent() { /** * Provides [ByteReadChannel] for the content + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.OutgoingContent.ReadChannelContent.readFrom) */ public abstract fun readFrom(): ByteReadChannel /** * Provides [ByteReadChannel] for the given range of the content + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.OutgoingContent.ReadChannelContent.readFrom) */ @OptIn(DelicateCoroutinesApi::class) public open fun readFrom(range: LongRange): ByteReadChannel = if (range.isEmpty()) { @@ -99,26 +125,36 @@ public sealed class OutgoingContent { /** * Variant of a [OutgoingContent] with payload written to [ByteWriteChannel] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.OutgoingContent.WriteChannelContent) */ public abstract class WriteChannelContent : OutgoingContent() { /** * Receives [channel] provided by the engine and writes all data to it + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.OutgoingContent.WriteChannelContent.writeTo) */ public abstract suspend fun writeTo(channel: ByteWriteChannel) } /** * Variant of a [OutgoingContent] with payload represented as [ByteArray] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.OutgoingContent.ByteArrayContent) */ public abstract class ByteArrayContent : OutgoingContent() { /** * Provides [ByteArray] which engine will send to peer + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.OutgoingContent.ByteArrayContent.bytes) */ public abstract fun bytes(): ByteArray } /** * Variant of a [OutgoingContent] for upgrading an HTTP connection + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.OutgoingContent.ProtocolUpgrade) */ public abstract class ProtocolUpgrade : OutgoingContent() { final override val status: HttpStatusCode @@ -126,6 +162,9 @@ public sealed class OutgoingContent { /** * Upgrades an HTTP connection + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.OutgoingContent.ProtocolUpgrade.upgrade) + * * @param input is a [ByteReadChannel] for an upgraded connection * @param output is a [ByteWriteChannel] for an upgraded connection * @param engineContext is a [CoroutineContext] to execute non-blocking code, such as parsing or processing @@ -141,6 +180,8 @@ public sealed class OutgoingContent { /** * Variant of an [OutgoingContent] which delegates to provided [OutgoingContent] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.OutgoingContent.ContentWrapper) */ public abstract class ContentWrapper(private val delegate: OutgoingContent) : OutgoingContent() { override val contentType: ContentType? @@ -159,6 +200,8 @@ public sealed class OutgoingContent { /** * Returns a copy of this implementation of [ContentWrapper] with provided [OutgoingContent] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.OutgoingContent.ContentWrapper.copy) */ public abstract fun copy(delegate: OutgoingContent): ContentWrapper } @@ -166,6 +209,8 @@ public sealed class OutgoingContent { /** * Check if current [OutgoingContent] doesn't contain content + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.isEmpty) */ @InternalAPI public fun OutgoingContent.isEmpty(): Boolean = when (this) { diff --git a/ktor-http/common/src/io/ktor/http/content/TextContent.kt b/ktor-http/common/src/io/ktor/http/content/TextContent.kt index 6160284ecd8..73364a72ed7 100644 --- a/ktor-http/common/src/io/ktor/http/content/TextContent.kt +++ b/ktor-http/common/src/io/ktor/http/content/TextContent.kt @@ -10,6 +10,9 @@ import io.ktor.utils.io.core.* /** * Represents a text content that could be sent + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.TextContent) + * * @property text to be sent */ public class TextContent( diff --git a/ktor-http/common/src/io/ktor/http/content/Versions.kt b/ktor-http/common/src/io/ktor/http/content/Versions.kt index 16b168a7c7a..bb5db9824d1 100644 --- a/ktor-http/common/src/io/ktor/http/content/Versions.kt +++ b/ktor-http/common/src/io/ktor/http/content/Versions.kt @@ -10,11 +10,15 @@ import io.ktor.util.date.* /** * Specifies a key for the VersionList extension property for [OutgoingContent]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.VersionListProperty) */ public val VersionListProperty: AttributeKey> = AttributeKey("VersionList") /** * Gets or sets a list of [Version] instances as an extension property on this content. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.versions) */ public var OutgoingContent.versions: List get() = getProperty(VersionListProperty) ?: emptyList() @@ -24,15 +28,21 @@ public var OutgoingContent.versions: List * A content version. * * An example of version is [EntityTagVersion] or [LastModifiedVersion]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.Version) */ public interface Version { /** * Checks [requestHeaders] against this version and returns [VersionCheckResult]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.Version.check) */ public fun check(requestHeaders: Headers): VersionCheckResult /** * Appends relevant headers to the builder. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.Version.appendHeadersTo) */ public fun appendHeadersTo(builder: HeadersBuilder) } @@ -40,21 +50,30 @@ public interface Version { /** * Represent the result of the version comparison between content being sent and HTTP request. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.VersionCheckResult) + * * @param statusCode represents [HttpStatusCode] associated with the result. */ public enum class VersionCheckResult(public val statusCode: HttpStatusCode) { /** * Indicates that content needs to be sent to recipient. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.VersionCheckResult.OK) */ OK(HttpStatusCode.OK), /** * Indicates that content has not been modified according to headers sent by the client. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.VersionCheckResult.NOT_MODIFIED) */ NOT_MODIFIED(HttpStatusCode.NotModified), /** * One or more conditions given in the request header fields evaluated to false. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.VersionCheckResult.PRECONDITION_FAILED) */ PRECONDITION_FAILED(HttpStatusCode.PreconditionFailed) } @@ -65,12 +84,18 @@ public enum class VersionCheckResult(public val statusCode: HttpStatusCode) { * * For better accuracy, use ETag instead. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.LastModifiedVersion) + * * @param lastModified of the current content, for example the file's last modified date */ public data class LastModifiedVersion(val lastModified: GMTDate) : Version { private val truncatedModificationDate: GMTDate = lastModified.truncateToSeconds() /** + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.LastModifiedVersion.check) + * * @return [VersionCheckResult.OK] if all headers pass or there are no headers in the request, * [VersionCheckResult.NOT_MODIFIED] for `If-Modified-Since`, * [VersionCheckResult.PRECONDITION_FAILED] for `If-Unmodified-Since` @@ -91,6 +116,8 @@ public data class LastModifiedVersion(val lastModified: GMTDate) : Version { /** * If-Modified-Since logic: all [dates] should be _before_ this date (truncated to seconds). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.LastModifiedVersion.ifModifiedSince) */ public fun ifModifiedSince(dates: List): Boolean { return dates.any { truncatedModificationDate > it } @@ -98,6 +125,8 @@ public data class LastModifiedVersion(val lastModified: GMTDate) : Version { /** * If-Unmodified-Since logic: all [dates] should not be before this date (truncated to seconds). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.LastModifiedVersion.ifUnmodifiedSince) */ public fun ifUnmodifiedSince(dates: List): Boolean { return dates.all { truncatedModificationDate <= it } @@ -122,6 +151,8 @@ public data class LastModifiedVersion(val lastModified: GMTDate) : Version { /** * Creates an instance of [EntityTagVersion] parsing the [spec] via [EntityTagVersion.parseSingle]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.EntityTagVersion) */ @Suppress("FunctionName", "CONFLICTING_OVERLOADS") public fun EntityTagVersion(spec: String): EntityTagVersion { @@ -134,6 +165,9 @@ public fun EntityTagVersion(spec: String): EntityTagVersion { * * It never handles `If-None-Match: *` as it is related to non-etag logic (for example, Last modified checks). * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.EntityTagVersion) + * * @param etag - entity tag, for example file's content hash * @param weak - whether strong or weak validation should be applied * @return [VersionCheckResult.OK] if all headers pass or there was no related headers, @@ -174,6 +208,8 @@ public data class EntityTagVersion(val etag: String, val weak: Boolean) : Versio /** * Checks whether two entity-tags match (strong). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.EntityTagVersion.match) */ public fun match(other: EntityTagVersion): Boolean { if (this == STAR || other == STAR) return true @@ -182,6 +218,8 @@ public data class EntityTagVersion(val etag: String, val weak: Boolean) : Versio /** * Specifies `If-None-Match` logic using the [match] function. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.EntityTagVersion.noneMatch) */ public fun noneMatch(givenNoneMatchEtags: List): VersionCheckResult { if (STAR in givenNoneMatchEtags) return VersionCheckResult.OK @@ -195,6 +233,8 @@ public data class EntityTagVersion(val etag: String, val weak: Boolean) : Versio /** * Specifies `If-Match` logic using the [match] function. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.EntityTagVersion.match) */ public fun match(givenMatchEtags: List): VersionCheckResult { if (givenMatchEtags.isEmpty()) return VersionCheckResult.OK @@ -216,11 +256,15 @@ public data class EntityTagVersion(val etag: String, val weak: Boolean) : Versio public companion object { /** * Instance for `*` entity-tag pattern. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.EntityTagVersion.Companion.STAR) */ public val STAR: EntityTagVersion = EntityTagVersion("*", false) /** * Parses headers with a list of entity-tags. Useful for headers such as `If-Match`/`If-None-Match`. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.EntityTagVersion.Companion.parse) */ public fun parse(headerValue: String): List { val rawEntries = parseHeaderValue(headerValue) @@ -234,6 +278,8 @@ public data class EntityTagVersion(val etag: String, val weak: Boolean) : Versio /** * Parses a single entity-tag or pattern specification. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.EntityTagVersion.Companion.parseSingle) */ public fun parseSingle(value: String): EntityTagVersion { if (value == "*") return STAR diff --git a/ktor-http/common/src/io/ktor/http/header/AcceptEncoding.kt b/ktor-http/common/src/io/ktor/http/header/AcceptEncoding.kt index a837175e3e4..7f0b7d7a1d8 100644 --- a/ktor-http/common/src/io/ktor/http/header/AcceptEncoding.kt +++ b/ktor-http/common/src/io/ktor/http/header/AcceptEncoding.kt @@ -9,6 +9,9 @@ import io.ktor.http.* /** * Represents the `Accept-Encoding` HTTP header, which specifies the content encoding the client is willing to accept. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.header.AcceptEncoding) + * * @property acceptEncoding The encoding type as a string, such as "gzip", "compress", "br", etc. * @param parameters Optional list of parameters associated with the encoding, such as quality values (q-values). */ @@ -20,6 +23,9 @@ public class AcceptEncoding( /** * Constructs an `AcceptEncoding` instance with a specified encoding type and q-value. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.header.AcceptEncoding.AcceptEncoding) + * * @param acceptEncoding The encoding type, such as "gzip", "compress", "br", etc. * @param qValue The quality value (q-value) associated with this encoding. */ @@ -30,6 +36,8 @@ public class AcceptEncoding( /** * Companion object containing predefined commonly used `Accept-Encoding` values. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.header.AcceptEncoding.Companion) */ public companion object { public val Gzip: AcceptEncoding = AcceptEncoding("gzip") @@ -43,6 +51,9 @@ public class AcceptEncoding( /** * Merges multiple `AcceptEncoding` instances into a single string separated by commas. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.header.AcceptEncoding.Companion.mergeAcceptEncodings) + * * @param encodings A variable number of `AcceptEncoding` objects to be merged. * @return A string representing the merged `Accept-Encoding` values. */ @@ -54,6 +65,9 @@ public class AcceptEncoding( /** * Returns a new `AcceptEncoding` instance with the specified q-value parameter. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.header.AcceptEncoding.withQValue) + * * @param qValue The q-value to be associated with this encoding. The value should be between 0.0 and 1.0. * @return A new `AcceptEncoding` instance with the specified q-value, or the same instance if the q-value is already set. */ @@ -69,6 +83,9 @@ public class AcceptEncoding( * Checks if `this` `AcceptEncoding` matches a [pattern] `AcceptEncoding`, taking into account * wildcard symbols `*` and parameters such as q-values. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.header.AcceptEncoding.match) + * * @param pattern The `AcceptEncoding` to match against. * @return `true` if `this` matches the given [pattern], `false` otherwise. */ diff --git a/ktor-http/common/src/io/ktor/http/parsing/ParseException.kt b/ktor-http/common/src/io/ktor/http/parsing/ParseException.kt index 3797b6cc9ff..81b7f369817 100644 --- a/ktor-http/common/src/io/ktor/http/parsing/ParseException.kt +++ b/ktor-http/common/src/io/ktor/http/parsing/ParseException.kt @@ -9,6 +9,8 @@ package io.ktor.http.parsing * a string to one of the specific types, but that the string does not * have the appropriate format. * Please check the message for more details on the failure. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.parsing.ParseException) * */ public class ParseException( override val message: String, diff --git a/ktor-http/common/src/io/ktor/http/websocket/Utils.kt b/ktor-http/common/src/io/ktor/http/websocket/Utils.kt index d4be18a1b5e..491509de126 100644 --- a/ktor-http/common/src/io/ktor/http/websocket/Utils.kt +++ b/ktor-http/common/src/io/ktor/http/websocket/Utils.kt @@ -12,6 +12,8 @@ private const val WEBSOCKET_SERVER_ACCEPT_TAIL = "258EAFA5-E914-47DA-95CA-C5AB0D /** * Calculates `Sec-WebSocket-Accept` header value + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.websocket.websocketServerAccept) */ public fun websocketServerAccept(nonce: String): String = sha1("${nonce.trim()}$WEBSOCKET_SERVER_ACCEPT_TAIL".toByteArray(Charsets.ISO_8859_1)).encodeBase64() diff --git a/ktor-http/common/test/io/ktor/tests/http/UrlTest.kt b/ktor-http/common/test/io/ktor/tests/http/UrlTest.kt index 068225ea4a4..f696b72eb42 100644 --- a/ktor-http/common/test/io/ktor/tests/http/UrlTest.kt +++ b/ktor-http/common/test/io/ktor/tests/http/UrlTest.kt @@ -110,6 +110,8 @@ class UrlTest { /** * https://tools.ietf.org/html/rfc1738#section-5 * hsegment = *[ uchar | ";" | ":" | "@" | "&" | "=" ] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.tests.http.UrlTest.testPath) */ @Test fun testPath() { diff --git a/ktor-http/jsAndWasmShared/src/io/ktor/http/URLBuilderJs.kt b/ktor-http/jsAndWasmShared/src/io/ktor/http/URLBuilderJs.kt index 011c1d8cc04..121d67ead53 100644 --- a/ktor-http/jsAndWasmShared/src/io/ktor/http/URLBuilderJs.kt +++ b/ktor-http/jsAndWasmShared/src/io/ktor/http/URLBuilderJs.kt @@ -26,6 +26,8 @@ private fun locationOrigin(): String = js( * Hostname of current origin. * * It uses "localhost" for all platforms except js. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.origin) */ public actual val URLBuilder.Companion.origin: String get() = when { diff --git a/ktor-http/jvm/src/io/ktor/http/FileContentTypeJvm.kt b/ktor-http/jvm/src/io/ktor/http/FileContentTypeJvm.kt index b7ab31e321a..0a2d6e9937d 100644 --- a/ktor-http/jvm/src/io/ktor/http/FileContentTypeJvm.kt +++ b/ktor-http/jvm/src/io/ktor/http/FileContentTypeJvm.kt @@ -9,12 +9,18 @@ import java.nio.file.* import kotlin.io.path.* /** + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.defaultForFile) + * * @return default content type for [file] by its extension */ public fun ContentType.Companion.defaultForFile(file: File): ContentType = ContentType.fromFileExtension(file.extension).selectDefault() /** + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.defaultForPath) + * * @return default content type for [path] by its extension */ public fun ContentType.Companion.defaultForPath(path: Path): ContentType = diff --git a/ktor-http/jvm/src/io/ktor/http/HttpMessagePropertiesJvm.kt b/ktor-http/jvm/src/io/ktor/http/HttpMessagePropertiesJvm.kt index d03308e4da6..f535bd70d57 100644 --- a/ktor-http/jvm/src/io/ktor/http/HttpMessagePropertiesJvm.kt +++ b/ktor-http/jvm/src/io/ktor/http/HttpMessagePropertiesJvm.kt @@ -18,31 +18,43 @@ private fun formatHttpDate(date: Date): String = HTTP_DATE_FORMAT.format(date) /** * Set `If-Modified-Since` header. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.ifModifiedSince) */ public fun HttpMessageBuilder.ifModifiedSince(date: Date): Unit = headers.set(HttpHeaders.IfModifiedSince, formatHttpDate(date)) /** * Parse `Last-Modified` header. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.lastModified) */ public fun HttpMessageBuilder.lastModified(): Date? = headers[HttpHeaders.LastModified]?.let { parseHttpDate(it) } /** * Parse `Expires` header. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.expires) */ public fun HttpMessageBuilder.expires(): Date? = headers[HttpHeaders.Expires]?.let { parseHttpDate(it) } /** * Parse `Last-Modified` header. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.lastModified) */ public fun HttpMessage.lastModified(): Date? = headers[HttpHeaders.LastModified]?.let { parseHttpDate(it) } /** * Parse `Expires` header. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.expires) */ public fun HttpMessage.expires(): Date? = headers[HttpHeaders.Expires]?.let { parseHttpDate(it) } /** * Parse `Date` header. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.date) */ public fun HttpMessage.date(): Date? = headers[HttpHeaders.Date]?.let { parseHttpDate(it) } diff --git a/ktor-http/jvm/src/io/ktor/http/URLBuilderJvm.kt b/ktor-http/jvm/src/io/ktor/http/URLBuilderJvm.kt index d9daf70e493..6c7025ceca4 100644 --- a/ktor-http/jvm/src/io/ktor/http/URLBuilderJvm.kt +++ b/ktor-http/jvm/src/io/ktor/http/URLBuilderJvm.kt @@ -8,6 +8,8 @@ import java.net.* /** * Construct [Url] from [String] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.invoke) */ public operator fun Url.Companion.invoke(fullUrl: String): Url = URLBuilder().apply { takeFrom(URI(fullUrl)) @@ -17,5 +19,7 @@ public operator fun Url.Companion.invoke(fullUrl: String): Url = URLBuilder().ap * Hostname of current origin. * * It uses "localhost" for all platforms except js. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.origin) */ public actual val URLBuilder.Companion.origin: String get() = "http://localhost" diff --git a/ktor-http/jvm/src/io/ktor/http/URLUtilsJvm.kt b/ktor-http/jvm/src/io/ktor/http/URLUtilsJvm.kt index 102aa581121..426d1456e13 100644 --- a/ktor-http/jvm/src/io/ktor/http/URLUtilsJvm.kt +++ b/ktor-http/jvm/src/io/ktor/http/URLUtilsJvm.kt @@ -8,6 +8,8 @@ import java.net.* /** * Take URI components from [uri] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.takeFrom) */ public fun URLBuilder.takeFrom(uri: URI): URLBuilder { uri.scheme?.let { @@ -45,6 +47,8 @@ public fun URLBuilder.takeFrom(uri: URI): URLBuilder { /** * Take URL components from [url] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.takeFrom) */ public fun URLBuilder.takeFrom(url: URL): URLBuilder = when { url.host.contains('_') -> takeFrom(url.toString()) @@ -53,6 +57,8 @@ public fun URLBuilder.takeFrom(url: URL): URLBuilder = when { /** * Convert [Url] to [URI] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.toURI) */ public fun Url.toURI(): URI = URI(toString()) @@ -60,6 +66,8 @@ public fun Url.toURI(): URI = URI(toString()) * Helper method that concisely creates a [Url] from a [URI] * * Creates [Url] from [URI] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.Url) */ @Suppress("FunctionName") public fun Url(uri: URI): Url = URLBuilder().takeFrom(uri).build() diff --git a/ktor-http/jvm/src/io/ktor/http/content/MultipartJvm.kt b/ktor-http/jvm/src/io/ktor/http/content/MultipartJvm.kt index 2133326c406..643c9bb75be 100644 --- a/ktor-http/jvm/src/io/ktor/http/content/MultipartJvm.kt +++ b/ktor-http/jvm/src/io/ktor/http/content/MultipartJvm.kt @@ -9,6 +9,8 @@ import java.io.* /** * Provides file item's content as an [InputStream] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.streamProvider) */ @Suppress("DeprecatedCallableAddReplaceWith") @Deprecated("This API uses blocking InputStream. Please use provider() directly.") diff --git a/ktor-http/jvm/src/io/ktor/http/content/OutputStreamContent.kt b/ktor-http/jvm/src/io/ktor/http/content/OutputStreamContent.kt index 745d2df30fb..8a9c9c47911 100644 --- a/ktor-http/jvm/src/io/ktor/http/content/OutputStreamContent.kt +++ b/ktor-http/jvm/src/io/ktor/http/content/OutputStreamContent.kt @@ -12,6 +12,8 @@ import java.io.* /** * [OutgoingContent] to respond with [OutputStream]. * The stream would be automatically closed after [body] finish. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.OutputStreamContent) */ public class OutputStreamContent( private val body: suspend OutputStream.() -> Unit, diff --git a/ktor-http/jvm/src/io/ktor/http/content/URIFileContent.kt b/ktor-http/jvm/src/io/ktor/http/content/URIFileContent.kt index aefa9c08d66..70e7e22fd2a 100644 --- a/ktor-http/jvm/src/io/ktor/http/content/URIFileContent.kt +++ b/ktor-http/jvm/src/io/ktor/http/content/URIFileContent.kt @@ -12,6 +12,9 @@ import java.net.* /** * Represents a content that is served from the specified [uri] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.URIFileContent) + * * @property uri that is used as a source */ public class URIFileContent( diff --git a/ktor-http/jvm/src/io/ktor/http/content/VersionsJvm.kt b/ktor-http/jvm/src/io/ktor/http/content/VersionsJvm.kt index d34e2cd1e11..265c306c4e5 100644 --- a/ktor-http/jvm/src/io/ktor/http/content/VersionsJvm.kt +++ b/ktor-http/jvm/src/io/ktor/http/content/VersionsJvm.kt @@ -18,6 +18,9 @@ import java.util.* * See https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.28 and * https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.25 * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.LastModifiedVersion) + * * @param lastModified of the current content, for example file's last modified date */ public fun LastModifiedVersion(lastModified: Date): LastModifiedVersion = diff --git a/ktor-http/jvm/src/io/ktor/http/content/WriterContent.kt b/ktor-http/jvm/src/io/ktor/http/content/WriterContent.kt index 677e03e347a..1e120e7d040 100644 --- a/ktor-http/jvm/src/io/ktor/http/content/WriterContent.kt +++ b/ktor-http/jvm/src/io/ktor/http/content/WriterContent.kt @@ -11,6 +11,8 @@ import java.io.* /** * Represents a content that is produced by [body] function + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.content.WriterContent) */ public class WriterContent( private val body: suspend Writer.() -> Unit, diff --git a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/CIOHeaders.kt b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/CIOHeaders.kt index 5d2bf6750ee..f16fc5d8617 100644 --- a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/CIOHeaders.kt +++ b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/CIOHeaders.kt @@ -9,6 +9,8 @@ import io.ktor.util.* /** * An adapter from CIO low-level headers map to ktor [Headers] interface + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.CIOHeaders) */ public class CIOHeaders(private val headers: HttpHeadersMap) : Headers { diff --git a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/CIOMultipartDataBase.kt b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/CIOMultipartDataBase.kt index 65c45647029..d1b92ab31ae 100644 --- a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/CIOMultipartDataBase.kt +++ b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/CIOMultipartDataBase.kt @@ -13,6 +13,8 @@ import kotlin.coroutines.* /** * Represents a multipart data object that does parse and convert parts to ktor's [PartData] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.CIOMultipartDataBase) */ @InternalAPI public class CIOMultipartDataBase( diff --git a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/ChunkedTransferEncoding.kt b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/ChunkedTransferEncoding.kt index 297c48593bd..0e044e7ff4a 100644 --- a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/ChunkedTransferEncoding.kt +++ b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/ChunkedTransferEncoding.kt @@ -24,11 +24,15 @@ private val ChunkSizeBufferPool: ObjectPool = /** * Decoder job type + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.DecoderJob) */ public typealias DecoderJob = WriterJob /** * Start a chunked stream decoder coroutine + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.decodeChunked) */ @Suppress("TYPEALIAS_EXPANSION_DEPRECATION") @Deprecated( @@ -41,6 +45,8 @@ public fun CoroutineScope.decodeChunked(input: ByteReadChannel): DecoderJob = /** * Start a chunked stream decoder coroutine + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.decodeChunked) */ @Suppress("UNUSED_PARAMETER", "TYPEALIAS_EXPANSION_DEPRECATION") public fun CoroutineScope.decodeChunked(input: ByteReadChannel, contentLength: Long): DecoderJob = @@ -51,6 +57,9 @@ public fun CoroutineScope.decodeChunked(input: ByteReadChannel, contentLength: L /** * Decode chunked transfer encoding from the [input] channel and write the result in [out]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.decodeChunked) + * * @throws EOFException if stream has ended unexpectedly. * @throws ParserException if the format is invalid. */ @@ -97,11 +106,15 @@ public suspend fun decodeChunked(input: ByteReadChannel, out: ByteWriteChannel) /** * Encoder job type + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.EncoderJob) */ public typealias EncoderJob = ReaderJob /** * Start chunked stream encoding coroutine + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.encodeChunked) */ @OptIn(DelicateCoroutinesApi::class) public fun encodeChunked( @@ -113,6 +126,8 @@ public fun encodeChunked( /** * Chunked stream encoding loop + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.encodeChunked) */ public suspend fun encodeChunked(output: ByteWriteChannel, input: ByteReadChannel) { try { diff --git a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/ConnectionOptions.kt b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/ConnectionOptions.kt index 472750f117c..3c5fd4b5578 100644 --- a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/ConnectionOptions.kt +++ b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/ConnectionOptions.kt @@ -8,6 +8,9 @@ import io.ktor.http.cio.internals.* /** * Represents a parsed `Connection` header + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.ConnectionOptions) + * * @property close `true` for `Connection: close` * @property keepAlive `true` for `Connection: keep-alive` * @property upgrade `true` for `Connection: upgrade` @@ -22,16 +25,22 @@ public class ConnectionOptions( public companion object { /** * An instance for `Connection: close` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.ConnectionOptions.Companion.Close) */ public val Close: ConnectionOptions = ConnectionOptions(close = true) /** * An instance for `Connection: keep-alive` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.ConnectionOptions.Companion.KeepAlive) */ public val KeepAlive: ConnectionOptions = ConnectionOptions(keepAlive = true) /** * An instance for `Connection: upgrade` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.ConnectionOptions.Companion.Upgrade) */ public val Upgrade: ConnectionOptions = ConnectionOptions(upgrade = true) @@ -43,6 +52,8 @@ public class ConnectionOptions( /** * Parse `Connection` header value + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.ConnectionOptions.Companion.parse) */ public fun parse(connection: CharSequence?): ConnectionOptions? { if (connection == null) return null diff --git a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/HttpBody.kt b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/HttpBody.kt index b55dab89439..d5c437dccd1 100644 --- a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/HttpBody.kt +++ b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/HttpBody.kt @@ -10,6 +10,9 @@ import io.ktor.utils.io.* import io.ktor.utils.io.errors.* /** + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.expectHttpUpgrade) + * * @return `true` if an http upgrade is expected according to request [method], [upgrade] header value and * parsed [connectionOptions] */ @@ -22,6 +25,9 @@ public fun expectHttpUpgrade( connectionOptions?.upgrade == true /** + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.expectHttpUpgrade) + * * @return `true` if an http upgrade is expected according to [request] */ public fun expectHttpUpgrade(request: Request): Boolean = expectHttpUpgrade( @@ -31,6 +37,9 @@ public fun expectHttpUpgrade(request: Request): Boolean = expectHttpUpgrade( ) /** + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.expectHttpBody) + * * @return `true` if request or response with the specified parameters could have a body */ public fun expectHttpBody( @@ -54,6 +63,9 @@ public fun expectHttpBody( } /** + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.expectHttpBody) + * * @return `true` if request or response with the specified parameters could have a body */ public fun expectHttpBody(request: Request): Boolean = expectHttpBody( @@ -69,6 +81,9 @@ public fun expectHttpBody(request: Request): Boolean = expectHttpBody( * writing it to [out]. * Usually doesn't fail but closing [out] channel with error. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.parseHttpBody) + * * @param contentLength from the corresponding header or -1 * @param transferEncoding header or `null` * @param @@ -111,6 +126,9 @@ public suspend fun parseHttpBody( * writing it to [out]. * Usually doesn't fail but closing [out] channel with error. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.parseHttpBody) + * * @param contentLength from the corresponding header or -1 * @param transferEncoding header or `null` * @param @@ -132,6 +150,8 @@ public suspend fun parseHttpBody( /** * Parse HTTP request or response body using request/response's [headers] * writing it to [out]. Usually doesn't fail but closing [out] channel with error. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.parseHttpBody) */ public suspend fun parseHttpBody( headers: HttpHeadersMap, diff --git a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/HttpHeadersMap.kt b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/HttpHeadersMap.kt index d78fd779a72..d2311650863 100644 --- a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/HttpHeadersMap.kt +++ b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/HttpHeadersMap.kt @@ -26,6 +26,8 @@ private val EMPTY_INT_LIST = IntArray(0) /** * A headers map data structure used in CIO + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.HttpHeadersMap) */ public class HttpHeadersMap internal constructor(private val builder: CharArrayBuilder) { diff --git a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/HttpParser.kt b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/HttpParser.kt index 99ee47de4c9..045f3f9a81f 100644 --- a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/HttpParser.kt +++ b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/HttpParser.kt @@ -10,6 +10,8 @@ import io.ktor.utils.io.* /** * An HTTP parser exception + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.ParserException) */ public class ParserException(message: String) : IllegalStateException(message) @@ -20,6 +22,8 @@ private val hostForbiddenSymbols = setOf('/', '?', '#', '@') /** * Parse an HTTP request line and headers + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.parseRequest) */ public suspend fun parseRequest(input: ByteReadChannel): Request? { val builder = CharArrayBuilder() @@ -54,6 +58,8 @@ public suspend fun parseRequest(input: ByteReadChannel): Request? { /** * Parse an HTTP response status line and headers + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.parseResponse) */ public suspend fun parseResponse(input: ByteReadChannel): Response? { val builder = CharArrayBuilder() @@ -80,6 +86,8 @@ public suspend fun parseResponse(input: ByteReadChannel): Response? { /** * Parse http headers. Not applicable to request and response status lines. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.parseHeaders) */ public suspend fun parseHeaders(input: ByteReadChannel): HttpHeadersMap { val builder = CharArrayBuilder() diff --git a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/Multipart.kt b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/Multipart.kt index 8f98c8674fc..fb4d0ac5bdd 100644 --- a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/Multipart.kt +++ b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/Multipart.kt @@ -20,16 +20,23 @@ import kotlinx.io.bytestring.ByteString /** * Represents a multipart content starting event. Every part need to be completely consumed or released via [release] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.MultipartEvent) */ public sealed class MultipartEvent { /** * Release underlying data/packet. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.MultipartEvent.release) */ public abstract fun release() /** * Represents a multipart content preamble. A multipart stream could have at most one preamble. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.MultipartEvent.Preamble) + * * @property body contains preamble's content */ public class Preamble( @@ -45,6 +52,9 @@ public sealed class MultipartEvent { * it is important to consume [body] otherwise multipart parser could get stuck (suspend) * so you will not receive more events. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.MultipartEvent.MultipartPart) + * * @property headers deferred that will be completed once will be parsed * @property body a channel of part content */ @@ -66,6 +76,9 @@ public sealed class MultipartEvent { /** * Represents a multipart content epilogue. A multipart stream could have at most one epilogue. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.MultipartEvent.Epilogue) + * * @property body contains epilogue's content */ public class Epilogue( @@ -135,6 +148,8 @@ private suspend fun ByteReadChannel.skipIfFoundReadCount(prefix: ByteString): Lo /** * Starts a multipart parser coroutine producing multipart events + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.parseMultipart) */ @OptIn(InternalAPI::class) public fun CoroutineScope.parseMultipart( @@ -152,6 +167,8 @@ public fun CoroutineScope.parseMultipart( /** * Starts a multipart parser coroutine producing multipart events + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.parseMultipart) */ @OptIn(InternalAPI::class) public fun CoroutineScope.parseMultipart( diff --git a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/RequestResponse.kt b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/RequestResponse.kt index f31aa6e0c1a..cb7b92896c7 100644 --- a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/RequestResponse.kt +++ b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/RequestResponse.kt @@ -10,6 +10,9 @@ import io.ktor.utils.io.core.* /** * Represents a base HTTP message type for request and response + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.HttpMessage) + * * @property headers request/response headers */ public abstract class HttpMessage internal constructor( @@ -19,6 +22,8 @@ public abstract class HttpMessage internal constructor( /** * Release all memory resources hold by this message + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.HttpMessage.release) */ public fun release() { builder.release() @@ -27,6 +32,8 @@ public abstract class HttpMessage internal constructor( /** * Release all memory resources hold by this message + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.HttpMessage.close) */ override fun close() { release() @@ -35,6 +42,9 @@ public abstract class HttpMessage internal constructor( /** * Represents an HTTP request + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.Request) + * * @property method * @property uri * @property version @@ -49,6 +59,9 @@ public class Request internal constructor( /** * Represents an HTTP response + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.Response) + * * @property version * @property status * @property statusText diff --git a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/RequestResponseBuilderCommon.kt b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/RequestResponseBuilderCommon.kt index 082354377aa..392924b8502 100644 --- a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/RequestResponseBuilderCommon.kt +++ b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/RequestResponseBuilderCommon.kt @@ -9,46 +9,64 @@ import kotlinx.io.* /** * Builds an HTTP request or response + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.RequestResponseBuilder) */ public expect class RequestResponseBuilder() { /** * Append response status line + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.RequestResponseBuilder.responseLine) */ public fun responseLine(version: CharSequence, status: Int, statusText: CharSequence) /** * Append request line + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.RequestResponseBuilder.requestLine) */ public fun requestLine(method: HttpMethod, uri: CharSequence, version: CharSequence) /** * Append a line + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.RequestResponseBuilder.line) */ public fun line(line: CharSequence) /** * Append raw bytes + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.RequestResponseBuilder.bytes) */ public fun bytes(content: ByteArray, offset: Int = 0, length: Int = content.size) /** * Append header line + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.RequestResponseBuilder.headerLine) */ public fun headerLine(name: CharSequence, value: CharSequence) /** * Append an empty line (CR + LF in fact) + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.RequestResponseBuilder.emptyLine) */ public fun emptyLine() /** * Build a packet of request/response + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.RequestResponseBuilder.build) */ public fun build(): Source /** * Release all resources hold by the builder + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.RequestResponseBuilder.release) */ public fun release() } diff --git a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/internals/Chars.kt b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/internals/Chars.kt index 5d6343a40b6..b29f5aae162 100644 --- a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/internals/Chars.kt +++ b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/internals/Chars.kt @@ -64,6 +64,8 @@ internal fun CharSequence.parseHexLong(): Long { /** * Converts [CharSequence] representation in decimal format to [Long] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.internals.parseDecLong) */ public fun CharSequence.parseDecLong(): Long { val length = length diff --git a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/internals/MutableRange.kt b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/internals/MutableRange.kt index 10a49e9c938..996aec4cf40 100644 --- a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/internals/MutableRange.kt +++ b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/internals/MutableRange.kt @@ -6,6 +6,9 @@ package io.ktor.http.cio.internals /** * A text range with mutable bounds + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.internals.MutableRange) + * * @param start points to the first character * @param end points to the next character after the last one */ diff --git a/ktor-http/ktor-http-cio/jsAndWasmShared/src/io/ktor/http/cio/RequestResponseBuilderJs.kt b/ktor-http/ktor-http-cio/jsAndWasmShared/src/io/ktor/http/cio/RequestResponseBuilderJs.kt index 7c31202edb4..bc8cf147224 100644 --- a/ktor-http/ktor-http-cio/jsAndWasmShared/src/io/ktor/http/cio/RequestResponseBuilderJs.kt +++ b/ktor-http/ktor-http-cio/jsAndWasmShared/src/io/ktor/http/cio/RequestResponseBuilderJs.kt @@ -11,12 +11,16 @@ import kotlinx.io.* /** * Builds an HTTP request or response + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.RequestResponseBuilder) */ public actual class RequestResponseBuilder actual constructor() { private val packet = BytePacketBuilder() /** * Append response status line + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.RequestResponseBuilder.responseLine) */ public actual fun responseLine(version: CharSequence, status: Int, statusText: CharSequence) { packet.writeText(version) @@ -30,6 +34,8 @@ public actual class RequestResponseBuilder actual constructor() { /** * Append request line + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.RequestResponseBuilder.requestLine) */ public actual fun requestLine(method: HttpMethod, uri: CharSequence, version: CharSequence) { packet.writeText(method.value) @@ -43,6 +49,8 @@ public actual class RequestResponseBuilder actual constructor() { /** * Append a line + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.RequestResponseBuilder.line) */ public actual fun line(line: CharSequence) { packet.append(line) @@ -52,6 +60,8 @@ public actual class RequestResponseBuilder actual constructor() { /** * Append raw bytes + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.RequestResponseBuilder.bytes) */ public actual fun bytes(content: ByteArray, offset: Int, length: Int) { packet.writeFully(content, offset, length) @@ -59,6 +69,8 @@ public actual class RequestResponseBuilder actual constructor() { /** * Append header line + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.RequestResponseBuilder.headerLine) */ public actual fun headerLine(name: CharSequence, value: CharSequence) { packet.append(name) @@ -70,6 +82,8 @@ public actual class RequestResponseBuilder actual constructor() { /** * Append an empty line (CR + LF in fact) + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.RequestResponseBuilder.emptyLine) */ public actual fun emptyLine() { packet.writeByte(CR) @@ -78,12 +92,16 @@ public actual class RequestResponseBuilder actual constructor() { /** * Build a packet of request/response + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.RequestResponseBuilder.build) */ public actual fun build(): Source = packet.build() /** * Release all resources hold by the builder + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.RequestResponseBuilder.release) */ public actual fun release() { diff --git a/ktor-http/ktor-http-cio/jvm/src/io/ktor/http/cio/RequestResponseBuilder.kt b/ktor-http/ktor-http-cio/jvm/src/io/ktor/http/cio/RequestResponseBuilder.kt index e0447a9c1dc..96d971acf79 100644 --- a/ktor-http/ktor-http-cio/jvm/src/io/ktor/http/cio/RequestResponseBuilder.kt +++ b/ktor-http/ktor-http-cio/jvm/src/io/ktor/http/cio/RequestResponseBuilder.kt @@ -11,6 +11,8 @@ import java.nio.ByteBuffer /** * Builds an HTTP request or response + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.RequestResponseBuilder) */ public actual class RequestResponseBuilder actual constructor() { @@ -18,6 +20,8 @@ public actual class RequestResponseBuilder actual constructor() { /** * Append response status line + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.RequestResponseBuilder.responseLine) */ public actual fun responseLine(version: CharSequence, status: Int, statusText: CharSequence) { packet.writeText(version) @@ -31,6 +35,8 @@ public actual class RequestResponseBuilder actual constructor() { /** * Append request line + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.RequestResponseBuilder.requestLine) */ public actual fun requestLine(method: HttpMethod, uri: CharSequence, version: CharSequence) { packet.writeText(method.value) @@ -44,6 +50,8 @@ public actual class RequestResponseBuilder actual constructor() { /** * Append a line + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.RequestResponseBuilder.line) */ public actual fun line(line: CharSequence) { packet.append(line) @@ -53,6 +61,8 @@ public actual class RequestResponseBuilder actual constructor() { /** * Append raw bytes + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.RequestResponseBuilder.bytes) */ public actual fun bytes(content: ByteArray, offset: Int, length: Int) { packet.writeFully(content, offset, length) @@ -60,6 +70,8 @@ public actual class RequestResponseBuilder actual constructor() { /** * Append raw bytes + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.RequestResponseBuilder.bytes) */ public fun bytes(content: ByteBuffer) { packet.writeFully(content) @@ -67,6 +79,8 @@ public actual class RequestResponseBuilder actual constructor() { /** * Append header line + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.RequestResponseBuilder.headerLine) */ public actual fun headerLine(name: CharSequence, value: CharSequence) { packet.append(name) @@ -78,6 +92,8 @@ public actual class RequestResponseBuilder actual constructor() { /** * Append an empty line (CR + LF in fact) + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.RequestResponseBuilder.emptyLine) */ public actual fun emptyLine() { packet.writeByte(CR) @@ -86,11 +102,15 @@ public actual class RequestResponseBuilder actual constructor() { /** * Build a packet of request/response + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.RequestResponseBuilder.build) */ public actual fun build(): Source = packet.build() /** * Release all resources hold by the builder + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.RequestResponseBuilder.release) */ public actual fun release() { packet.close() diff --git a/ktor-http/ktor-http-cio/posix/src/io/ktor/http/cio/RequestResponseBuilderNative.kt b/ktor-http/ktor-http-cio/posix/src/io/ktor/http/cio/RequestResponseBuilderNative.kt index b731601a257..cfb5ef1ac52 100644 --- a/ktor-http/ktor-http-cio/posix/src/io/ktor/http/cio/RequestResponseBuilderNative.kt +++ b/ktor-http/ktor-http-cio/posix/src/io/ktor/http/cio/RequestResponseBuilderNative.kt @@ -11,6 +11,8 @@ import kotlinx.io.* /** * Builds an HTTP request or response + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.RequestResponseBuilder) */ public actual class RequestResponseBuilder actual constructor() { @@ -18,6 +20,8 @@ public actual class RequestResponseBuilder actual constructor() { /** * Append response status line + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.RequestResponseBuilder.responseLine) */ public actual fun responseLine(version: CharSequence, status: Int, statusText: CharSequence) { packet.writeText(version) @@ -31,6 +35,8 @@ public actual class RequestResponseBuilder actual constructor() { /** * Append request line + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.RequestResponseBuilder.requestLine) */ public actual fun requestLine(method: HttpMethod, uri: CharSequence, version: CharSequence) { packet.writeText(method.value) @@ -44,6 +50,8 @@ public actual class RequestResponseBuilder actual constructor() { /** * Append a line + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.RequestResponseBuilder.line) */ public actual fun line(line: CharSequence) { packet.append(line) @@ -53,6 +61,8 @@ public actual class RequestResponseBuilder actual constructor() { /** * Append raw bytes + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.RequestResponseBuilder.bytes) */ public actual fun bytes(content: ByteArray, offset: Int, length: Int) { packet.writeFully(content, offset, length) @@ -60,6 +70,8 @@ public actual class RequestResponseBuilder actual constructor() { /** * Append header line + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.RequestResponseBuilder.headerLine) */ public actual fun headerLine(name: CharSequence, value: CharSequence) { packet.append(name) @@ -71,6 +83,8 @@ public actual class RequestResponseBuilder actual constructor() { /** * Append an empty line (CR + LF in fact) + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.RequestResponseBuilder.emptyLine) */ public actual fun emptyLine() { packet.writeByte(CR) @@ -79,11 +93,15 @@ public actual class RequestResponseBuilder actual constructor() { /** * Build a packet of request/response + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.RequestResponseBuilder.build) */ public actual fun build(): Source = packet.build() /** * Release all resources hold by the builder + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.RequestResponseBuilder.release) */ public actual fun release() { packet.close() diff --git a/ktor-http/posix/src/io/ktor/http/URLBuilderPosix.kt b/ktor-http/posix/src/io/ktor/http/URLBuilderPosix.kt index 3d3748e8c64..53bd8684dc5 100644 --- a/ktor-http/posix/src/io/ktor/http/URLBuilderPosix.kt +++ b/ktor-http/posix/src/io/ktor/http/URLBuilderPosix.kt @@ -8,5 +8,7 @@ package io.ktor.http * Hostname of current origin. * * It uses "localhost" for all platforms except js. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.origin) */ public actual val URLBuilder.Companion.origin: String get() = "http://localhost" diff --git a/ktor-io/common/src/io/ktor/utils/io/Annotations.kt b/ktor-io/common/src/io/ktor/utils/io/Annotations.kt index 6ea67740127..47a22fdeef7 100644 --- a/ktor-io/common/src/io/ktor/utils/io/Annotations.kt +++ b/ktor-io/common/src/io/ktor/utils/io/Annotations.kt @@ -8,6 +8,8 @@ package io.ktor.utils.io * API marked with this annotation is internal, and it is not intended to be used outside Ktor. * It could be modified or removed without any notice. Using it outside Ktor could cause undefined behaviour and/or * any unexpected effects. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.InternalAPI) */ @RequiresOptIn( level = RequiresOptIn.Level.ERROR, @@ -27,6 +29,8 @@ public annotation class InternalAPI /** * API marked with this annotation is experimental and is not guaranteed to be stable. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.KtorExperimentalAPI) */ @RequiresOptIn( level = RequiresOptIn.Level.WARNING, @@ -58,6 +62,9 @@ public annotation class KtorExperimentalAPI * Please note that the specified [version] and the fact of making something a candidate is not a guarantee, * so the target version could be changed without any notice or even the promotion could be cancelled at all. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.PublicAPICandidate) + * * @property version in which the API is planned to be promoted */ @InternalAPI @@ -75,6 +82,8 @@ public annotation class PublicAPICandidate(val version: String) /** * A marker annotations for DSLs. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.KtorDsl) */ @DslMarker @Target(AnnotationTarget.CLASS, AnnotationTarget.TYPEALIAS, AnnotationTarget.TYPE, AnnotationTarget.FUNCTION) diff --git a/ktor-io/common/src/io/ktor/utils/io/BufferedByteWriteChannel.kt b/ktor-io/common/src/io/ktor/utils/io/BufferedByteWriteChannel.kt index 05e01161509..975193b65f3 100644 --- a/ktor-io/common/src/io/ktor/utils/io/BufferedByteWriteChannel.kt +++ b/ktor-io/common/src/io/ktor/utils/io/BufferedByteWriteChannel.kt @@ -7,12 +7,16 @@ package io.ktor.utils.io public interface BufferedByteWriteChannel : ByteWriteChannel { /** * Flush all pending bytes from [writeBuffer] to the internal read buffer without suspension. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.BufferedByteWriteChannel.flushWriteBuffer) */ @InternalAPI public fun flushWriteBuffer() /** * Flush all pending bytes from [writeBuffer] to the internal read buffer without suspension and initiate channel close. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.BufferedByteWriteChannel.close) */ public fun close() } diff --git a/ktor-io/common/src/io/ktor/utils/io/ByteChannel.kt b/ktor-io/common/src/io/ktor/utils/io/ByteChannel.kt index ce9f39167b2..8e8da8bc0d6 100644 --- a/ktor-io/common/src/io/ktor/utils/io/ByteChannel.kt +++ b/ktor-io/common/src/io/ktor/utils/io/ByteChannel.kt @@ -17,6 +17,8 @@ internal const val CHANNEL_MAX_SIZE: Int = 1024 * 1024 /** * Sequential (non-concurrent) byte channel implementation + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.ByteChannel) */ public class ByteChannel(public val autoFlush: Boolean = false) : ByteReadChannel, BufferedByteWriteChannel { private val flushBuffer: Buffer = Buffer() @@ -268,6 +270,8 @@ public class ByteChannel(public val autoFlush: Boolean = false) : ByteReadChanne /** * Thrown when a coroutine awaiting I/O is replaced by another. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.ConcurrentIOException) */ public class ConcurrentIOException( taskName: String, diff --git a/ktor-io/common/src/io/ktor/utils/io/ByteChannelCtor.kt b/ktor-io/common/src/io/ktor/utils/io/ByteChannelCtor.kt index 2da9677dcf6..dcf361a3573 100644 --- a/ktor-io/common/src/io/ktor/utils/io/ByteChannelCtor.kt +++ b/ktor-io/common/src/io/ktor/utils/io/ByteChannelCtor.kt @@ -12,6 +12,8 @@ import kotlinx.io.Buffer /** * Creates a channel for reading from the specified byte array. Please note that it could use [content] directly * or copy its bytes depending on the platform + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.ByteReadChannel) */ public fun ByteReadChannel(content: ByteArray, offset: Int = 0, length: Int = content.size): ByteReadChannel { val source = Buffer().also { diff --git a/ktor-io/common/src/io/ktor/utils/io/ByteChannelUtils.kt b/ktor-io/common/src/io/ktor/utils/io/ByteChannelUtils.kt index d5c86537a72..6954529d443 100644 --- a/ktor-io/common/src/io/ktor/utils/io/ByteChannelUtils.kt +++ b/ktor-io/common/src/io/ktor/utils/io/ByteChannelUtils.kt @@ -8,6 +8,8 @@ import kotlinx.coroutines.* /** * Ensures that when the given job is canceled, the ByteChannel is canceled with the same exception. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.attachJob) */ public fun ByteChannel.attachJob(job: Job) { job.invokeOnCompletion { @@ -19,6 +21,8 @@ public fun ByteChannel.attachJob(job: Job) { /** * Ensures that when the given job is canceled, the ByteChannel is canceled with the same exception. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.attachJob) */ public fun ByteChannel.attachJob(job: ChannelJob) { attachJob(job.job) diff --git a/ktor-io/common/src/io/ktor/utils/io/ByteReadChannel.kt b/ktor-io/common/src/io/ktor/utils/io/ByteReadChannel.kt index f60046d62e8..bc9c7270c31 100644 --- a/ktor-io/common/src/io/ktor/utils/io/ByteReadChannel.kt +++ b/ktor-io/common/src/io/ktor/utils/io/ByteReadChannel.kt @@ -11,6 +11,8 @@ import kotlinx.io.* * This is a **single-reader channel**. * * Operations on this channel cannot be invoked concurrently. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.ByteReadChannel) */ public interface ByteReadChannel { @@ -25,6 +27,9 @@ public interface ByteReadChannel { * Suspend the channel until it has [min] bytes or gets closed. Throws exception if the channel was closed with an * error. If there are bytes available in the channel, this function returns immediately. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.ByteReadChannel.awaitContent) + * * @return return `false` eof is reached, otherwise `true`. */ public suspend fun awaitContent(min: Int = 1): Boolean diff --git a/ktor-io/common/src/io/ktor/utils/io/ByteReadChannelOperations.kt b/ktor-io/common/src/io/ktor/utils/io/ByteReadChannelOperations.kt index e10169017b0..ba6885bf8e4 100644 --- a/ktor-io/common/src/io/ktor/utils/io/ByteReadChannelOperations.kt +++ b/ktor-io/common/src/io/ktor/utils/io/ByteReadChannelOperations.kt @@ -25,6 +25,9 @@ public val ByteWriteChannel.availableForWrite: Int * If the read buffer is empty, it suspends until there are bytes available in the channel. * Once the channel is exhausted or closed, this function returns. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.exhausted) + * * @return `true` if the channel is exhausted, `false` if EOF is reached or an error occurred. */ @OptIn(InternalAPI::class) @@ -64,6 +67,8 @@ public suspend fun ByteReadChannel.readInt(): Int { /** * Reads a 32-bit floating-point value from the current [ByteReadChannel]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.readFloat) */ @OptIn(InternalAPI::class) public suspend fun ByteReadChannel.readFloat(): Float { @@ -79,6 +84,8 @@ public suspend fun ByteReadChannel.readLong(): Long { /** * Reads a 32-bit floating-point value from the current [ByteReadChannel]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.readDouble) */ @OptIn(InternalAPI::class) public suspend fun ByteReadChannel.readDouble(): Double { @@ -149,6 +156,9 @@ public suspend fun ByteReadChannel.copyAndClose(channel: ByteWriteChannel): Long * Reads a line of UTF-8 characters from the `ByteReadChannel`. * It recognizes CR, LF and CRLF as line delimiters. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.readUTF8Line) + * * @param max the maximum number of characters to read. Default is [Int.MAX_VALUE]. * @return a string containing the line read, or null if channel is closed * @throws TooLongLineException if max is reached before encountering a newline or end of input @@ -241,6 +251,9 @@ public suspend fun ByteReadChannel.readRemaining(max: Long): Source { /** * Reads all available bytes to [dst] buffer and returns immediately or suspends if no bytes available + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.readAvailable) + * * @return number of bytes were read or `-1` if the channel has been closed */ @OptIn(InternalAPI::class) @@ -265,6 +278,9 @@ public suspend fun ByteReadChannel.readAvailable( * eg: it could be 4 bytes available for read but the provided byte buffer could have only 2 available bytes: * in this case you have to invoke read again (with decreased [min] accordingly). * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.readAvailable) + * * @param min amount of bytes available for read, should be positive * @param block to be invoked when at least [min] bytes available * @@ -332,6 +348,9 @@ public fun CoroutineScope.reader( /** * Reads a packet of [packet] bytes from the channel. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.readPacket) + * * @throws EOFException if the channel is closed before the packet is fully read. */ @OptIn(InternalAPI::class) @@ -381,6 +400,9 @@ private const val LF: Byte = '\n'.code.toByte() * Reads a line of UTF-8 characters to the specified [out] buffer. * It recognizes CR, LF and CRLF as a line delimiter. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.readUTF8LineTo) + * * @param out the buffer to write the line to * @param max the maximum number of characters to read * @@ -454,6 +476,9 @@ public val ByteReadChannel.availableForRead: Int * * Suspension occurs when there are not enough bytes available in the channel. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.readFully) + * * @param out the buffer to write to * @param start the index to start writing at * @param end the index to write until @@ -492,6 +517,9 @@ public fun ByteChannel.rethrowCloseCauseIfNeeded() { * * This uses the KMP algorithm for finding the string match using a partial match table. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.readUntil) + * * @see [Knuth–Morris–Pratt algorithm](https://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm) * @param matchString The sequence of bytes to look for. * @param writeChannel The channel to write the read bytes to. @@ -585,6 +613,9 @@ private fun ByteString.toSingleLineString() = /** * Skips the specified [byteString] in the ByteReadChannel if it is found at the current position. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.skipIfFound) + * * @param byteString The ByteString to look for and skip if found. * @return Returns `true` if the byteString was found and skipped, otherwise returns `false`. */ @@ -600,6 +631,9 @@ public suspend fun ByteReadChannel.skipIfFound(byteString: ByteString): Boolean * Retrieves, but does not consume, up to the specified number of bytes from the current position in this * [ByteReadChannel]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.peek) + * * @param count The number of bytes to peek. * @return A [ByteString] containing the bytes that were peeked, or null if unable to peek the specified number of bytes. */ diff --git a/ktor-io/common/src/io/ktor/utils/io/ByteWriteChannel.kt b/ktor-io/common/src/io/ktor/utils/io/ByteWriteChannel.kt index 25e2db0097d..b1afc38f044 100644 --- a/ktor-io/common/src/io/ktor/utils/io/ByteWriteChannel.kt +++ b/ktor-io/common/src/io/ktor/utils/io/ByteWriteChannel.kt @@ -13,6 +13,8 @@ import kotlinx.io.* * * Operations on this channel cannot be invoked concurrently, unless explicitly specified otherwise * in the description. Exceptions are [close] and [flush]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.ByteWriteChannel) */ public interface ByteWriteChannel { diff --git a/ktor-io/common/src/io/ktor/utils/io/ByteWriteChannelOperations.kt b/ktor-io/common/src/io/ktor/utils/io/ByteWriteChannelOperations.kt index 16ffa2d914b..e57cef27868 100644 --- a/ktor-io/common/src/io/ktor/utils/io/ByteWriteChannelOperations.kt +++ b/ktor-io/common/src/io/ktor/utils/io/ByteWriteChannelOperations.kt @@ -32,6 +32,8 @@ public suspend fun ByteWriteChannel.writeInt(value: Int) { /** * Writes a 32-bit floating-point [value] to the current [ByteWriteChannel]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.writeFloat) */ @OptIn(InternalAPI::class) public suspend fun ByteWriteChannel.writeFloat(value: Float) { @@ -42,6 +44,9 @@ public suspend fun ByteWriteChannel.writeFloat(value: Float) { /** * Writes a 64-bit floating-point value to the current [ByteWriteChannel]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.writeDouble) + * * @param value The floating-point value to be written to the channel. */ @OptIn(InternalAPI::class) @@ -192,6 +197,8 @@ public fun CoroutineScope.writer( * specified [desiredSpace] is bigger that the buffer's capacity * or when it is impossible to represent all [desiredSpace] bytes as a single memory range * due to internal implementation reasons. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.write) */ @OptIn(UnsafeIoApi::class, InternalAPI::class, InternalIoApi::class) public suspend fun ByteWriteChannel.write( diff --git a/ktor-io/common/src/io/ktor/utils/io/CloseHookByteWriteChannel.kt b/ktor-io/common/src/io/ktor/utils/io/CloseHookByteWriteChannel.kt index d5925c7b2db..63bb381c224 100644 --- a/ktor-io/common/src/io/ktor/utils/io/CloseHookByteWriteChannel.kt +++ b/ktor-io/common/src/io/ktor/utils/io/CloseHookByteWriteChannel.kt @@ -7,6 +7,9 @@ package io.ktor.utils.io /** * Wraps this channel to execute the provided action when closed using `flushAndClose()`. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.onClose) + * * @param onClose The action to execute when the channel is closed. * @return A new `ByteWriteChannel` that executes the given action upon closure. */ diff --git a/ktor-io/common/src/io/ktor/utils/io/Exceptions.kt b/ktor-io/common/src/io/ktor/utils/io/Exceptions.kt index f5ad6b1dd76..f4cc7a25fb7 100644 --- a/ktor-io/common/src/io/ktor/utils/io/Exceptions.kt +++ b/ktor-io/common/src/io/ktor/utils/io/Exceptions.kt @@ -10,15 +10,21 @@ public typealias CancellationException = kotlinx.coroutines.CancellationExceptio /** * Exception wrapper for causes of byte channel closures. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.ClosedByteChannelException) */ public open class ClosedByteChannelException(cause: Throwable? = null) : IOException(cause?.message, cause) /** * Exception thrown when attempting to write to a closed byte channel. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.ClosedWriteChannelException) */ public class ClosedWriteChannelException(cause: Throwable? = null) : ClosedByteChannelException(cause) /** * Exception thrown when attempting to read from a closed byte channel. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.ClosedReadChannelException) */ public class ClosedReadChannelException(cause: Throwable? = null) : ClosedByteChannelException(cause) diff --git a/ktor-io/common/src/io/ktor/utils/io/JvmSerializable.kt b/ktor-io/common/src/io/ktor/utils/io/JvmSerializable.kt index da568dd2ee0..b55f8a19ea9 100644 --- a/ktor-io/common/src/io/ktor/utils/io/JvmSerializable.kt +++ b/ktor-io/common/src/io/ktor/utils/io/JvmSerializable.kt @@ -4,7 +4,11 @@ package io.ktor.utils.io -/** Alias for `java.io.Serializable` on JVM. Empty interface otherwise. */ +/** + * Alias for `java.io.Serializable` on JVM. Empty interface otherwise. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.JvmSerializable) + */ @InternalAPI public expect interface JvmSerializable diff --git a/ktor-io/common/src/io/ktor/utils/io/SinkByteWriteChannel.kt b/ktor-io/common/src/io/ktor/utils/io/SinkByteWriteChannel.kt index f9ac57f2013..c79acbf035e 100644 --- a/ktor-io/common/src/io/ktor/utils/io/SinkByteWriteChannel.kt +++ b/ktor-io/common/src/io/ktor/utils/io/SinkByteWriteChannel.kt @@ -25,6 +25,8 @@ import kotlinx.io.* * ``` * * Please note that the channel will be buffered even if the sink is not. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.asByteWriteChannel) */ public fun RawSink.asByteWriteChannel(): ByteWriteChannel = SinkByteWriteChannel(this) diff --git a/ktor-io/common/src/io/ktor/utils/io/bits/ByteOrder.kt b/ktor-io/common/src/io/ktor/utils/io/bits/ByteOrder.kt index a57e3f21829..9b2a8d5d1b1 100644 --- a/ktor-io/common/src/io/ktor/utils/io/bits/ByteOrder.kt +++ b/ktor-io/common/src/io/ktor/utils/io/bits/ByteOrder.kt @@ -6,41 +6,57 @@ package io.ktor.utils.io.bits /** * Reverse number's byte order + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.bits.reverseByteOrder) */ public expect fun Short.reverseByteOrder(): Short /** * Reverse number's byte order + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.bits.reverseByteOrder) */ public expect fun Int.reverseByteOrder(): Int /** * Reverse number's byte order + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.bits.reverseByteOrder) */ public expect fun Long.reverseByteOrder(): Long /** * Reverse number's byte order + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.bits.reverseByteOrder) */ public expect fun Float.reverseByteOrder(): Float /** * Reverse number's byte order + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.bits.reverseByteOrder) */ public expect fun Double.reverseByteOrder(): Double /** * Reverse number's byte order + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.bits.reverseByteOrder) */ public fun UShort.reverseByteOrder(): UShort = toShort().reverseByteOrder().toUShort() /** * Reverse number's byte order + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.bits.reverseByteOrder) */ public fun UInt.reverseByteOrder(): UInt = toInt().reverseByteOrder().toUInt() /** * Reverse number's byte order + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.bits.reverseByteOrder) */ public fun ULong.reverseByteOrder(): ULong = toLong().reverseByteOrder().toULong() diff --git a/ktor-io/common/src/io/ktor/utils/io/charsets/Encoding.kt b/ktor-io/common/src/io/ktor/utils/io/charsets/Encoding.kt index 1fd20fcf549..36c047eec6b 100644 --- a/ktor-io/common/src/io/ktor/utils/io/charsets/Encoding.kt +++ b/ktor-io/common/src/io/ktor/utils/io/charsets/Encoding.kt @@ -22,11 +22,15 @@ public expect abstract class Charset { /** * Check if a charset is supported by the current platform. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.charsets.isSupported) */ public expect fun Charsets.isSupported(name: String): Boolean /** * Find a charset by name. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.charsets.forName) */ public expect fun Charsets.forName(name: String): Charset @@ -61,6 +65,8 @@ public expect abstract class CharsetDecoder /** * Decoder's charset it is created for. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.charsets.charset) */ public expect val CharsetDecoder.charset: Charset diff --git a/ktor-io/common/src/io/ktor/utils/io/core/Buffer.kt b/ktor-io/common/src/io/ktor/utils/io/core/Buffer.kt index f54fd85b51d..b72eff24ce9 100644 --- a/ktor-io/common/src/io/ktor/utils/io/core/Buffer.kt +++ b/ktor-io/common/src/io/ktor/utils/io/core/Buffer.kt @@ -14,6 +14,8 @@ import kotlinx.io.Buffer * * Concurrent unsafe: the same memory could be shared between different instances of [Buffer] however you can't * read/write using the same [Buffer] instance from different threads. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.core.Buffer) */ @Deprecated( IO_DEPRECATION_MESSAGE, diff --git a/ktor-io/common/src/io/ktor/utils/io/core/Buffers.kt b/ktor-io/common/src/io/ktor/utils/io/core/Buffers.kt index 73600400a9a..62fb2c7be74 100644 --- a/ktor-io/common/src/io/ktor/utils/io/core/Buffers.kt +++ b/ktor-io/common/src/io/ktor/utils/io/core/Buffers.kt @@ -9,6 +9,8 @@ import kotlinx.io.readByteArray /** * Read the specified number of bytes specified (optional, read all remaining by default) + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.core.readBytes) */ public fun Buffer.readBytes(count: Int = size.toInt()): ByteArray { return readByteArray(count) diff --git a/ktor-io/common/src/io/ktor/utils/io/core/Builder.kt b/ktor-io/common/src/io/ktor/utils/io/core/Builder.kt index 88b25573e99..a4cabf13628 100644 --- a/ktor-io/common/src/io/ktor/utils/io/core/Builder.kt +++ b/ktor-io/common/src/io/ktor/utils/io/core/Builder.kt @@ -9,6 +9,8 @@ import kotlin.contracts.* /** * Build a byte packet in [block] lambda. Creates a temporary builder and releases it in case of failure + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.core.buildPacket) */ @OptIn(ExperimentalContracts::class) public inline fun buildPacket(block: Sink.() -> Unit): Source { diff --git a/ktor-io/common/src/io/ktor/utils/io/core/Copy.kt b/ktor-io/common/src/io/ktor/utils/io/core/Copy.kt index efb8933f388..19ceccde6cb 100644 --- a/ktor-io/common/src/io/ktor/utils/io/core/Copy.kt +++ b/ktor-io/common/src/io/ktor/utils/io/core/Copy.kt @@ -11,6 +11,8 @@ import kotlinx.io.* * Depending on actual input and output implementation it could be zero-copy or copy byte per byte. * All regular types such as [ByteReadPacket], [BytePacketBuilder], [Input] and [Output] * are always optimized so no bytes will be copied. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.core.copyTo) */ @Deprecated( "Use transferTo instead", diff --git a/ktor-io/common/src/io/ktor/utils/io/core/Output.kt b/ktor-io/common/src/io/ktor/utils/io/core/Output.kt index 2d848a4e843..2751a341968 100644 --- a/ktor-io/common/src/io/ktor/utils/io/core/Output.kt +++ b/ktor-io/common/src/io/ktor/utils/io/core/Output.kt @@ -8,6 +8,8 @@ import io.ktor.utils.io.* /** * This shouldn't be implemented directly. Inherit [Output] instead. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.core.Output) */ @Deprecated(IO_DEPRECATION_MESSAGE, replaceWith = ReplaceWith("Sink", "kotlinx.io")) public typealias Output = kotlinx.io.Sink diff --git a/ktor-io/common/src/io/ktor/utils/io/core/Packet.kt b/ktor-io/common/src/io/ktor/utils/io/core/Packet.kt index df9543fed96..5110efce1a1 100644 --- a/ktor-io/common/src/io/ktor/utils/io/core/Packet.kt +++ b/ktor-io/common/src/io/ktor/utils/io/core/Packet.kt @@ -10,6 +10,8 @@ import kotlinx.io.* /** * For streaming input it should be [Input.endOfInput] instead. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.core.isEmpty) */ @Deprecated("Use exhausted() instead", ReplaceWith("exhausted()")) public val Source.isEmpty: Boolean @@ -18,6 +20,8 @@ public val Source.isEmpty: Boolean /** * For streaming input there is no reliable way to detect it without triggering bytes population from the underlying * source. Consider using [Input.endOfInput] or use [ByteReadPacket] instead. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.core.isNotEmpty) */ @Deprecated( "This makes no sense for streaming inputs. Some use-cases are covered by exhausted() method", diff --git a/ktor-io/common/src/io/ktor/utils/io/core/Strings.kt b/ktor-io/common/src/io/ktor/utils/io/core/Strings.kt index 9a1d694f7b9..7a5bf1f115c 100644 --- a/ktor-io/common/src/io/ktor/utils/io/core/Strings.kt +++ b/ktor-io/common/src/io/ktor/utils/io/core/Strings.kt @@ -17,6 +17,8 @@ public fun String.toByteArray(charset: Charset = Charsets.UTF_8): ByteArray { /** * Create an instance of [String] from the specified [bytes] range starting at [offset] and bytes [length] * interpreting characters in the specified [charset]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.core.String) */ @Deprecated( "Use decodeToString instead", @@ -38,6 +40,8 @@ public fun String( /** * Read exactly [n] bytes (consumes all remaining if [n] is not specified but up to [Int.MAX_VALUE] bytes). * Does fail if not enough bytes remaining. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.core.readBytes) */ @Deprecated( "Use readByteArray instead", @@ -53,6 +57,9 @@ public fun Source.readBytes(count: Int): ByteArray = readByteArray(count) /** * Reads at most [max] characters decoding bytes with specified [charset]. Extra character bytes will remain unconsumed + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.core.readText) + * * @return a decoded string */ @OptIn(InternalIoApi::class) @@ -68,6 +75,8 @@ public fun Source.readText(charset: Charset = Charsets.UTF_8, max: Int = Int.MAX /** * Read exactly [n] characters interpreting bytes in the specified [charset]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.core.readTextExact) */ @Deprecated( "Use readTextExactCharacters instead.", @@ -79,6 +88,8 @@ public fun Source.readTextExact(charset: Charset = Charsets.UTF_8, n: Int): Stri /** * Read exactly [charactersCount] characters interpreting bytes in the specified [charset]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.core.readTextExactCharacters) */ public fun Source.readTextExactCharacters(charactersCount: Int, charset: Charset = Charsets.UTF_8): String { val s = readText(charset, charactersCount) @@ -90,6 +101,8 @@ public fun Source.readTextExactCharacters(charactersCount: Int, charset: Charset /** * Writes [text] characters in range \[[fromIndex] .. [toIndex]) with the specified [charset] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.core.writeText) */ public fun Sink.writeText( text: CharSequence, @@ -106,6 +119,8 @@ public fun Sink.writeText( /** * Writes [text] characters in range \[[fromIndex] .. [toIndex]) with the specified [charset] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.core.writeText) */ public fun Sink.writeText( text: CharArray, diff --git a/ktor-io/common/src/io/ktor/utils/io/locks/Synchronized.kt b/ktor-io/common/src/io/ktor/utils/io/locks/Synchronized.kt index aba2894a54a..0661b6702ff 100644 --- a/ktor-io/common/src/io/ktor/utils/io/locks/Synchronized.kt +++ b/ktor-io/common/src/io/ktor/utils/io/locks/Synchronized.kt @@ -14,6 +14,8 @@ import io.ktor.utils.io.* * from the standard library that is available for JVM. * The [SynchronizedObject] superclass gets erased (transformed to Any) on JVM and JS, * with `synchronized` leaving no trace in the code on JS and getting replaced with built-in monitors for locking on JVM. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.locks.SynchronizedObject) */ @InternalAPI public expect open class SynchronizedObject() @@ -24,12 +26,16 @@ public expect open class SynchronizedObject() * [ReentrantLock] is designed for delegation. You write `val lock = reentrantLock()` to construct its instance and * use `lock/tryLock/unlock` functions or `lock.withLock { ... }` extension function similarly to * the way jucl.ReentrantLock is used on JVM. On JVM it is a typealias to the later class, erased on JS. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.locks.ReentrantLock) */ @InternalAPI public expect class ReentrantLock { /** * Acquires the lock. If the lock is already held by another thread, the current thread * will block until it can acquire the lock. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.locks.ReentrantLock.lock) */ public fun lock() @@ -38,6 +44,9 @@ public expect class ReentrantLock { * function will return true. If the lock is already held by another thread, this function * will return false immediately without blocking. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.locks.ReentrantLock.tryLock) + * * @return true if the lock was acquired, false otherwise. */ public fun tryLock(): Boolean @@ -45,12 +54,16 @@ public expect class ReentrantLock { /** * Releases the lock. If the current thread holds the lock, it will be released, allowing * other threads to acquire it. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.locks.ReentrantLock.unlock) */ public fun unlock() } /** * Creates a new [ReentrantLock] instance. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.locks.reentrantLock) */ @InternalAPI public expect fun reentrantLock(): ReentrantLock @@ -66,6 +79,8 @@ public expect fun reentrantLock(): ReentrantLock * // Critical section of code * } * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.locks.withLock) */ @InternalAPI public expect inline fun ReentrantLock.withLock(block: () -> T): T @@ -82,6 +97,8 @@ public expect inline fun ReentrantLock.withLock(block: () -> T): T * // Critical section of code * } * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.locks.synchronized) */ @InternalAPI public expect inline fun synchronized(lock: SynchronizedObject, block: () -> T): T diff --git a/ktor-io/common/src/io/ktor/utils/io/pool/Pool.kt b/ktor-io/common/src/io/ktor/utils/io/pool/Pool.kt index d5e79924433..98d6c367231 100644 --- a/ktor-io/common/src/io/ktor/utils/io/pool/Pool.kt +++ b/ktor-io/common/src/io/ktor/utils/io/pool/Pool.kt @@ -9,27 +9,37 @@ import kotlinx.atomicfu.* public interface ObjectPool : AutoCloseable { /** * Pool capacity + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.pool.ObjectPool.capacity) */ public val capacity: Int /** * borrow an instance. Pool can recycle an old instance or create a new one + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.pool.ObjectPool.borrow) */ public fun borrow(): T /** * Recycle an instance. Should be recycled what was borrowed before otherwise could fail + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.pool.ObjectPool.recycle) */ public fun recycle(instance: T) /** * Dispose the whole pool. None of borrowed objects could be used after the pool gets disposed * otherwise it can result in undefined behaviour + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.pool.ObjectPool.dispose) */ public fun dispose() /** * Does pool dispose + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.pool.ObjectPool.close) */ override fun close() { dispose() @@ -38,6 +48,8 @@ public interface ObjectPool : AutoCloseable { /** * A pool implementation of zero capacity that always creates new instances + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.pool.NoPoolImpl) */ public abstract class NoPoolImpl : ObjectPool { override val capacity: Int @@ -50,6 +62,8 @@ public abstract class NoPoolImpl : ObjectPool { /** * A pool that produces at most one instance + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.pool.SingleInstancePool) */ public abstract class SingleInstancePool : ObjectPool { private val borrowed = atomic(0) @@ -111,10 +125,14 @@ public abstract class SingleInstancePool : ObjectPool { /** * Default object pool implementation. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.pool.DefaultPool) */ public expect abstract class DefaultPool(capacity: Int) : ObjectPool { /** * Pool capacity. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.pool.DefaultPool.capacity) */ final override val capacity: Int @@ -147,6 +165,8 @@ public expect abstract class DefaultPool(capacity: Int) : ObjectPool /** * Borrows and instance of [T] from the pool, invokes [block] with it and finally recycles it + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.pool.useBorrowed) */ @Deprecated("Use useInstance instead", ReplaceWith("useInstance(block)")) public inline fun ObjectPool.useBorrowed(block: (T) -> R): R { @@ -155,6 +175,8 @@ public inline fun ObjectPool.useBorrowed(block: (T) -> R): R { /** * Borrows and instance of [T] from the pool, invokes [block] with it and finally recycles it + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.pool.useInstance) */ public inline fun ObjectPool.useInstance(block: (T) -> R): R { val instance = borrow() diff --git a/ktor-io/js/src/io/ktor/utils/io/charsets/Charset.js.kt b/ktor-io/js/src/io/ktor/utils/io/charsets/Charset.js.kt index 12f67774c8f..398686b1c51 100644 --- a/ktor-io/js/src/io/ktor/utils/io/charsets/Charset.js.kt +++ b/ktor-io/js/src/io/ktor/utils/io/charsets/Charset.js.kt @@ -9,11 +9,15 @@ import org.khronos.webgl.Int8Array /** * Find a charset by name. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.charsets.forName) */ public actual fun Charsets.forName(name: String): Charset = Charset.forName(name) /** * Check if a charset is supported by the current platform. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.charsets.isSupported) */ public actual fun Charsets.isSupported(name: String): Boolean = Charset.isSupported(name) diff --git a/ktor-io/jsAndWasmShared/src/io/ktor/utils/io/bits/ByteOrderJs.kt b/ktor-io/jsAndWasmShared/src/io/ktor/utils/io/bits/ByteOrderJs.kt index 883fb2209b2..6b773b80692 100644 --- a/ktor-io/jsAndWasmShared/src/io/ktor/utils/io/bits/ByteOrderJs.kt +++ b/ktor-io/jsAndWasmShared/src/io/ktor/utils/io/bits/ByteOrderJs.kt @@ -8,26 +8,36 @@ package io.ktor.utils.io.bits /** * Reverse number's byte order + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.bits.reverseByteOrder) */ public actual fun Short.reverseByteOrder(): Short = swap(this) /** * Reverse number's byte order + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.bits.reverseByteOrder) */ public actual fun Int.reverseByteOrder(): Int = swap(this) /** * Reverse number's byte order + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.bits.reverseByteOrder) */ public actual fun Long.reverseByteOrder(): Long = swap(this) /** * Reverse number's byte order + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.bits.reverseByteOrder) */ public actual fun Float.reverseByteOrder(): Float = swap(this) /** * Reverse number's byte order + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.bits.reverseByteOrder) */ public actual fun Double.reverseByteOrder(): Double = swap(this) diff --git a/ktor-io/jsAndWasmShared/src/io/ktor/utils/io/locks/Synchronized.kt b/ktor-io/jsAndWasmShared/src/io/ktor/utils/io/locks/Synchronized.kt index 4998ae5c5a5..7c601efe62c 100644 --- a/ktor-io/jsAndWasmShared/src/io/ktor/utils/io/locks/Synchronized.kt +++ b/ktor-io/jsAndWasmShared/src/io/ktor/utils/io/locks/Synchronized.kt @@ -14,6 +14,8 @@ import io.ktor.utils.io.* * from the standard library that is available for JVM. * The [SynchronizedObject] superclass gets erased (transformed to Any) on JVM and JS, * with `synchronized` leaving no trace in the code on JS and getting replaced with built-in monitors for locking on JVM. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.locks.SynchronizedObject) */ @InternalAPI public actual typealias SynchronizedObject = Any @@ -24,6 +26,8 @@ public actual typealias SynchronizedObject = Any * [ReentrantLock] is designed for delegation. You write `val lock = reentrantLock()` to construct its instance and * use `lock/tryLock/unlock` functions or `lock.withLock { ... }` extension function similarly to * the way jucl.ReentrantLock is used on JVM. On JVM it is a typealias to the later class, erased on JS. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.locks.ReentrantLock) */ @Suppress("NOTHING_TO_INLINE") @InternalAPI @@ -35,6 +39,8 @@ public actual class ReentrantLock { /** * Creates a new [ReentrantLock] instance. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.locks.Lock) */ @JsName(REENTRANT_LOCK) @InternalAPI @@ -42,6 +48,8 @@ public val Lock: ReentrantLock = ReentrantLock() /** * Creates a new [ReentrantLock] instance. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.locks.reentrantLock) */ @Suppress("NOTHING_TO_INLINE") @InternalAPI @@ -58,6 +66,8 @@ public actual inline fun reentrantLock(): ReentrantLock = Lock * // Critical section of code * } * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.locks.withLock) */ @InternalAPI public actual inline fun ReentrantLock.withLock(block: () -> T): T = block() @@ -74,6 +84,8 @@ public actual inline fun ReentrantLock.withLock(block: () -> T): T = block() * // Critical section of code * } * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.locks.synchronized) */ @InternalAPI public actual inline fun synchronized(lock: SynchronizedObject, block: () -> T): T = block() diff --git a/ktor-io/jvm/src/io/ktor/utils/io/ByteReadChannelOperations.jvm.kt b/ktor-io/jvm/src/io/ktor/utils/io/ByteReadChannelOperations.jvm.kt index 11b9dce6262..3b5faddd1b6 100644 --- a/ktor-io/jvm/src/io/ktor/utils/io/ByteReadChannelOperations.jvm.kt +++ b/ktor-io/jvm/src/io/ktor/utils/io/ByteReadChannelOperations.jvm.kt @@ -13,6 +13,8 @@ import java.nio.channels.* /** * Creates a channel for reading from the specified byte buffer. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.ByteReadChannel) */ public fun ByteReadChannel(content: ByteBuffer): ByteReadChannel { val packet = buildPacket { @@ -26,6 +28,9 @@ public fun ByteReadChannel(content: ByteBuffer): ByteReadChannel { * Reads bytes from the channel and writes them to the buffer up to its limit. * If the channel's read buffer is exhausted, it suspends until there are bytes available. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.readAvailable) + * * @param buffer the buffer to write the read bytes into * @return the number of bytes read and written to the buffer or -1 if the channel is closed */ @@ -51,6 +56,9 @@ public fun ByteString(buffer: ByteBuffer): ByteString { * Copying to a non-blocking channel requires selection and not supported. * It is suspended if no data are available in a byte channel but may block if destination NIO channel blocks. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.copyTo) + * * @return number of bytes copied */ public suspend fun ByteReadChannel.copyTo(channel: WritableByteChannel, limit: Long = Long.MAX_VALUE): Long { @@ -130,6 +138,9 @@ public suspend fun ByteReadChannel.readFully(buffer: ByteBuffer) { * eg: it could be 4 bytes available for read but the provided byte buffer could have only 2 available bytes: * in this case you have to invoke read again (with decreased [min] accordingly). * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.readAvailable) + * * @param min amount of bytes available for read, should be positive * @param block to be invoked when at least [min] bytes available * @@ -168,6 +179,9 @@ public fun ByteReadChannel.readAvailable(block: (ByteBuffer) -> Int): Int { * it should restore it before return. It is not recommended to access any bytes of the buffer outside of the * provided byte range [position(); limit()) as there could be any garbage or incomplete data. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.read) + * * @param min amount of bytes available for read, should be positive or zero * @param consumer to be invoked when at least [min] bytes available for read */ diff --git a/ktor-io/jvm/src/io/ktor/utils/io/ByteWriteChannelOperations.jvm.kt b/ktor-io/jvm/src/io/ktor/utils/io/ByteWriteChannelOperations.jvm.kt index 7ef27f8ab2f..7301bbf6be0 100644 --- a/ktor-io/jvm/src/io/ktor/utils/io/ByteWriteChannelOperations.jvm.kt +++ b/ktor-io/jvm/src/io/ktor/utils/io/ByteWriteChannelOperations.jvm.kt @@ -40,6 +40,9 @@ public suspend fun ByteWriteChannel.write(min: Int = 1, block: (buffer: ByteBuff * eg: it could be 4 bytes available for write but the provided byte buffer could have only 2 remaining bytes: * in this case you have to invoke write again (with decreased [min] accordingly). * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.writeAvailable) + * * @param min amount of bytes available for write, should be positive * @param block to be invoked when at least [min] bytes free capacity available * diff --git a/ktor-io/jvm/src/io/ktor/utils/io/LookAheadSession.kt b/ktor-io/jvm/src/io/ktor/utils/io/LookAheadSession.kt index 3c2f94f01af..cdf61fc4561 100644 --- a/ktor-io/jvm/src/io/ktor/utils/io/LookAheadSession.kt +++ b/ktor-io/jvm/src/io/ktor/utils/io/LookAheadSession.kt @@ -13,6 +13,9 @@ public typealias LookAheadSession = LookAheadSuspendSession public class LookAheadSuspendSession(private val channel: ByteReadChannel) { /** * Request byte buffer range skipping [skip] bytes and [atLeast] bytes length + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.LookAheadSuspendSession.request) + * * @return byte buffer for the requested range or null if it is impossible to provide such a buffer * * There are the following reasons for this function to return `null`: diff --git a/ktor-io/jvm/src/io/ktor/utils/io/bits/ByteOrderJvm.kt b/ktor-io/jvm/src/io/ktor/utils/io/bits/ByteOrderJvm.kt index 29c43fcc161..2da9811cc7e 100644 --- a/ktor-io/jvm/src/io/ktor/utils/io/bits/ByteOrderJvm.kt +++ b/ktor-io/jvm/src/io/ktor/utils/io/bits/ByteOrderJvm.kt @@ -4,24 +4,32 @@ package io.ktor.utils.io.bits /** * Reverse number's byte order + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.bits.reverseByteOrder) */ @Suppress("NOTHING_TO_INLINE") public actual inline fun Short.reverseByteOrder(): Short = java.lang.Short.reverseBytes(this) /** * Reverse number's byte order + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.bits.reverseByteOrder) */ @Suppress("NOTHING_TO_INLINE") public actual inline fun Int.reverseByteOrder(): Int = Integer.reverseBytes(this) /** * Reverse number's byte order + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.bits.reverseByteOrder) */ @Suppress("NOTHING_TO_INLINE") public actual inline fun Long.reverseByteOrder(): Long = java.lang.Long.reverseBytes(this) /** * Reverse number's byte order + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.bits.reverseByteOrder) */ @Suppress("NOTHING_TO_INLINE") public actual inline fun Float.reverseByteOrder(): Float = @@ -33,6 +41,8 @@ public actual inline fun Float.reverseByteOrder(): Float = /** * Reverse number's byte order + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.bits.reverseByteOrder) */ @Suppress("NOTHING_TO_INLINE") public actual inline fun Double.reverseByteOrder(): Double = diff --git a/ktor-io/jvm/src/io/ktor/utils/io/charsets/CharsetJVM.kt b/ktor-io/jvm/src/io/ktor/utils/io/charsets/CharsetJVM.kt index 9d6a048c2f9..29e97f37109 100644 --- a/ktor-io/jvm/src/io/ktor/utils/io/charsets/CharsetJVM.kt +++ b/ktor-io/jvm/src/io/ktor/utils/io/charsets/CharsetJVM.kt @@ -14,11 +14,15 @@ public actual typealias Charset = java.nio.charset.Charset /** * Find a charset by name. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.charsets.forName) */ public actual fun Charsets.forName(name: String): Charset = Charset.forName(name) /** * Check if a charset is supported by the current platform. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.charsets.isSupported) */ public actual fun Charsets.isSupported(name: String): Boolean = Charset.isSupported(name) diff --git a/ktor-io/jvm/src/io/ktor/utils/io/core/BufferPrimitivesJvm.kt b/ktor-io/jvm/src/io/ktor/utils/io/core/BufferPrimitivesJvm.kt index 57efee9506c..40472e58c81 100644 --- a/ktor-io/jvm/src/io/ktor/utils/io/core/BufferPrimitivesJvm.kt +++ b/ktor-io/jvm/src/io/ktor/utils/io/core/BufferPrimitivesJvm.kt @@ -10,6 +10,8 @@ import java.nio.* /** * Write [source] buffer content moving its position. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.core.writeByteBuffer) */ @Deprecated( "[writeByteBuffer] is deprecated. Consider using [transferFrom] instead", diff --git a/ktor-io/jvm/src/io/ktor/utils/io/jvm/javaio/Blocking.kt b/ktor-io/jvm/src/io/ktor/utils/io/jvm/javaio/Blocking.kt index ee93471d092..c0547580a2e 100644 --- a/ktor-io/jvm/src/io/ktor/utils/io/jvm/javaio/Blocking.kt +++ b/ktor-io/jvm/src/io/ktor/utils/io/jvm/javaio/Blocking.kt @@ -12,6 +12,8 @@ import kotlin.math.* /** * Create blocking [java.io.InputStream] for this channel that does block every time the channel suspends at read * Similar to do reading in [runBlocking] however you can pass it to regular blocking API + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.jvm.javaio.toInputStream) */ @Suppress("UNUSED_PARAMETER") @OptIn(InternalAPI::class) @@ -49,6 +51,8 @@ public fun ByteReadChannel.toInputStream(parent: Job? = null): InputStream = obj /** * Create blocking [java.io.OutputStream] for this channel that does block every time the channel suspends at write * Similar to do reading in [runBlocking] however you can pass it to regular blocking API + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.jvm.javaio.toOutputStream) */ public fun ByteWriteChannel.toOutputStream(): OutputStream = object : OutputStream() { override fun write(b: Int) { diff --git a/ktor-io/jvm/src/io/ktor/utils/io/jvm/javaio/Reading.kt b/ktor-io/jvm/src/io/ktor/utils/io/jvm/javaio/Reading.kt index c96e2acf0e8..ab18e053a6b 100644 --- a/ktor-io/jvm/src/io/ktor/utils/io/jvm/javaio/Reading.kt +++ b/ktor-io/jvm/src/io/ktor/utils/io/jvm/javaio/Reading.kt @@ -20,6 +20,8 @@ import kotlin.coroutines.* * Open a channel and launch a coroutine to copy bytes from the input stream to the channel. * Please note that it may block your async code when started on [Dispatchers.Unconfined] * since [InputStream] is blocking on it's nature + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.jvm.javaio.toByteReadChannel) */ @Suppress("UNUSED_PARAMETER") public fun InputStream.toByteReadChannel( @@ -31,6 +33,8 @@ public fun InputStream.toByteReadChannel( * Open a channel and launch a coroutine to copy bytes from the input stream to the channel. * Please note that it may block your async code when started on [Dispatchers.Unconfined] * since [InputStream] is blocking on it's nature + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.jvm.javaio.toByteReadChannel) */ @Suppress("UNUSED_PARAMETER") @JvmName("toByteReadChannelWithArrayPool") diff --git a/ktor-io/jvm/src/io/ktor/utils/io/jvm/javaio/Writing.kt b/ktor-io/jvm/src/io/ktor/utils/io/jvm/javaio/Writing.kt index be84138613e..c737fd9cf6a 100644 --- a/ktor-io/jvm/src/io/ktor/utils/io/jvm/javaio/Writing.kt +++ b/ktor-io/jvm/src/io/ktor/utils/io/jvm/javaio/Writing.kt @@ -12,6 +12,9 @@ import java.io.* * Copies up to [limit] bytes from [this] byte channel to [out] stream suspending on read channel * and blocking on output * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.jvm.javaio.copyTo) + * * @return number of bytes copied */ @OptIn(InternalAPI::class, InternalIoApi::class) diff --git a/ktor-io/jvm/src/io/ktor/utils/io/jvm/nio/Reading.kt b/ktor-io/jvm/src/io/ktor/utils/io/jvm/nio/Reading.kt index c33fa968eb8..7dee05549f5 100644 --- a/ktor-io/jvm/src/io/ktor/utils/io/jvm/nio/Reading.kt +++ b/ktor-io/jvm/src/io/ktor/utils/io/jvm/nio/Reading.kt @@ -17,6 +17,9 @@ import kotlin.coroutines.* /** * Converts a [ReadableByteChannel] to a [ByteReadChannel], enabling asynchronous reading of bytes. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.jvm.nio.toByteReadChannel) + * * @param context the [CoroutineContext] to execute the read operation. Defaults to [Dispatchers.IO]. * @return a [ByteReadChannel] for reading bytes asynchronously from the given [ReadableByteChannel]. */ @@ -30,6 +33,9 @@ public fun ReadableByteChannel.toByteReadChannel( * This extension function wraps the given [ReadableByteChannel] into a [RawSource], * enabling efficient reading of bytes from the channel as a source of data. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.jvm.nio.asSource) + * * @return a [RawSource] representation of the [ReadableByteChannel]. */ public fun ReadableByteChannel.asSource(): RawSource = diff --git a/ktor-io/jvm/src/io/ktor/utils/io/locks/Synchronized.kt b/ktor-io/jvm/src/io/ktor/utils/io/locks/Synchronized.kt index e0b67e7bd45..52159584a4a 100644 --- a/ktor-io/jvm/src/io/ktor/utils/io/locks/Synchronized.kt +++ b/ktor-io/jvm/src/io/ktor/utils/io/locks/Synchronized.kt @@ -14,6 +14,8 @@ import io.ktor.utils.io.InternalAPI * from the standard library that is available for JVM. * The [SynchronizedObject] superclass gets erased (transformed to Any) on JVM and JS, * with `synchronized` leaving no trace in the code on JS and getting replaced with built-in monitors for locking on JVM. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.locks.SynchronizedObject) */ @InternalAPI public actual typealias SynchronizedObject = Any @@ -24,12 +26,16 @@ public actual typealias SynchronizedObject = Any * [ReentrantLock] is designed for delegation. You write `val lock = reentrantLock()` to construct its instance and * use `lock/tryLock/unlock` functions or `lock.withLock { ... }` extension function similarly to * the way jucl.ReentrantLock is used on JVM. On JVM it is a typealias to the later class, erased on JS. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.locks.ReentrantLock) */ @InternalAPI public actual typealias ReentrantLock = java.util.concurrent.locks.ReentrantLock /** * Creates a new [ReentrantLock] instance. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.locks.reentrantLock) */ @InternalAPI public actual fun reentrantLock(): ReentrantLock = ReentrantLock() @@ -45,6 +51,8 @@ public actual fun reentrantLock(): ReentrantLock = ReentrantLock() * // Critical section of code * } * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.locks.withLock) */ @InternalAPI public actual inline fun ReentrantLock.withLock(block: () -> T): T { @@ -68,6 +76,8 @@ public actual inline fun ReentrantLock.withLock(block: () -> T): T { * // Critical section of code * } * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.locks.synchronized) */ @InternalAPI public actual inline fun synchronized(lock: SynchronizedObject, block: () -> T): T = diff --git a/ktor-io/jvm/src/io/ktor/utils/io/streams/Streams.kt b/ktor-io/jvm/src/io/ktor/utils/io/streams/Streams.kt index 4c04dcefc72..d68c8d5cd69 100644 --- a/ktor-io/jvm/src/io/ktor/utils/io/streams/Streams.kt +++ b/ktor-io/jvm/src/io/ktor/utils/io/streams/Streams.kt @@ -50,5 +50,7 @@ public fun InputStream.readPacketAtLeast(min: Int = 1): Source { * * All operations on the [ByteWriteChannel] are buffered: the underlying [OutputStream] will be receiving bytes * when the [ByteWriteChannel.flush] happens. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.streams.asByteWriteChannel) */ public fun OutputStream.asByteWriteChannel(): ByteWriteChannel = asSink().asByteWriteChannel() diff --git a/ktor-io/jvmAndPosix/src/io/ktor/utils/io/ByteReadChannelSource.kt b/ktor-io/jvmAndPosix/src/io/ktor/utils/io/ByteReadChannelSource.kt index 318391df1d4..6bff5b70cda 100644 --- a/ktor-io/jvmAndPosix/src/io/ktor/utils/io/ByteReadChannelSource.kt +++ b/ktor-io/jvmAndPosix/src/io/ktor/utils/io/ByteReadChannelSource.kt @@ -14,6 +14,9 @@ import kotlinx.io.RawSource * * Please note: the [RawSource] produced by this operation uses [runBlocking] to wait for the content to be available. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.asSource) + * * @return a `RawSource` implementation that wraps the `ByteReadChannel`. */ public fun ByteReadChannel.asSource(): RawSource = ByteReadChannelSource(this) diff --git a/ktor-io/jvmAndPosix/src/io/ktor/utils/io/ByteWriteChannelSink.kt b/ktor-io/jvmAndPosix/src/io/ktor/utils/io/ByteWriteChannelSink.kt index 6b52f537db6..6713c243117 100644 --- a/ktor-io/jvmAndPosix/src/io/ktor/utils/io/ByteWriteChannelSink.kt +++ b/ktor-io/jvmAndPosix/src/io/ktor/utils/io/ByteWriteChannelSink.kt @@ -13,6 +13,8 @@ import kotlinx.io.RawSink * Converts the current `ByteWriteChannel` instance into a `RawSink`. * * Please note: the [RawSink] produced by this operation uses [runBlocking] to flush the content. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.asSink) */ public fun ByteWriteChannel.asSink(): RawSink = ByteWriteChannelSink(this) diff --git a/ktor-io/posix/src/io/ktor/utils/io/ByteReadChannelOperations.posix.kt b/ktor-io/posix/src/io/ktor/utils/io/ByteReadChannelOperations.posix.kt index 05dec955579..2ba4e744dba 100644 --- a/ktor-io/posix/src/io/ktor/utils/io/ByteReadChannelOperations.posix.kt +++ b/ktor-io/posix/src/io/ktor/utils/io/ByteReadChannelOperations.posix.kt @@ -8,6 +8,9 @@ import kotlinx.cinterop.* /** * Reads all available bytes to [dst] buffer and returns immediately or suspends if no bytes available + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.readAvailable) + * * @return number of bytes were read or `-1` if the channel has been closed */ @OptIn(ExperimentalForeignApi::class, InternalAPI::class) diff --git a/ktor-io/posix/src/io/ktor/utils/io/bits/ByteOrderNative.kt b/ktor-io/posix/src/io/ktor/utils/io/bits/ByteOrderNative.kt index 883fb2209b2..6b773b80692 100644 --- a/ktor-io/posix/src/io/ktor/utils/io/bits/ByteOrderNative.kt +++ b/ktor-io/posix/src/io/ktor/utils/io/bits/ByteOrderNative.kt @@ -8,26 +8,36 @@ package io.ktor.utils.io.bits /** * Reverse number's byte order + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.bits.reverseByteOrder) */ public actual fun Short.reverseByteOrder(): Short = swap(this) /** * Reverse number's byte order + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.bits.reverseByteOrder) */ public actual fun Int.reverseByteOrder(): Int = swap(this) /** * Reverse number's byte order + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.bits.reverseByteOrder) */ public actual fun Long.reverseByteOrder(): Long = swap(this) /** * Reverse number's byte order + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.bits.reverseByteOrder) */ public actual fun Float.reverseByteOrder(): Float = swap(this) /** * Reverse number's byte order + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.bits.reverseByteOrder) */ public actual fun Double.reverseByteOrder(): Double = swap(this) diff --git a/ktor-io/posix/src/io/ktor/utils/io/charsets/CharsetNative.kt b/ktor-io/posix/src/io/ktor/utils/io/charsets/CharsetNative.kt index 8f73bdce25a..32a04e528c2 100644 --- a/ktor-io/posix/src/io/ktor/utils/io/charsets/CharsetNative.kt +++ b/ktor-io/posix/src/io/ktor/utils/io/charsets/CharsetNative.kt @@ -8,11 +8,15 @@ import io.ktor.utils.io.core.* /** * Find a charset by name. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.charsets.forName) */ public actual fun Charsets.forName(name: String): Charset = Charset.forName(name) /** * Check if a charset is supported by the current platform. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.charsets.isSupported) */ public actual fun Charsets.isSupported(name: String): Boolean = Charset.isSupported(name) diff --git a/ktor-io/posix/src/io/ktor/utils/io/errors/PosixErrors.kt b/ktor-io/posix/src/io/ktor/utils/io/errors/PosixErrors.kt index 17f47d6f849..ece25129909 100644 --- a/ktor-io/posix/src/io/ktor/utils/io/errors/PosixErrors.kt +++ b/ktor-io/posix/src/io/ktor/utils/io/errors/PosixErrors.kt @@ -31,6 +31,9 @@ private val KnownPosixErrors = mapOf( /** * Represents a POSIX error. Could be thrown when a POSIX function returns error code. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.errors.PosixException) + * * @property errno error code that caused this exception * @property message error text */ @@ -72,6 +75,9 @@ public sealed class PosixException(public val errno: Int, message: String) : Exc * Create the corresponding instance of PosixException * with error message provided by the underlying POSIX implementation. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.errors.PosixException.Companion.forErrno) + * * @param errno error code returned by [posix.platform.errno] * @param posixFunctionName optional function name to be included to the exception message * @return an instance of [PosixException] or it's subtype diff --git a/ktor-io/posix/src/io/ktor/utils/io/locks/Synchronized.kt b/ktor-io/posix/src/io/ktor/utils/io/locks/Synchronized.kt index c6693c549a5..5281716d944 100644 --- a/ktor-io/posix/src/io/ktor/utils/io/locks/Synchronized.kt +++ b/ktor-io/posix/src/io/ktor/utils/io/locks/Synchronized.kt @@ -21,6 +21,8 @@ import kotlin.native.internal.NativePtr * from the standard library that is available for JVM. * The [SynchronizedObject] superclass gets erased (transformed to Any) on JVM and JS, * with `synchronized` leaving no trace in the code on JS and getting replaced with built-in monitors for locking on JVM. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.locks.SynchronizedObject) */ @OptIn(ExperimentalForeignApi::class) @InternalAPI @@ -31,6 +33,8 @@ public actual open class SynchronizedObject { /** * Acquires the lock. If the lock is already held by another thread, the current thread * will block until it can acquire the lock. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.locks.SynchronizedObject.lock) */ public fun lock() { val currentThreadId = pthread_self()!! @@ -110,6 +114,9 @@ public actual open class SynchronizedObject { * function will return true. If the lock is already held by another thread, this function * will return false immediately without blocking. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.locks.SynchronizedObject.tryLock) + * * @return true if the lock was acquired, false otherwise. */ public fun tryLock(): Boolean { @@ -143,6 +150,8 @@ public actual open class SynchronizedObject { /** * Releases the lock. If the current thread holds the lock, it will be released, allowing * other threads to acquire it. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.locks.SynchronizedObject.unlock) */ public fun unlock() { val currentThreadId = pthread_self() @@ -238,12 +247,16 @@ public actual open class SynchronizedObject { * [ReentrantLock] is designed for delegation. You write `val lock = reentrantLock()` to construct its instance and * use `lock/tryLock/unlock` functions or `lock.withLock { ... }` extension function similarly to * the way jucl.ReentrantLock is used on JVM. On JVM it is a typealias to the later class, erased on JS. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.locks.ReentrantLock) */ @InternalAPI public actual typealias ReentrantLock = SynchronizedObject /** * Creates a new [ReentrantLock] instance. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.locks.reentrantLock) */ @InternalAPI public actual fun reentrantLock(): ReentrantLock = ReentrantLock() @@ -259,6 +272,8 @@ public actual fun reentrantLock(): ReentrantLock = ReentrantLock() * // Critical section of code * } * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.locks.withLock) */ @InternalAPI public actual inline fun ReentrantLock.withLock(block: () -> T): T { @@ -282,6 +297,8 @@ public actual inline fun ReentrantLock.withLock(block: () -> T): T { * // Critical section of code * } * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.locks.synchronized) */ @InternalAPI public actual inline fun synchronized(lock: SynchronizedObject, block: () -> T): T { diff --git a/ktor-io/wasmJs/src/io/ktor/utils/io/charsets/Encoding.wasmJs.kt b/ktor-io/wasmJs/src/io/ktor/utils/io/charsets/Encoding.wasmJs.kt index 093f2065938..2209333e930 100644 --- a/ktor-io/wasmJs/src/io/ktor/utils/io/charsets/Encoding.wasmJs.kt +++ b/ktor-io/wasmJs/src/io/ktor/utils/io/charsets/Encoding.wasmJs.kt @@ -38,11 +38,15 @@ public actual abstract class Charset(internal val _name: String) { /** * Check if a charset is supported by the current platform. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.charsets.isSupported) */ public actual fun Charsets.isSupported(name: String): Boolean = Charset.isSupported(name) /** * Find a charset by name. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.charsets.forName) */ public actual fun Charsets.forName(name: String): Charset = Charset.forName(name) @@ -56,6 +60,8 @@ public actual val CharsetEncoder.charset: Charset /** * Decoder's charset it is created for. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.utils.io.charsets.charset) */ public actual val CharsetDecoder.charset: Charset get() = _charset diff --git a/ktor-network/common/src/io/ktor/network/selector/Selectable.kt b/ktor-network/common/src/io/ktor/network/selector/Selectable.kt index 5d035b5c8ae..0732511fa7e 100644 --- a/ktor-network/common/src/io/ktor/network/selector/Selectable.kt +++ b/ktor-network/common/src/io/ktor/network/selector/Selectable.kt @@ -8,6 +8,8 @@ import kotlinx.coroutines.* /** * A selectable entity with selectable NIO [channel], [interestedOps] subscriptions. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.selector.Selectable) */ public expect interface Selectable diff --git a/ktor-network/common/src/io/ktor/network/selector/SelectorManagerCommon.kt b/ktor-network/common/src/io/ktor/network/selector/SelectorManagerCommon.kt index 85fa219ca5f..3f4900dbd9c 100644 --- a/ktor-network/common/src/io/ktor/network/selector/SelectorManagerCommon.kt +++ b/ktor-network/common/src/io/ktor/network/selector/SelectorManagerCommon.kt @@ -10,6 +10,8 @@ import kotlin.coroutines.* /** * Creates the selector manager for current platform. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.selector.SelectorManager) */ public expect fun SelectorManager( dispatcher: CoroutineContext = EmptyCoroutineContext @@ -17,10 +19,14 @@ public expect fun SelectorManager( /** * SelectorManager interface allows [Selectable] wait for [SelectInterest]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.selector.SelectorManager) */ public expect interface SelectorManager : CoroutineScope, Closeable { /** * Notifies the selector that selectable has been closed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.selector.SelectorManager.notifyClosed) */ public fun notifyClosed(selectable: Selectable) @@ -32,6 +38,8 @@ public expect interface SelectorManager : CoroutineScope, Closeable { * select for different interests for the same selectable simultaneously. * In other words you can select for read and write at the same time but should never * try to read twice for the same selectable. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.selector.SelectorManager.select) */ public suspend fun select(selectable: Selectable, interest: SelectInterest) @@ -40,6 +48,8 @@ public expect interface SelectorManager : CoroutineScope, Closeable { /** * Select interest kind. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.selector.SelectInterest) */ public expect enum class SelectInterest { READ, diff --git a/ktor-network/common/src/io/ktor/network/sockets/Builders.kt b/ktor-network/common/src/io/ktor/network/sockets/Builders.kt index 81c4a1306c1..cd5bdd87ef8 100644 --- a/ktor-network/common/src/io/ktor/network/sockets/Builders.kt +++ b/ktor-network/common/src/io/ktor/network/sockets/Builders.kt @@ -8,11 +8,15 @@ import io.ktor.network.selector.* /** * Start building a socket + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.aSocket) */ public fun aSocket(selector: SelectorManager): SocketBuilder = SocketBuilder(selector, SocketOptions.create()) /** * Socket builder + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.SocketBuilder) */ public class SocketBuilder internal constructor( private val selector: SelectorManager, @@ -21,17 +25,23 @@ public class SocketBuilder internal constructor( /** * Build TCP socket. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.SocketBuilder.tcp) */ public fun tcp(): TcpSocketBuilder = TcpSocketBuilder(selector, options.peer()) /** * Build UDP socket. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.SocketBuilder.udp) */ public fun udp(): UDPSocketBuilder = UDPSocketBuilder(selector, options.peer().udp()) } /** * Set TCP_NODELAY socket option to disable the Nagle algorithm. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.tcpNoDelay) */ @Deprecated("noDelay is true by default", ReplaceWith("this")) public fun > T.tcpNoDelay(): T { @@ -44,15 +54,21 @@ public fun > T.tcpNoDelay(): T { /** * Represent a configurable socket + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.Configurable) */ public interface Configurable, Options : SocketOptions> { /** * Current socket options + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.Configurable.options) */ public var options: Options /** * Configure socket options in [block] function + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.Configurable.configure) */ public fun configure(block: Options.() -> Unit): T { @Suppress("UNCHECKED_CAST") diff --git a/ktor-network/common/src/io/ktor/network/sockets/Datagram.kt b/ktor-network/common/src/io/ktor/network/sockets/Datagram.kt index ea916b86f9f..f5719f79d64 100644 --- a/ktor-network/common/src/io/ktor/network/sockets/Datagram.kt +++ b/ktor-network/common/src/io/ktor/network/sockets/Datagram.kt @@ -12,6 +12,9 @@ internal const val MAX_DATAGRAM_SIZE = 65535 /** * UDP datagram with [packet] content targeted to [address] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.Datagram) + * * @property packet content * @property address to send to */ @@ -28,15 +31,21 @@ public class Datagram( /** * A channel for sending datagrams + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.DatagramWriteChannel) */ public interface DatagramWriteChannel { /** * Datagram outgoing channel. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.DatagramWriteChannel.outgoing) */ public val outgoing: SendChannel /** * Send datagram. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.DatagramWriteChannel.send) */ public suspend fun send(datagram: Datagram) { outgoing.send(datagram) @@ -45,31 +54,43 @@ public interface DatagramWriteChannel { /** * A channel for receiving datagrams + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.DatagramReadChannel) */ public interface DatagramReadChannel { /** * Incoming datagrams channel + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.DatagramReadChannel.incoming) */ public val incoming: ReceiveChannel /** * Receive a datagram. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.DatagramReadChannel.receive) */ public suspend fun receive(): Datagram = incoming.receive() } /** * A channel for sending and receiving datagrams + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.DatagramReadWriteChannel) */ public interface DatagramReadWriteChannel : DatagramReadChannel, DatagramWriteChannel /** * Represents a bound datagram socket + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.BoundDatagramSocket) */ public interface BoundDatagramSocket : ASocket, ABoundSocket, DatagramReadWriteChannel /** * Represents a connected datagram socket. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.ConnectedDatagramSocket) */ public interface ConnectedDatagramSocket : ASocket, ABoundSocket, AConnectedSocket, DatagramReadWriteChannel diff --git a/ktor-network/common/src/io/ktor/network/sockets/SocketAddress.kt b/ktor-network/common/src/io/ktor/network/sockets/SocketAddress.kt index d7df452da83..41f1822e819 100644 --- a/ktor-network/common/src/io/ktor/network/sockets/SocketAddress.kt +++ b/ktor-network/common/src/io/ktor/network/sockets/SocketAddress.kt @@ -14,11 +14,15 @@ public expect class InetSocketAddress( * The hostname of the socket address. * * Note that this may trigger a name service reverse lookup. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.InetSocketAddress.hostname) */ public val hostname: String /** * The port number of the socket address. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.InetSocketAddress.port) */ public val port: Int @@ -26,11 +30,15 @@ public expect class InetSocketAddress( * The hostname of the socket address. * * Note that this may trigger a name service reverse lookup. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.InetSocketAddress.component1) */ public operator fun component1(): String /** * The port number of the socket address. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.InetSocketAddress.component2) */ public operator fun component2(): Int @@ -38,6 +46,8 @@ public expect class InetSocketAddress( * Create a copy of [InetSocketAddress]. * * Note that this may trigger a name service reverse lookup. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.InetSocketAddress.copy) */ public fun copy(hostname: String = this.hostname, port: Int = this.port): InetSocketAddress @@ -51,16 +61,22 @@ public expect class UnixSocketAddress( ) : SocketAddress { /** * The path of the socket address. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.UnixSocketAddress.path) */ public val path: String /** * The path of the socket address. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.UnixSocketAddress.component1) */ public operator fun component1(): String /** * Create a copy of [UnixSocketAddress]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.UnixSocketAddress.copy) */ public fun copy(path: String = this.path): UnixSocketAddress override fun equals(other: Any?): Boolean diff --git a/ktor-network/common/src/io/ktor/network/sockets/SocketOptions.kt b/ktor-network/common/src/io/ktor/network/sockets/SocketOptions.kt index 5bf016ac4e7..d15a08ca44f 100644 --- a/ktor-network/common/src/io/ktor/network/sockets/SocketOptions.kt +++ b/ktor-network/common/src/io/ktor/network/sockets/SocketOptions.kt @@ -8,6 +8,8 @@ private const val INFINITE_TIMEOUT_MS = Long.MAX_VALUE /** * Socket options builder + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.SocketOptions) */ public sealed class SocketOptions( protected val customOptions: MutableMap @@ -45,21 +47,29 @@ public sealed class SocketOptions( /** * ToS value, [TypeOfService.UNDEFINED] by default, may not work with old JDK (will be silently ignored) + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.SocketOptions.typeOfService) */ public var typeOfService: TypeOfService = TypeOfService.UNDEFINED /** * SO_REUSEADDR option + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.SocketOptions.reuseAddress) */ public var reuseAddress: Boolean = false /** * SO_REUSEPORT option, may not work with old JDK (will be silently ignored) + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.SocketOptions.reusePort) */ public var reusePort: Boolean = false /** * TCP server socket options + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.SocketOptions.AcceptorOptions) */ public class AcceptorOptions internal constructor( customOptions: MutableMap @@ -71,6 +81,8 @@ public sealed class SocketOptions( * If the backlog is too small, it may overflow and upcoming requests will be * rejected by the underlying TCP implementation (usually with RST frame that * usually causes "connection reset by peer" error on the opposite side). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.SocketOptions.AcceptorOptions.backlogSize) */ public var backlogSize: Int = 511 @@ -83,6 +95,8 @@ public sealed class SocketOptions( /** * Represents TCP client or UDP socket options + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.SocketOptions.PeerSocketOptions) */ public open class PeerSocketOptions internal constructor( customOptions: MutableMap @@ -90,11 +104,15 @@ public sealed class SocketOptions( /** * Socket ougoing buffer size (SO_SNDBUF), `-1` or `0` to make system decide + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.SocketOptions.PeerSocketOptions.sendBufferSize) */ public var sendBufferSize: Int = -1 /** * Socket incoming buffer size (SO_RCVBUF), `-1` or `0` to make system decide + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.SocketOptions.PeerSocketOptions.receiveBufferSize) */ public var receiveBufferSize: Int = -1 @@ -127,6 +145,8 @@ public sealed class SocketOptions( /** * Represents UDP socket options + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.SocketOptions.UDPSocketOptions) */ public class UDPSocketOptions internal constructor( customOptions: MutableMap @@ -134,6 +154,8 @@ public sealed class SocketOptions( /** * SO_BROADCAST socket option + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.SocketOptions.UDPSocketOptions.broadcast) */ public var broadcast: Boolean = false @@ -153,28 +175,38 @@ public sealed class SocketOptions( /** * Represents TCP client socket options + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.SocketOptions.TCPClientSocketOptions) */ public class TCPClientSocketOptions internal constructor( customOptions: MutableMap ) : PeerSocketOptions(customOptions) { /** * TCP_NODELAY socket option, useful to disable Nagle + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.SocketOptions.TCPClientSocketOptions.noDelay) */ public var noDelay: Boolean = true /** * SO_LINGER option applied at socket close, not recommended to set to 0 however useful for debugging * Value of `-1` is the default and means that it is not set and system-dependant + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.SocketOptions.TCPClientSocketOptions.lingerSeconds) */ public var lingerSeconds: Int = -1 /** * SO_KEEPALIVE option is to enable/disable TCP keep-alive + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.SocketOptions.TCPClientSocketOptions.keepAlive) */ public var keepAlive: Boolean? = null /** * Socket timeout (read and write). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.SocketOptions.TCPClientSocketOptions.socketTimeout) */ public var socketTimeout: Long = INFINITE_TIMEOUT_MS diff --git a/ktor-network/common/src/io/ktor/network/sockets/Sockets.kt b/ktor-network/common/src/io/ktor/network/sockets/Sockets.kt index c8a9fa005b7..0ab426d981f 100644 --- a/ktor-network/common/src/io/ktor/network/sockets/Sockets.kt +++ b/ktor-network/common/src/io/ktor/network/sockets/Sockets.kt @@ -11,10 +11,14 @@ import kotlinx.io.* /** * Base type for all async sockets + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.ASocket) */ public interface ASocket : Closeable, DisposableHandle { /** * Represents a socket lifetime, completes at socket closure + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.ASocket.socketContext) */ public val socketContext: Job @@ -28,11 +32,15 @@ public interface ASocket : Closeable, DisposableHandle { /** * Check if the socket is closed + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.isClosed) */ public val ASocket.isClosed: Boolean get() = socketContext.isCompleted /** * Await until socket close + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.awaitClosed) */ public suspend fun ASocket.awaitClosed() { socketContext.join() @@ -43,32 +51,45 @@ public suspend fun ASocket.awaitClosed() { /** * Represent a connected socket + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.AConnectedSocket) */ public interface AConnectedSocket { /** * Remote socket address. Could throw an exception if the peer is not yet connected or already disconnected. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.AConnectedSocket.remoteAddress) */ public val remoteAddress: SocketAddress } /** * Represents a bound socket + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.ABoundSocket) */ public interface ABoundSocket { /** * Local socket address. Could throw an exception if no address bound yet. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.ABoundSocket.localAddress) */ public val localAddress: SocketAddress } /** * Represents a socket source, for example server socket + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.Acceptable) */ public interface Acceptable : ASocket { /** * Suspends until a connection is available and returns it or throws if something * goes wrong. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.Acceptable.accept) + * * @return accepted socket * @throws IOException */ @@ -77,11 +98,16 @@ public interface Acceptable : ASocket { /** * Represent a readable socket + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.AReadable) */ public interface AReadable { /** * Attach [channel] for reading so incoming bytes appears in the attached channel. * Only one channel could be attached + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.AReadable.attachForReading) + * * @return a job that does supply data */ @@ -90,11 +116,16 @@ public interface AReadable { /** * Represents a writable socket + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.AWritable) */ public interface AWritable { /** * Attach [channel] for writing so bytes written to the attached channel will be transmitted * Only one channel could be attached + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.AWritable.attachForWriting) + * * @return a job that does transmit data from the channel */ @@ -103,17 +134,24 @@ public interface AWritable { /** * Represents both readable and writable socket + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.ReadWriteSocket) */ public interface ReadWriteSocket : ASocket, AReadable, AWritable /** * Open a read channel, could be done only once + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.openReadChannel) */ public fun AReadable.openReadChannel(): ByteReadChannel = ByteChannel(false).also { attachForReading(it) } /** * Open a write channel, could be opened only once + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.openWriteChannel) + * * @param autoFlush whether returned channel do flush for every write operation */ @@ -122,11 +160,15 @@ public fun AWritable.openWriteChannel(autoFlush: Boolean = false): ByteWriteChan /** * Represents a connected socket + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.Socket) */ public interface Socket : ReadWriteSocket, ABoundSocket, AConnectedSocket, CoroutineScope /** * Represents a server bound socket ready for accepting connections + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.ServerSocket) */ public interface ServerSocket : ASocket, ABoundSocket, Acceptable @@ -134,6 +176,8 @@ public expect class SocketTimeoutException(message: String) : IOException /** * Represents a connected socket with its input and output + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.Connection) */ public class Connection( public val socket: Socket, @@ -143,5 +187,7 @@ public class Connection( /** * Opens socket input and output channels and returns connection object + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.connection) */ public fun Socket.connection(): Connection = Connection(this, openReadChannel(), openWriteChannel()) diff --git a/ktor-network/common/src/io/ktor/network/sockets/TcpSocketBuilder.kt b/ktor-network/common/src/io/ktor/network/sockets/TcpSocketBuilder.kt index ec88283f44e..6ae026e5387 100644 --- a/ktor-network/common/src/io/ktor/network/sockets/TcpSocketBuilder.kt +++ b/ktor-network/common/src/io/ktor/network/sockets/TcpSocketBuilder.kt @@ -8,6 +8,8 @@ import io.ktor.network.selector.* /** * TCP socket builder + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.TcpSocketBuilder) */ public class TcpSocketBuilder internal constructor( private val selector: SelectorManager, @@ -15,6 +17,8 @@ public class TcpSocketBuilder internal constructor( ) : Configurable { /** * Connect to [hostname] and [port]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.TcpSocketBuilder.connect) */ public suspend fun connect( hostname: String, @@ -24,6 +28,8 @@ public class TcpSocketBuilder internal constructor( /** * Bind server socket at [port] to listen to [hostname]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.TcpSocketBuilder.bind) */ public suspend fun bind( hostname: String = "0.0.0.0", @@ -33,6 +39,8 @@ public class TcpSocketBuilder internal constructor( /** * Connect to [remoteAddress]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.TcpSocketBuilder.connect) */ public suspend fun connect( remoteAddress: SocketAddress, @@ -41,6 +49,8 @@ public class TcpSocketBuilder internal constructor( /** * Bind server socket to listen to [localAddress]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.TcpSocketBuilder.bind) */ public suspend fun bind( localAddress: SocketAddress? = null, diff --git a/ktor-network/common/src/io/ktor/network/sockets/TypeOfService.kt b/ktor-network/common/src/io/ktor/network/sockets/TypeOfService.kt index f080844b264..1ad27735256 100644 --- a/ktor-network/common/src/io/ktor/network/sockets/TypeOfService.kt +++ b/ktor-network/common/src/io/ktor/network/sockets/TypeOfService.kt @@ -8,17 +8,24 @@ import kotlin.jvm.* /** * An inline class to hold a IP ToS value + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.TypeOfService) + * * @property value an unsigned byte IP_TOS value */ @JvmInline public value class TypeOfService(public val value: UByte) { /** * Creates ToS by integer value discarding extra high bits + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.TypeOfService.TypeOfService) */ public constructor(value: Int) : this(value.toUByte()) /** * Integer representation of this ToS + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.TypeOfService.intValue) */ public inline val intValue: Int get() = value.toInt() diff --git a/ktor-network/common/src/io/ktor/network/sockets/UDPSocketBuilder.kt b/ktor-network/common/src/io/ktor/network/sockets/UDPSocketBuilder.kt index 7b680260c45..8a0b3cde561 100644 --- a/ktor-network/common/src/io/ktor/network/sockets/UDPSocketBuilder.kt +++ b/ktor-network/common/src/io/ktor/network/sockets/UDPSocketBuilder.kt @@ -8,6 +8,8 @@ import io.ktor.network.selector.* /** * UDP socket builder + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.UDPSocketBuilder) */ public class UDPSocketBuilder internal constructor( private val selector: SelectorManager, @@ -15,6 +17,8 @@ public class UDPSocketBuilder internal constructor( ) : Configurable { /** * Bind server socket to listen to [localAddress]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.UDPSocketBuilder.bind) */ public suspend fun bind( localAddress: SocketAddress? = null, @@ -23,6 +27,8 @@ public class UDPSocketBuilder internal constructor( /** * Bind server socket at [port] to listen to [hostname]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.UDPSocketBuilder.bind) */ public suspend fun bind( hostname: String = "0.0.0.0", @@ -32,6 +38,8 @@ public class UDPSocketBuilder internal constructor( /** * Create a datagram socket to listen datagrams at [localAddress] and set to [remoteAddress]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.UDPSocketBuilder.connect) */ public suspend fun connect( remoteAddress: SocketAddress, diff --git a/ktor-network/jsAndWasmShared/src/io/ktor/network/selector/SelectorManager.jsAndWasmShared.kt b/ktor-network/jsAndWasmShared/src/io/ktor/network/selector/SelectorManager.jsAndWasmShared.kt index 538ddc3eccc..3ac497278ec 100644 --- a/ktor-network/jsAndWasmShared/src/io/ktor/network/selector/SelectorManager.jsAndWasmShared.kt +++ b/ktor-network/jsAndWasmShared/src/io/ktor/network/selector/SelectorManager.jsAndWasmShared.kt @@ -13,6 +13,8 @@ public actual fun SelectorManager(dispatcher: CoroutineContext): SelectorManager public actual interface SelectorManager : CoroutineScope, Closeable { /** * Notifies the selector that selectable has been closed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.selector.SelectorManager.notifyClosed) */ public actual fun notifyClosed(selectable: Selectable) @@ -24,6 +26,8 @@ public actual interface SelectorManager : CoroutineScope, Closeable { * select for different interests for the same selectable simultaneously. * In other words you can select for read and write at the same time but should never * try to read twice for the same selectable. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.selector.SelectorManager.select) */ public actual suspend fun select( selectable: Selectable, @@ -35,6 +39,8 @@ public actual interface SelectorManager : CoroutineScope, Closeable { /** * Select interest kind + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.selector.SelectInterest) */ public actual enum class SelectInterest { READ, diff --git a/ktor-network/jvm/src/io/ktor/network/selector/ActorSelectorManager.kt b/ktor-network/jvm/src/io/ktor/network/selector/ActorSelectorManager.kt index 8f66c2def9e..6c293228782 100644 --- a/ktor-network/jvm/src/io/ktor/network/selector/ActorSelectorManager.kt +++ b/ktor-network/jvm/src/io/ktor/network/selector/ActorSelectorManager.kt @@ -14,6 +14,8 @@ import kotlin.coroutines.intrinsics.* /** * Default CIO selector manager implementation + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.selector.ActorSelectorManager) */ public class ActorSelectorManager(context: CoroutineContext) : SelectorManagerSupport(), Closeable, CoroutineScope { @Volatile @@ -135,6 +137,8 @@ public class ActorSelectorManager(context: CoroutineContext) : SelectorManagerSu /** * Publish current [selectable] interest + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.selector.ActorSelectorManager.publishInterest) */ override fun publishInterest(selectable: Selectable) { try { @@ -169,6 +173,8 @@ public class ActorSelectorManager(context: CoroutineContext) : SelectorManagerSu /** * Close selector manager and release all resources + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.selector.ActorSelectorManager.close) */ override fun close() { closed = true diff --git a/ktor-network/jvm/src/io/ktor/network/selector/JvmSelector.kt b/ktor-network/jvm/src/io/ktor/network/selector/JvmSelector.kt index 9b9723de242..03f8da163f1 100644 --- a/ktor-network/jvm/src/io/ktor/network/selector/JvmSelector.kt +++ b/ktor-network/jvm/src/io/ktor/network/selector/JvmSelector.kt @@ -11,16 +11,22 @@ import java.nio.channels.* public actual interface Selectable : Closeable, DisposableHandle { /** * Current selectable suspensions map + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.selector.Selectable.suspensions) */ public val suspensions: InterestSuspensionsMap /** * Indicated if the selectable is closed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.selector.Selectable.isClosed) */ public val isClosed: Boolean /** * current interests + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.selector.Selectable.interestedOps) */ public val interestedOps: Int @@ -28,6 +34,8 @@ public actual interface Selectable : Closeable, DisposableHandle { /** * Apply [state] flag of [interest] to [interestedOps]. Notice that is doesn't actually change selection key. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.selector.Selectable.interestOp) */ public fun interestOp(interest: SelectInterest, state: Boolean) } diff --git a/ktor-network/jvm/src/io/ktor/network/selector/SelectorManager.kt b/ktor-network/jvm/src/io/ktor/network/selector/SelectorManager.kt index 6041df1ce3b..67323573a6b 100644 --- a/ktor-network/jvm/src/io/ktor/network/selector/SelectorManager.kt +++ b/ktor-network/jvm/src/io/ktor/network/selector/SelectorManager.kt @@ -14,15 +14,21 @@ public actual fun SelectorManager(dispatcher: CoroutineContext): SelectorManager /** * Selector manager is a service that manages NIO selectors and selection threads + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.selector.SelectorManager) */ public actual interface SelectorManager : CoroutineScope, Closeable { /** * NIO selector provider + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.selector.SelectorManager.provider) */ public val provider: SelectorProvider /** * Notifies the selector that selectable has been closed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.selector.SelectorManager.notifyClosed) */ public actual fun notifyClosed(selectable: Selectable) @@ -34,6 +40,8 @@ public actual interface SelectorManager : CoroutineScope, Closeable { * select for different interests for the same selectable simultaneously. * In other words you can select for read and write at the same time but should never * try to read twice for the same selectable. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.selector.SelectorManager.select) */ public actual suspend fun select(selectable: Selectable, interest: SelectInterest) @@ -43,6 +51,8 @@ public actual interface SelectorManager : CoroutineScope, Closeable { /** * Creates a NIO entity via [create] and calls [setup] on it. If any exception happens then the entity will be closed * and an exception will be propagated. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.selector.buildOrClose) */ public inline fun SelectorManager.buildOrClose( create: SelectorProvider.() -> C, @@ -62,6 +72,9 @@ public inline fun SelectorManager.buildOrClose( /** * Select interest kind + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.selector.SelectInterest) + * * @property [flag] to be set in NIO selector */ public actual enum class SelectInterest(public val flag: Int) { diff --git a/ktor-network/jvm/src/io/ktor/network/selector/SelectorManagerSupport.kt b/ktor-network/jvm/src/io/ktor/network/selector/SelectorManagerSupport.kt index 9f2ddb31aed..f77d5ac9bfe 100644 --- a/ktor-network/jvm/src/io/ktor/network/selector/SelectorManagerSupport.kt +++ b/ktor-network/jvm/src/io/ktor/network/selector/SelectorManagerSupport.kt @@ -13,6 +13,8 @@ import kotlin.coroutines.* /** * Base class for NIO selector managers + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.selector.SelectorManagerSupport) */ public abstract class SelectorManagerSupport internal constructor() : SelectorManager { public final override val provider: SelectorProvider = SelectorProvider.provider() diff --git a/ktor-network/jvm/src/io/ktor/network/sockets/SocketAddressJvm.kt b/ktor-network/jvm/src/io/ktor/network/sockets/SocketAddressJvm.kt index e7dd82ab464..6d78855c284 100644 --- a/ktor-network/jvm/src/io/ktor/network/sockets/SocketAddressJvm.kt +++ b/ktor-network/jvm/src/io/ktor/network/sockets/SocketAddressJvm.kt @@ -30,6 +30,8 @@ public actual class InetSocketAddress internal constructor( * Create a copy of [InetSocketAddress]. * * Note that this may trigger a name service reverse lookup. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.InetSocketAddress.copy) */ public actual fun copy( hostname: String, diff --git a/ktor-network/jvm/src/io/ktor/network/util/Pools.kt b/ktor-network/jvm/src/io/ktor/network/util/Pools.kt index ac20c79d73e..5f5143f00e5 100644 --- a/ktor-network/jvm/src/io/ktor/network/util/Pools.kt +++ b/ktor-network/jvm/src/io/ktor/network/util/Pools.kt @@ -14,12 +14,16 @@ internal const val DEFAULT_BYTE_BUFFER_BUFFER_SIZE: Int = 4096 /** * Byte buffer pool for general-purpose buffers. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.util.DefaultByteBufferPool) */ public val DefaultByteBufferPool: ObjectPool = DirectByteBufferPool(DEFAULT_BYTE_BUFFER_POOL_SIZE, DEFAULT_BYTE_BUFFER_BUFFER_SIZE) /** * Byte buffer pool for UDP datagrams + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.util.DefaultDatagramByteBufferPool) */ public val DefaultDatagramByteBufferPool: ObjectPool = DirectByteBufferPool(2048, MAX_DATAGRAM_SIZE) diff --git a/ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/CipherSuites.kt b/ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/CipherSuites.kt index 9c96e828c80..19058a85b0e 100644 --- a/ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/CipherSuites.kt +++ b/ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/CipherSuites.kt @@ -9,32 +9,44 @@ import kotlinx.io.* /** * TLS secret key exchange type. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.SecretExchangeType) */ public enum class SecretExchangeType(public val jvmName: String) { /** * Elliptic Curve Diffie-Hellman Exchange. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.SecretExchangeType.ECDHE) */ ECDHE("ECDHE_ECDSA"), /** * RSA key exchange. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.SecretExchangeType.RSA) */ RSA("RSA") } /** * Cipher type. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.CipherType) */ public enum class CipherType { /** * Galois/Counter Mode. * See also: https://en.wikipedia.org/wiki/Galois/Counter_Mode + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.CipherType.GCM) */ GCM, /** * Cipher Block Chaining. * See also: https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher_Block_Chaining_(CBC) + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.CipherType.CBC) */ CBC } @@ -42,6 +54,9 @@ public enum class CipherType { /** * Represents a TLS cipher suite * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.CipherSuite) + * * @property code numeric cipher suite code * @property name cipher suite name * @property openSSLName for this suite that is used in openssl @@ -83,6 +98,8 @@ public data class CipherSuite( * CIO cipher suites collection * https://www.ietf.org/rfc/rfc5289.txt * https://tools.ietf.org/html/rfc5288#section-3 + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.CIOCipherSuites) */ @Suppress("KDocMissingDocumentation", "PublicApiImplicitType", "MemberVisibilityCanBePrivate") public object CIOCipherSuites { @@ -140,6 +157,8 @@ public object CIOCipherSuites { /** * List of suites supported by current platform + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.CIOCipherSuites.SupportedSuites) */ public val SupportedSuites: List = listOf( ECDHE_ECDSA_AES256_SHA384, diff --git a/ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/OID.kt b/ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/OID.kt index 78b3fc88d5c..86abc8bcfb5 100644 --- a/ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/OID.kt +++ b/ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/OID.kt @@ -16,6 +16,8 @@ public data class OID(public val identifier: String) { /** * CA OID + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.OID.Companion.BasicConstraints) * */ public val BasicConstraints: OID = OID("2.5.29.19") public val KeyUsage: OID = OID("2.5.29.15") @@ -25,12 +27,16 @@ public data class OID(public val identifier: String) { /** * Encryption OID + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.OID.Companion.RSAEncryption) */ public val RSAEncryption: OID = OID("1 2 840 113549 1 1 1") public val ECEncryption: OID = OID("1.2.840.10045.2.1") /** * Algorithm OID + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.OID.Companion.ECDSAwithSHA384Encryption) */ public val ECDSAwithSHA384Encryption: OID = OID("1.2.840.10045.4.3.3") public val ECDSAwithSHA256Encryption: OID = OID("1.2.840.10045.4.3.2") @@ -42,6 +48,8 @@ public data class OID(public val identifier: String) { /** * EC curves + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.OID.Companion.secp256r1) */ public val secp256r1: OID = OID("1.2.840.10045.3.1.7") @@ -65,6 +73,8 @@ public data class OID(public val identifier: String) { * and * [KeyPairGenerator](https://docs.oracle.com/en/java/javase/17/docs/specs/security/standard-names.html#keypairgenerator-algorithms) * sections in the Java Security Standard Algorithm Names Specification for information about standard algorithm names. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.keysGenerationAlgorithm) */ public fun keysGenerationAlgorithm(algorithm: String): String = when { algorithm.endsWith("ecdsa", ignoreCase = true) -> "EC" diff --git a/ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/TLSCommon.kt b/ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/TLSCommon.kt index 358f3e0bf91..3c8cf04489f 100644 --- a/ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/TLSCommon.kt +++ b/ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/TLSCommon.kt @@ -10,6 +10,8 @@ import kotlin.coroutines.* /** * Make [Socket] connection secure with TLS using [TLSConfig]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.tls) */ public expect suspend fun Socket.tls( coroutineContext: CoroutineContext, @@ -20,16 +22,22 @@ public expect suspend fun Socket.tls( * Make [Socket] connection secure with TLS. * * TODO: report YT issue + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.tls) */ public suspend fun Socket.tls(coroutineContext: CoroutineContext): Socket = tls(coroutineContext) {} /** * Make [Socket] connection secure with TLS configured with [block]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.tls) */ public expect suspend fun Socket.tls(coroutineContext: CoroutineContext, block: TLSConfigBuilder.() -> Unit): Socket /** * Make [Socket] connection secure with TLS using [TLSConfig]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.tls) */ public suspend fun Connection.tls( coroutineContext: CoroutineContext, @@ -47,11 +55,15 @@ public suspend fun Connection.tls( /** * Make [Socket] connection secure with TLS. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.tls) */ public suspend fun Connection.tls(coroutineContext: CoroutineContext): Socket = tls(coroutineContext) {} /** * Make [Socket] connection secure with TLS configured with [block]. +* +* [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.tls) */ public suspend fun Connection.tls(coroutineContext: CoroutineContext, block: TLSConfigBuilder.() -> Unit): Socket = tls(coroutineContext, TLSConfigBuilder().apply(block).build()) diff --git a/ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/TLSConfigBuilderCommon.kt b/ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/TLSConfigBuilderCommon.kt index 1054ce0b90f..d14d6ec0255 100644 --- a/ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/TLSConfigBuilderCommon.kt +++ b/ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/TLSConfigBuilderCommon.kt @@ -6,21 +6,29 @@ package io.ktor.network.tls /** * [TLSConfig] builder. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.TLSConfigBuilder) */ public expect class TLSConfigBuilder() { /** * Custom server name for TLS server name extension. * See also: https://en.wikipedia.org/wiki/Server_Name_Indication + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.TLSConfigBuilder.serverName) */ public var serverName: String? /** * Create [TLSConfig]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.TLSConfigBuilder.build) */ public fun build(): TLSConfig } /** * Append config from [other] builder. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.takeFrom) */ public expect fun TLSConfigBuilder.takeFrom(other: TLSConfigBuilder) diff --git a/ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/extensions/NamedCurves.kt b/ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/extensions/NamedCurves.kt index ad1059b53b4..5ebf2fa6fae 100644 --- a/ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/extensions/NamedCurves.kt +++ b/ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/extensions/NamedCurves.kt @@ -6,6 +6,9 @@ package io.ktor.network.tls.extensions /** * Named curves for Elliptic Curves. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.extensions.NamedCurve) + * * @property code curve numeric code * @property fieldSize curve size in bits, affects key and signature size, performance and security strength */ @@ -40,6 +43,9 @@ public enum class NamedCurve(public val code: Short, public val fieldSize: Int) public companion object { /** * Find named curve by numeric [code] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.extensions.NamedCurve.Companion.fromCode) + * * @return [NamedCurve] instance or `null` */ public fun fromCode(code: Short): NamedCurve? = entries.find { it.code == code } @@ -48,6 +54,8 @@ public enum class NamedCurve(public val code: Short, public val fieldSize: Int) /** * List of supported named curves + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.extensions.SupportedNamedCurves) */ public val SupportedNamedCurves: List = listOf( diff --git a/ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/extensions/PointFormat.kt b/ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/extensions/PointFormat.kt index 9b3e4c54ffd..5cb404efa89 100644 --- a/ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/extensions/PointFormat.kt +++ b/ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/extensions/PointFormat.kt @@ -6,27 +6,38 @@ package io.ktor.network.tls.extensions /** * Elliptic curve point format + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.extensions.PointFormat) + * * @property code numeric point format code */ public enum class PointFormat(public val code: Byte) { /** * Curve point is not compressed + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.extensions.PointFormat.UNCOMPRESSED) */ UNCOMPRESSED(0), /** * Point is compressed according to ANSI X9.62 + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.extensions.PointFormat.ANSIX962_COMPRESSED_PRIME) */ ANSIX962_COMPRESSED_PRIME(1), /** * Point is compressed according to ANSI X9.62 + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.extensions.PointFormat.ANSIX962_COMPRESSED_CHAR2) */ ANSIX962_COMPRESSED_CHAR2(2) } /** * List of supported curve point formats + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.extensions.SupportedPointFormats) */ public val SupportedPointFormats: List = listOf( diff --git a/ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/extensions/SignatureAlgorithm.kt b/ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/extensions/SignatureAlgorithm.kt index d170233d516..abf0e3d9c6c 100644 --- a/ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/extensions/SignatureAlgorithm.kt +++ b/ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/extensions/SignatureAlgorithm.kt @@ -12,6 +12,9 @@ import kotlinx.io.* /** * Hash algorithms + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.extensions.HashAlgorithm) + * * @property code numeric hash algorithm code * @property openSSLName is a name used in openssl for this algorithm */ @@ -29,6 +32,9 @@ public enum class HashAlgorithm(public val code: Byte, public val openSSLName: S public companion object { /** * Find hash algorithm instance by its numeric [code] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.extensions.HashAlgorithm.Companion.byCode) + * * @throws TLSExtension if no hash algorithm found by code */ public fun byCode(code: Byte): HashAlgorithm = entries.find { it.code == code } @@ -38,6 +44,9 @@ public enum class HashAlgorithm(public val code: Byte, public val openSSLName: S /** * Signature algorithms + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.extensions.SignatureAlgorithm) + * * @property code numeric algorithm codes */ public enum class SignatureAlgorithm(public val code: Byte) { @@ -52,6 +61,9 @@ public enum class SignatureAlgorithm(public val code: Byte) { public companion object { /** * Find signature algorithm instance by its numeric [code] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.extensions.SignatureAlgorithm.Companion.byCode) + * * @throws TLSExtension if no hash algorithm found by code */ public fun byCode(code: Byte): SignatureAlgorithm? = entries.find { it.code == code } @@ -61,6 +73,9 @@ public enum class SignatureAlgorithm(public val code: Byte) { /** * Hash and signature algorithm pair * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.extensions.HashAndSign) + * * @property hash algorithm. * @property sign algorithm. * @property oid [object identifier](https://en.wikipedia.org/wiki/Object_identifier). @@ -68,6 +83,8 @@ public enum class SignatureAlgorithm(public val code: Byte) { public data class HashAndSign(val hash: HashAlgorithm, val sign: SignatureAlgorithm, val oid: OID? = null) { /** * String representation of this algorithms pair + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.extensions.HashAndSign.name) */ val name: String = "${hash.name}with${sign.name}" @@ -85,6 +102,8 @@ internal fun HashAndSign(hashValue: Byte, signValue: Byte, oidValue: String? = n /** * List of supported combinations of hash and signature algorithms + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.extensions.SupportedSignatureAlgorithms) */ public val SupportedSignatureAlgorithms: List = listOf( HashAndSign(HashAlgorithm.SHA384, SignatureAlgorithm.ECDSA, OID.ECDSAwithSHA384Encryption), diff --git a/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/TLS.kt b/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/TLS.kt index 0d9d17e471a..c7eaa536214 100644 --- a/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/TLS.kt +++ b/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/TLS.kt @@ -19,6 +19,8 @@ import kotlin.coroutines.* * Note that the context passed here is rarely a child of the scope in which the method is called, because it is not * usually a decomposition of the parent task. If it is a child, errors may be propogated to the parent's coroutine * exception handler rather than being caught and handled via a try-catch block. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.tls) */ public actual suspend fun Socket.tls( coroutineContext: CoroutineContext, @@ -46,6 +48,8 @@ public actual suspend fun Socket.tls( * Note that the context passed here is rarely a child of the scope in which the method is called, because it is not * usually a decomposition of the parent task. If it is a child, errors may be propogated to the parent's coroutine * exception handler rather than being caught and handled via a try-catch block. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.tls) */ public suspend fun Socket.tls( coroutineContext: CoroutineContext, @@ -69,6 +73,8 @@ public suspend fun Socket.tls( * Note that the context passed here is rarely a child of the scope in which the method is called, because it is not * usually a decomposition of the parent task. If it is a child, errors may be propogated to the parent's coroutine * exception handler rather than being caught and handled via a try-catch block. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.tls) */ public actual suspend fun Socket.tls(coroutineContext: CoroutineContext, block: TLSConfigBuilder.() -> Unit): Socket = tls(coroutineContext, TLSConfigBuilder().apply(block).build()) diff --git a/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/TLSAlert.kt b/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/TLSAlert.kt index 84c2faf30bf..4541f8f881c 100644 --- a/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/TLSAlert.kt +++ b/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/TLSAlert.kt @@ -6,16 +6,23 @@ package io.ktor.network.tls /** * TLS alert level + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.TLSAlertLevel) + * * @property code alert numeric code */ public enum class TLSAlertLevel(public val code: Int) { /** * alert warning level + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.TLSAlertLevel.WARNING) */ WARNING(1), /** * alert level fatal so the session most likely will be discarded + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.TLSAlertLevel.FATAL) */ FATAL(2); @@ -24,6 +31,8 @@ public enum class TLSAlertLevel(public val code: Int) { /** * Find alert level by its numeric [code] or fail + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.TLSAlertLevel.Companion.byCode) */ public fun byCode(code: Int): TLSAlertLevel = when (code) { in 0..255 -> byCode[code] @@ -34,6 +43,9 @@ public enum class TLSAlertLevel(public val code: Int) { /** * TLS alert types with codes + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.TLSAlertType) + * * @property code numeric alert code */ @Suppress("KDocMissingDocumentation", "EnumEntryName") @@ -70,6 +82,8 @@ public enum class TLSAlertType(public val code: Int) { /** * Find TLS alert instance by its numeric [code] or fail + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.TLSAlertType.Companion.byCode) */ public fun byCode(code: Int): TLSAlertType = when (code) { in 0..255 -> byCode[code] diff --git a/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/TLSConfigBuilder.kt b/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/TLSConfigBuilder.kt index 616ff30c3dd..68aedb9a173 100644 --- a/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/TLSConfigBuilder.kt +++ b/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/TLSConfigBuilder.kt @@ -12,17 +12,23 @@ import javax.net.ssl.* /** * [TLSConfig] builder. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.TLSConfigBuilder) */ public actual class TLSConfigBuilder { /** * List of client certificate chains with private keys. * * The Chain will be used only if the first certificate in the chain is issued by server's certificate. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.TLSConfigBuilder.certificates) */ public val certificates: MutableList = mutableListOf() /** * [SecureRandom] to use in encryption. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.TLSConfigBuilder.random) */ public var random: SecureRandom? = null @@ -30,6 +36,8 @@ public actual class TLSConfigBuilder { * Custom [X509TrustManager] to verify server authority. * * Use system by default. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.TLSConfigBuilder.trustManager) */ public var trustManager: TrustManager? = null set(value) { @@ -44,17 +52,23 @@ public actual class TLSConfigBuilder { /** * List of allowed [CipherSuite]s. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.TLSConfigBuilder.cipherSuites) */ public var cipherSuites: List = CIOCipherSuites.SupportedSuites /** * Custom server name for TLS server name extension. * See also: https://en.wikipedia.org/wiki/Server_Name_Indication + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.TLSConfigBuilder.serverName) */ public actual var serverName: String? = null /** * Create [TLSConfig]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.TLSConfigBuilder.build) */ public actual fun build(): TLSConfig = TLSConfig( random ?: SecureRandom(), @@ -67,6 +81,8 @@ public actual class TLSConfigBuilder { /** * Append config from [other] builder. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.takeFrom) */ public actual fun TLSConfigBuilder.takeFrom(other: TLSConfigBuilder) { certificates += other.certificates @@ -80,6 +96,8 @@ public actual fun TLSConfigBuilder.takeFrom(other: TLSConfigBuilder) { * Add client certificate chain to use. * * It will be used only if the first certificate in the chain is issued by server's certificate. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.addCertificateChain) */ public fun TLSConfigBuilder.addCertificateChain(chain: Array, key: PrivateKey) { certificates += CertificateAndKey(chain, key) @@ -88,6 +106,8 @@ public fun TLSConfigBuilder.addCertificateChain(chain: Array, k /** * Add client certificates from [store] by using the certificate with specific [alias] * or all certificates, if [alias] is null. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.addKeyStore) */ @JvmName("addKeyStoreNullablePassword") public fun TLSConfigBuilder.addKeyStore(store: KeyStore, password: CharArray?, alias: String? = null) { @@ -119,6 +139,8 @@ public fun TLSConfigBuilder.addKeyStore(store: KeyStore, password: CharArray?, a /** * Throws if failed to find [PrivateKey] for any alias in [KeyStore]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.NoPrivateKeyException) */ @OptIn(ExperimentalCoroutinesApi::class) public class NoPrivateKeyException( diff --git a/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/TLSConfigJvm.kt b/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/TLSConfigJvm.kt index acf7a615538..9f3038a12db 100644 --- a/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/TLSConfigJvm.kt +++ b/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/TLSConfigJvm.kt @@ -10,6 +10,9 @@ import javax.net.ssl.* /** * TLS configuration. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.TLSConfig) + * * @property trustManager: Custom [X509TrustManager] to verify server authority. Use system by default. * @property random: [SecureRandom] to use in encryption. * @property certificates: list of client certificate chains with private keys. @@ -26,6 +29,9 @@ public actual class TLSConfig( /** * Client certificate chain with private key. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.CertificateAndKey) + * * @property certificateChain: client certificate chain. * @property key: [PrivateKey] for certificate chain. */ diff --git a/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/TLSHandshakeType.kt b/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/TLSHandshakeType.kt index 945664e60d9..e8811a1b6a3 100644 --- a/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/TLSHandshakeType.kt +++ b/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/TLSHandshakeType.kt @@ -8,6 +8,9 @@ import io.ktor.network.tls.extensions.* /** * TLS handshake record type + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.TLSHandshakeType) + * * @property code numeric type code */ @@ -28,6 +31,8 @@ public enum class TLSHandshakeType(public val code: Int) { /** * Find handshake type instance by its numeric [code] or fail + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.TLSHandshakeType.Companion.byCode) */ public fun byCode(code: Int): TLSHandshakeType = when (code) { in 0..0xff -> byCode[code] @@ -38,6 +43,9 @@ public enum class TLSHandshakeType(public val code: Int) { /** * Server key exchange type with it's [code] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.ServerKeyExchangeType) + * * @property code numeric exchange type code */ @@ -51,6 +59,8 @@ public enum class ServerKeyExchangeType(public val code: Int) { /** * Find an instance of [ServerKeyExchangeType] by its numeric code or fail + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.ServerKeyExchangeType.Companion.byCode) */ public fun byCode(code: Int): ServerKeyExchangeType { val result = if (code in 0..0xff) byCode[code] else null diff --git a/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/TLSRecordType.kt b/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/TLSRecordType.kt index f38db13bfc9..0a96c150355 100644 --- a/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/TLSRecordType.kt +++ b/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/TLSRecordType.kt @@ -6,6 +6,9 @@ package io.ktor.network.tls /** * TLS record type with it's numeric [code] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.TLSRecordType) + * * @property code numeric record type code */ @@ -20,6 +23,8 @@ public enum class TLSRecordType(public val code: Int) { /** * Find an instance of [TLSRecordType] by its numeric code or fail + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.TLSRecordType.Companion.byCode) */ public fun byCode(code: Int): TLSRecordType = when (code) { in 0..255 -> byCode[code] diff --git a/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/TLSVersion.kt b/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/TLSVersion.kt index 5d6007b7155..47ad9c4b7fb 100644 --- a/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/TLSVersion.kt +++ b/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/TLSVersion.kt @@ -8,6 +8,9 @@ import kotlin.enums.* /** * TLS version + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.TLSVersion) + * * @property code numeric TLS version code */ public enum class TLSVersion(public val code: Int) { @@ -21,6 +24,8 @@ public enum class TLSVersion(public val code: Int) { /** * Find version instance by its numeric [code] or fail + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.TLSVersion.Companion.byCode) */ public fun byCode(code: Int): TLSVersion = when (code) { in 0x0300..0x0303 -> byOrdinal[code - 0x0300] diff --git a/ktor-network/ktor-network-tls/ktor-network-tls-certificates/jvm/src/io/ktor/network/tls/certificates/Certificates.kt b/ktor-network/ktor-network-tls/ktor-network-tls-certificates/jvm/src/io/ktor/network/tls/certificates/Certificates.kt index 5c704122f01..600678acbca 100644 --- a/ktor-network/ktor-network-tls/ktor-network-tls-certificates/jvm/src/io/ktor/network/tls/certificates/Certificates.kt +++ b/ktor-network/ktor-network-tls/ktor-network-tls-certificates/jvm/src/io/ktor/network/tls/certificates/Certificates.kt @@ -34,6 +34,8 @@ private val DEFAULT_CA_PRINCIPAL = X500Principal("CN=localhostCA, OU=Kotlin, O=J * * A generated certificate will have 3 days validity period and 1024-bits key strength. * Only localhost and 127.0.0.1 domains are valid with the certificate. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.certificates.generateCertificate) */ public fun generateCertificate( file: File? = null, @@ -129,6 +131,8 @@ public enum class KeyType { * * A generated certificate will have 3 days validity period and 1024-bits key strength. * Only localhost and 127.0.0.1 domains are valid with the certificate. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.certificates.generateCertificate) */ public fun KeyStore.generateCertificate( file: File? = null, @@ -175,6 +179,8 @@ public fun KeyStore.generateCertificate( * while their responding keys are private. * * If [file] is set, all certificates are stored in a JKS keystore in [file] with [password]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.certificates.trustStore) */ public fun KeyStore.trustStore( file: File? = null, diff --git a/ktor-network/ktor-network-tls/ktor-network-tls-certificates/jvm/src/io/ktor/network/tls/certificates/builders.kt b/ktor-network/ktor-network-tls/ktor-network-tls-certificates/jvm/src/io/ktor/network/tls/certificates/builders.kt index ebd9ddf7694..369bcd6cbc3 100644 --- a/ktor-network/ktor-network-tls/ktor-network-tls-certificates/jvm/src/io/ktor/network/tls/certificates/builders.kt +++ b/ktor-network/ktor-network-tls/ktor-network-tls-certificates/jvm/src/io/ktor/network/tls/certificates/builders.kt @@ -24,35 +24,49 @@ internal data class CertificateInfo( /** * Builder for certificate + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.certificates.CertificateBuilder) */ public class CertificateBuilder internal constructor() { /** * Certificate hash algorithm + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.certificates.CertificateBuilder.hash) */ public var hash: HashAlgorithm = HashAlgorithm.SHA1 /** * Certificate signature algorithm + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.certificates.CertificateBuilder.sign) */ public var sign: SignatureAlgorithm = SignatureAlgorithm.RSA /** * Certificate password (required) + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.certificates.CertificateBuilder.password) */ public lateinit var password: String /** * The subject of the certificate, owner of the generated public key that we certify. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.certificates.CertificateBuilder.subject) */ public var subject: X500Principal = DEFAULT_PRINCIPAL /** * Number of days the certificate is valid + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.certificates.CertificateBuilder.daysValid) */ public var daysValid: Long = 3 /** * Certificate key size in bits + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.certificates.CertificateBuilder.keySizeInBits) */ public var keySizeInBits: Int = 1024 @@ -61,16 +75,22 @@ public class CertificateBuilder internal constructor() { * * This determines the extensions that should be written in the certificate, such as [OID.ExtKeyUsage] (server or * client authentication), or [OID.BasicConstraints] to use the key as CA. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.certificates.CertificateBuilder.keyType) */ public var keyType: KeyType = KeyType.Server /** * Domains for which this certificate is valid (only relevant for [KeyType.Server], ignored for other key types). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.certificates.CertificateBuilder.domains) */ public var domains: List = listOf("localhost") /** * IP addresses for which this certificate is valid (only relevant for [KeyType.Server], ignored for other key types). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.certificates.CertificateBuilder.ipAddresses) */ public var ipAddresses: List = listOf(Inet4Address.getByName("127.0.0.1")) @@ -90,6 +110,8 @@ public class CertificateBuilder internal constructor() { * * If this method is not called, this certificate will be self-signed by the subject (with the same generated key * as the one being certified). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.certificates.CertificateBuilder.signWith) */ public fun signWith( issuerKeyPair: KeyPair, @@ -111,6 +133,8 @@ public class CertificateBuilder internal constructor() { * * If this method is not called, this certificate will be self-signed by the subject (with the same generated key * as the one being certified). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.certificates.CertificateBuilder.signWith) */ public fun signWith( issuerKeyPair: KeyPair, @@ -143,6 +167,8 @@ public class CertificateBuilder internal constructor() { /** * Builder for key store + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.certificates.KeyStoreBuilder) */ public class KeyStoreBuilder internal constructor() { private val certificates = mutableMapOf() @@ -150,6 +176,8 @@ public class KeyStoreBuilder internal constructor() { /** * Generate a certificate and append to the key store. * If there is a certificate with the same [alias] then it will be replaced + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.certificates.KeyStoreBuilder.certificate) */ public fun certificate(alias: String, block: CertificateBuilder.() -> Unit) { certificates[alias] = CertificateBuilder().apply(block).build() @@ -171,11 +199,15 @@ public class KeyStoreBuilder internal constructor() { /** * Create a keystore and configure it in [block] function + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.certificates.buildKeyStore) */ public fun buildKeyStore(block: KeyStoreBuilder.() -> Unit): KeyStore = KeyStoreBuilder().apply(block).build() /** * Save [KeyStore] to [output] file with the specified [password] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.certificates.saveToFile) */ public fun KeyStore.saveToFile(output: File, password: String) { output.parentFile?.mkdirs() diff --git a/ktor-network/ktor-network-tls/nonJvm/src/io/ktor/network/tls/TLS.nonJvm.kt b/ktor-network/ktor-network-tls/nonJvm/src/io/ktor/network/tls/TLS.nonJvm.kt index 422d50343ae..2a635657746 100644 --- a/ktor-network/ktor-network-tls/nonJvm/src/io/ktor/network/tls/TLS.nonJvm.kt +++ b/ktor-network/ktor-network-tls/nonJvm/src/io/ktor/network/tls/TLS.nonJvm.kt @@ -10,6 +10,8 @@ import kotlin.coroutines.* /** * Make [Socket] connection secure with TLS using [TLSConfig]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.tls) */ public actual suspend fun Socket.tls( coroutineContext: CoroutineContext, @@ -30,6 +32,8 @@ public actual suspend fun Socket.tls( /** * Make [Socket] connection secure with TLS configured with [block]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.tls) */ public actual suspend fun Socket.tls(coroutineContext: CoroutineContext, block: TLSConfigBuilder.() -> Unit): Socket = tls(coroutineContext, TLSConfigBuilder().apply(block).build()) diff --git a/ktor-network/ktor-network-tls/nonJvm/src/io/ktor/network/tls/TLSConfigBuilder.nonJvm.kt b/ktor-network/ktor-network-tls/nonJvm/src/io/ktor/network/tls/TLSConfigBuilder.nonJvm.kt index c793008af39..31aa79f67da 100644 --- a/ktor-network/ktor-network-tls/nonJvm/src/io/ktor/network/tls/TLSConfigBuilder.nonJvm.kt +++ b/ktor-network/ktor-network-tls/nonJvm/src/io/ktor/network/tls/TLSConfigBuilder.nonJvm.kt @@ -6,22 +6,30 @@ package io.ktor.network.tls /** * [TLSConfig] builder. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.TLSConfigBuilder) */ public actual class TLSConfigBuilder { /** * Custom server name for TLS server name extension. * See also: https://en.wikipedia.org/wiki/Server_Name_Indication + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.TLSConfigBuilder.serverName) */ public actual var serverName: String? = null /** * Create [TLSConfig]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.TLSConfigBuilder.build) */ public actual fun build(): TLSConfig = TLSConfig() } /** * Append config from [other] builder. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.tls.takeFrom) */ public actual fun TLSConfigBuilder.takeFrom(other: TLSConfigBuilder) { } diff --git a/ktor-network/nonJvm/src/io/ktor/network/sockets/SocketAddress.nonJvm.kt b/ktor-network/nonJvm/src/io/ktor/network/sockets/SocketAddress.nonJvm.kt index 366d00b31e7..b93b2dafa65 100644 --- a/ktor-network/nonJvm/src/io/ktor/network/sockets/SocketAddress.nonJvm.kt +++ b/ktor-network/nonJvm/src/io/ktor/network/sockets/SocketAddress.nonJvm.kt @@ -14,6 +14,8 @@ public actual class InetSocketAddress actual constructor( * Create a copy of [InetSocketAddress]. * * Note that this may trigger a name service reverse lookup. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.InetSocketAddress.copy) */ public actual fun copy(hostname: String, port: Int): InetSocketAddress { return InetSocketAddress(hostname, port) @@ -23,6 +25,8 @@ public actual class InetSocketAddress actual constructor( * The hostname of the socket address. * * Note that this may trigger a name service reverse lookup. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.InetSocketAddress.component1) */ public actual operator fun component1(): String { return hostname @@ -30,6 +34,8 @@ public actual class InetSocketAddress actual constructor( /** * The port number of the socket address. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.InetSocketAddress.component2) */ public actual operator fun component2(): Int { return port @@ -54,6 +60,8 @@ public actual class UnixSocketAddress actual constructor( ) : SocketAddress() { /** * The path of the socket address. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.UnixSocketAddress.component1) */ public actual operator fun component1(): String { return path @@ -74,6 +82,8 @@ public actual class UnixSocketAddress actual constructor( /** * Create a copy of [UnixSocketAddress]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.UnixSocketAddress.copy) */ public actual fun copy(path: String): UnixSocketAddress { return UnixSocketAddress(path) diff --git a/ktor-network/posix/src/io/ktor/network/selector/SelectorManager.kt b/ktor-network/posix/src/io/ktor/network/selector/SelectorManager.kt index 2e641af9fee..20effa44459 100644 --- a/ktor-network/posix/src/io/ktor/network/selector/SelectorManager.kt +++ b/ktor-network/posix/src/io/ktor/network/selector/SelectorManager.kt @@ -15,6 +15,8 @@ public actual fun SelectorManager( public actual interface SelectorManager : CoroutineScope, Closeable { /** * Notifies the selector that selectable has been closed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.selector.SelectorManager.notifyClosed) */ public actual fun notifyClosed(selectable: Selectable) @@ -26,6 +28,8 @@ public actual interface SelectorManager : CoroutineScope, Closeable { * select for different interests for the same selectable simultaneously. * In other words you can select for read and write at the same time but should never * try to read twice for the same selectable. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.selector.SelectorManager.select) */ public actual suspend fun select( selectable: Selectable, @@ -37,6 +41,8 @@ public actual interface SelectorManager : CoroutineScope, Closeable { /** * Select interest kind + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.selector.SelectInterest) */ public actual enum class SelectInterest { READ, diff --git a/ktor-server/ktor-server-cio/common/src/io/ktor/server/cio/CIO.kt b/ktor-server/ktor-server-cio/common/src/io/ktor/server/cio/CIO.kt index 0e2a98bb3d3..75c9872ff37 100644 --- a/ktor-server/ktor-server-cio/common/src/io/ktor/server/cio/CIO.kt +++ b/ktor-server/ktor-server-cio/common/src/io/ktor/server/cio/CIO.kt @@ -10,6 +10,8 @@ import io.ktor.server.engine.* /** * An [ApplicationEngineFactory] providing a CIO-based [ApplicationEngine] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.cio.CIO) */ public object CIO : ApplicationEngineFactory { diff --git a/ktor-server/ktor-server-cio/common/src/io/ktor/server/cio/CIOApplicationEngine.kt b/ktor-server/ktor-server-cio/common/src/io/ktor/server/cio/CIOApplicationEngine.kt index f7a62155cae..79ba9b2e220 100644 --- a/ktor-server/ktor-server-cio/common/src/io/ktor/server/cio/CIOApplicationEngine.kt +++ b/ktor-server/ktor-server-cio/common/src/io/ktor/server/cio/CIOApplicationEngine.kt @@ -19,6 +19,8 @@ import kotlin.concurrent.* /** * Engine that based on CIO backend + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.cio.CIOApplicationEngine) */ public class CIOApplicationEngine( environment: ApplicationEnvironment, @@ -30,16 +32,22 @@ public class CIOApplicationEngine( /** * CIO-based server configuration + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.cio.CIOApplicationEngine.Configuration) */ public class Configuration : BaseApplicationEngine.Configuration() { /** * Number of seconds that the server will keep HTTP IDLE connections open. * A connection is IDLE if there are no active requests running. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.cio.CIOApplicationEngine.Configuration.connectionIdleTimeoutSeconds) */ public var connectionIdleTimeoutSeconds: Int = 45 /** * Allow the server to bind to an address that is already in use + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.cio.CIOApplicationEngine.Configuration.reuseAddress) */ public var reuseAddress: Boolean = false } diff --git a/ktor-server/ktor-server-cio/common/src/io/ktor/server/cio/EngineMain.kt b/ktor-server/ktor-server-cio/common/src/io/ktor/server/cio/EngineMain.kt index ed7ae206542..af61d7e73c7 100644 --- a/ktor-server/ktor-server-cio/common/src/io/ktor/server/cio/EngineMain.kt +++ b/ktor-server/ktor-server-cio/common/src/io/ktor/server/cio/EngineMain.kt @@ -10,10 +10,14 @@ import kotlin.jvm.* /** * Default engine with main function that starts CIO engine using application.conf + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.cio.EngineMain) */ public object EngineMain { /** * CIO engine entry point + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.cio.EngineMain.main) */ @JvmStatic public fun main(args: Array) { diff --git a/ktor-server/ktor-server-cio/common/src/io/ktor/server/cio/HttpServer.kt b/ktor-server/ktor-server-cio/common/src/io/ktor/server/cio/HttpServer.kt index 9fc5ac260b8..b3c1a47fc6e 100644 --- a/ktor-server/ktor-server-cio/common/src/io/ktor/server/cio/HttpServer.kt +++ b/ktor-server/ktor-server-cio/common/src/io/ktor/server/cio/HttpServer.kt @@ -9,6 +9,9 @@ import kotlinx.coroutines.* /** * Represents a server instance + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.cio.HttpServer) + * * @property rootServerJob server job - root for all jobs * @property acceptJob client connections accepting job * @property serverSocket a deferred server socket instance, could be completed with error if it failed to bind @@ -21,6 +24,9 @@ public class HttpServer( /** * HTTP server connector settings + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.cio.HttpServerSettings) + * * @property host to listen to * @property port to listen to * @property connectionIdleTimeoutSeconds time to live for IDLE connections diff --git a/ktor-server/ktor-server-cio/common/src/io/ktor/server/cio/Pipeline.kt b/ktor-server/ktor-server-cio/common/src/io/ktor/server/cio/Pipeline.kt index 36acf9c1574..4bba3c7395f 100644 --- a/ktor-server/ktor-server-cio/common/src/io/ktor/server/cio/Pipeline.kt +++ b/ktor-server/ktor-server-cio/common/src/io/ktor/server/cio/Pipeline.kt @@ -11,6 +11,8 @@ import kotlin.native.concurrent.* /** * HTTP request handler function + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.cio.HttpRequestHandler) */ public typealias HttpRequestHandler = suspend ServerRequestScope.(request: Request) -> Unit diff --git a/ktor-server/ktor-server-cio/common/src/io/ktor/server/cio/backend/HttpServer.kt b/ktor-server/ktor-server-cio/common/src/io/ktor/server/cio/backend/HttpServer.kt index d83a63d8d24..8b0d4b36a12 100644 --- a/ktor-server/ktor-server-cio/common/src/io/ktor/server/cio/backend/HttpServer.kt +++ b/ktor-server/ktor-server-cio/common/src/io/ktor/server/cio/backend/HttpServer.kt @@ -19,6 +19,8 @@ private val LOGGER = KtorSimpleLogger("io.ktor.server.cio.HttpServer") /** * Start a http server with [settings] invoking [handler] for every request + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.cio.backend.httpServer) */ @OptIn(InternalAPI::class) public fun CoroutineScope.httpServer( diff --git a/ktor-server/ktor-server-cio/common/src/io/ktor/server/cio/backend/ServerIncomingConnection.kt b/ktor-server/ktor-server-cio/common/src/io/ktor/server/cio/backend/ServerIncomingConnection.kt index 30e5c89f957..de33b638427 100644 --- a/ktor-server/ktor-server-cio/common/src/io/ktor/server/cio/backend/ServerIncomingConnection.kt +++ b/ktor-server/ktor-server-cio/common/src/io/ktor/server/cio/backend/ServerIncomingConnection.kt @@ -9,6 +9,9 @@ import io.ktor.utils.io.* /** * Represents a server incoming connection. Usually it is a TCP connection but potentially could be other transport. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.cio.backend.ServerIncomingConnection) + * * @property input channel connected to incoming bytes end * @property output channel connected to outgoing bytes end * @property remoteAddress of the client (optional) diff --git a/ktor-server/ktor-server-cio/common/src/io/ktor/server/cio/backend/ServerPipeline.kt b/ktor-server/ktor-server-cio/common/src/io/ktor/server/cio/backend/ServerPipeline.kt index b5e3a23375c..a22e6c58704 100644 --- a/ktor-server/ktor-server-cio/common/src/io/ktor/server/cio/backend/ServerPipeline.kt +++ b/ktor-server/ktor-server-cio/common/src/io/ktor/server/cio/backend/ServerPipeline.kt @@ -22,6 +22,9 @@ import kotlin.time.* * Start connection HTTP pipeline invoking [handler] for every request. * Note that [handler] could be invoked multiple times concurrently due to HTTP pipeline nature * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.cio.backend.startServerConnectionPipeline) + * * @param connection incoming client connection info * @param timeout number of IDLE seconds after the connection will be closed * @param handler to be invoked for every incoming request diff --git a/ktor-server/ktor-server-cio/common/src/io/ktor/server/cio/backend/ServerRequestScope.kt b/ktor-server/ktor-server-cio/common/src/io/ktor/server/cio/backend/ServerRequestScope.kt index 40f7020362c..b1b6ad7710f 100644 --- a/ktor-server/ktor-server-cio/common/src/io/ktor/server/cio/backend/ServerRequestScope.kt +++ b/ktor-server/ktor-server-cio/common/src/io/ktor/server/cio/backend/ServerRequestScope.kt @@ -11,6 +11,9 @@ import kotlin.coroutines.* /** * Represents a request scope. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.cio.backend.ServerRequestScope) + * * @property upgraded deferred should be completed on upgrade request * @property input channel connected to request body bytes stream * @property output channel connected to response body @@ -27,6 +30,8 @@ public class ServerRequestScope internal constructor( ) : CoroutineScope { /** * Creates another request scope with same parameters except coroutine context + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.cio.backend.ServerRequestScope.withContext) */ public fun withContext(coroutineContext: CoroutineContext): ServerRequestScope = ServerRequestScope( diff --git a/ktor-server/ktor-server-cio/common/test/io/ktor/tests/server/cio/RAWExample.kt b/ktor-server/ktor-server-cio/common/test/io/ktor/tests/server/cio/RAWExample.kt index 4955c3fc5a9..6ba2bdcff05 100644 --- a/ktor-server/ktor-server-cio/common/test/io/ktor/tests/server/cio/RAWExample.kt +++ b/ktor-server/ktor-server-cio/common/test/io/ktor/tests/server/cio/RAWExample.kt @@ -28,6 +28,8 @@ private val notFound404_11 = RequestResponseBuilder().apply { /** * This is just an example demonstrating how to create CIO low-level http server + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.tests.server.cio.example) */ @OptIn(DelicateCoroutinesApi::class) fun example() { diff --git a/ktor-server/ktor-server-cio/jvm/test/io/ktor/tests/server/cio/ClassCastExceptionTest.kt b/ktor-server/ktor-server-cio/jvm/test/io/ktor/tests/server/cio/ClassCastExceptionTest.kt index 2c2fac14821..f04e810cbb8 100644 --- a/ktor-server/ktor-server-cio/jvm/test/io/ktor/tests/server/cio/ClassCastExceptionTest.kt +++ b/ktor-server/ktor-server-cio/jvm/test/io/ktor/tests/server/cio/ClassCastExceptionTest.kt @@ -26,6 +26,8 @@ class ClassCastExceptionTest : EngineTestBase = listOf(WORKING_DIRECTORY_PATH) /** * Application's root path (prefix, context path in servlet container). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ServerConfigBuilder.rootPath) */ public var rootPath: String = "" /** * Indicates whether development mode is enabled. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ServerConfigBuilder.developmentMode) */ public var developmentMode: Boolean = PlatformUtils.IS_DEVELOPMENT_MODE /** * Parent coroutine context for an application. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ServerConfigBuilder.parentCoroutineContext) */ public var parentCoroutineContext: CoroutineContext = EmptyCoroutineContext /** * Installs an application module. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ServerConfigBuilder.module) */ public fun module(body: Application.() -> Unit) { modules.add(body) @@ -55,6 +67,8 @@ public class ServerConfigBuilder( /** * Core configuration for a running server. * Contains modules, paths, and environment details. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ServerConfig) */ public class ServerConfig internal constructor( public val environment: ApplicationEnvironment, @@ -70,6 +84,8 @@ public class ServerConfig internal constructor( /** * Creates an [ServerConfig] instance. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.serverConfig) */ public fun serverConfig( environment: ApplicationEnvironment = applicationEnvironment {}, @@ -82,6 +98,8 @@ public fun serverConfig( * Represents configured and running web application, capable of handling requests. * It is also the application coroutine scope that is cancelled immediately at application stop so useful * for launching background coroutines. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.Application) */ @KtorDsl public class Application internal constructor( @@ -101,6 +119,8 @@ public class Application internal constructor( /** * Called by [ApplicationEngine] when [Application] is terminated. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.Application.dispose) */ @Suppress("DEPRECATION_ERROR") public fun dispose() { @@ -111,5 +131,7 @@ public class Application internal constructor( /** * Convenience property to access log from application + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.log) */ public val Application.log: Logger get() = environment.log diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/application/ApplicationCallPipeline.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/application/ApplicationCallPipeline.kt index 9e8e62a6543..85acaa116b0 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/application/ApplicationCallPipeline.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/application/ApplicationCallPipeline.kt @@ -10,6 +10,8 @@ import io.ktor.util.pipeline.* /** * Pipeline configuration for executing [PipelineCall] instances. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationCallPipeline) */ @Suppress("PublicApiImplicitType") public open class ApplicationCallPipeline public constructor( @@ -24,45 +26,63 @@ public open class ApplicationCallPipeline public constructor( ) { /** * Pipeline for receiving content + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationCallPipeline.receivePipeline) */ public val receivePipeline: ApplicationReceivePipeline = ApplicationReceivePipeline(developmentMode) /** * Pipeline for sending content + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationCallPipeline.sendPipeline) */ public val sendPipeline: ApplicationSendPipeline = ApplicationSendPipeline(developmentMode) /** * Standard phases for application call pipelines + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationCallPipeline.ApplicationPhase) */ public companion object ApplicationPhase { /** * Phase for preparing call and it's attributes for processing + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationCallPipeline.ApplicationPhase.Setup) */ public val Setup: PipelinePhase = PipelinePhase("Setup") /** * Phase for tracing calls, useful for logging, metrics, error handling and so on + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationCallPipeline.ApplicationPhase.Monitoring) */ public val Monitoring: PipelinePhase = PipelinePhase("Monitoring") /** * Phase for plugins. Most plugins should intercept this phase. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationCallPipeline.ApplicationPhase.Plugins) */ public val Plugins: PipelinePhase = PipelinePhase("Plugins") /** * Phase for processing a call and sending a response + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationCallPipeline.ApplicationPhase.Call) */ public val Call: PipelinePhase = PipelinePhase("Call") /** * Phase for handling unprocessed calls + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationCallPipeline.ApplicationPhase.Fallback) */ public val Fallback: PipelinePhase = PipelinePhase("Fallback") /** * Phase for plugins. Most plugins should intercept this phase. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationCallPipeline.ApplicationPhase.Features) */ @Deprecated( "Renamed to Plugins", @@ -75,10 +95,14 @@ public open class ApplicationCallPipeline public constructor( /** * Current call for the context + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.call) */ public inline val PipelineContext<*, PipelineCall>.call: PipelineCall get() = context /** * Current application for the context + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.application) */ public val PipelineContext<*, PipelineCall>.application: Application get() = call.application diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/application/ApplicationConfigExtensions.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/application/ApplicationConfigExtensions.kt index 5a5076ee775..0b6f6029da3 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/application/ApplicationConfigExtensions.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/application/ApplicationConfigExtensions.kt @@ -8,10 +8,14 @@ import io.ktor.server.config.* /** * The port the current application is running on, as defined by the configuration at start-up. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.port) **/ public val ApplicationConfig.port: Int get() = propertyOrNull("ktor.deployment.port")?.getString()?.toInt() ?: 8080 /** * The host address of the currently running application, as defined by the configuration at start-up. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.host) **/ public val ApplicationConfig.host: String get() = propertyOrNull("ktor.deployment.host")?.getString() ?: "0.0.0.0" diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/application/ApplicationEvents.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/application/ApplicationEvents.kt index 617b70a449f..ce4504240da 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/application/ApplicationEvents.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/application/ApplicationEvents.kt @@ -6,6 +6,8 @@ package io.ktor.server.application /** * Provides events for [Application] lifecycle. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationEvents) */ @Deprecated( "ApplicationEvents has been renamed to Events.", @@ -16,6 +18,8 @@ public typealias ApplicationEvents = io.ktor.events.Events /** * Specifies signature for the event handler. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.EventHandler) */ @Deprecated( "EventHandler has been moved to package io.ktor.events", @@ -30,6 +34,9 @@ public typealias EventHandler = io.ktor.events.EventHandler * Inheriting of this class is an experimental plugin. * Instantiate directly if inheritance not necessary. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.EventDefinition) + * * @param T specifies what is a type of a value passed to the event */ @Deprecated( diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/application/ApplicationPlugin.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/application/ApplicationPlugin.kt index 6f8012d4664..f6323a2cf35 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/application/ApplicationPlugin.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/application/ApplicationPlugin.kt @@ -12,6 +12,9 @@ import kotlinx.coroutines.* /** * Defines an installable [Plugin](https://ktor.io/docs/plugins.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.Plugin) + * * @param TPipeline is the type of the pipeline this plugin is compatible with * @param TConfiguration is the configuration object type for this Plugin * @param TPlugin is the instance type of the Plugin object @@ -24,17 +27,24 @@ public interface Plugin< > { /** * A unique key that identifies a plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.Plugin.key) */ public val key: AttributeKey /** * A plugin's installation script. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.Plugin.install) */ public fun install(pipeline: TPipeline, configure: TConfiguration.() -> Unit): TPlugin } /** * Defines a [Plugin](https://ktor.io/docs/plugins.html) that is installed into Application. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.BaseApplicationPlugin) + * * @param TPipeline is the type of the pipeline this plugin is compatible with * @param TConfiguration is the configuration object type for this Plugin * @param TPlugin is the instance type of the Plugin object @@ -47,6 +57,9 @@ public interface BaseApplicationPlugin< /** * Defines a [Plugin](https://ktor.io/docs/plugins.html) that is installed into Application. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationPlugin) + * * @param TConfiguration is the configuration object type for this Plugin */ public interface ApplicationPlugin : @@ -56,6 +69,8 @@ internal val pluginRegistryKey = AttributeKey("ApplicationPluginRegi /** * Returns the existing plugin registry or registers and returns a new one. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.pluginRegistry) */ public val > A.pluginRegistry: Attributes get() = attributes.computeIfAbsent(pluginRegistryKey) { Attributes(true) } @@ -63,6 +78,9 @@ public val > A.pluginRegistry: Attributes /** * Gets a plugin instance for this pipeline, or fails with [MissingApplicationPluginException] * if the plugin is not installed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.plugin) + * * @throws MissingApplicationPluginException * @param plugin [Plugin] to lookup * @return an instance of a plugin @@ -76,6 +94,8 @@ public fun , F : Any> A.plugin(plugin: Plugin<*, * /** * Returns a plugin instance for this pipeline, or null if the plugin is not installed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.pluginOrNull) */ public fun , F : Any> A.pluginOrNull(plugin: Plugin<*, *, F>): F? { return pluginRegistry.getOrNull(plugin.key) @@ -83,6 +103,8 @@ public fun , F : Any> A.pluginOrNull(plugin: Plugi /** * Installs a [plugin] into this pipeline, if it is not yet installed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.install) */ public fun

, B : Any, F : Any> P.install( plugin: Plugin, @@ -177,6 +199,8 @@ private fun P.install( /** * Uninstalls all plugins from the pipeline. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.uninstallAllPlugins) */ @Deprecated( "This method is misleading and will be removed. " + @@ -207,6 +233,8 @@ public fun > A.uninstallAllPlugins() { /** * Uninstalls a [plugin] from the pipeline. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.uninstall) */ @Suppress("DEPRECATION_ERROR") @Deprecated( @@ -220,6 +248,8 @@ public fun , B : Any, F : Any> A.uninstall( /** * Uninstalls a plugin specified by [key] from the pipeline. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.uninstallPlugin) */ @Deprecated( "This method is misleading and will be removed. " + @@ -237,6 +267,8 @@ public fun , F : Any> A.uninstallPlugin(key: Attri /** * Thrown on an attempt to install the plugin with the same key as for the already installed plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.DuplicateApplicationPluginException) */ @Deprecated( message = "Please use DuplicatePluginException instead", @@ -247,12 +279,17 @@ public open class DuplicateApplicationPluginException(message: String) : Excepti /** * Thrown on an attempt to install the plugin with the same key as for the already installed plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.DuplicatePluginException) */ @Suppress("DEPRECATION_ERROR") public class DuplicatePluginException(message: String) : DuplicateApplicationPluginException(message) /** * Thrown on an attempt to access the plugin that is not yet installed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.MissingApplicationPluginException) + * * @param key application plugin's attribute key */ @OptIn(ExperimentalCoroutinesApi::class) diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/application/CommonApplicationEnvironment.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/application/CommonApplicationEnvironment.kt index f2fb3fd3805..7996daaaeed 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/application/CommonApplicationEnvironment.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/application/CommonApplicationEnvironment.kt @@ -11,21 +11,29 @@ import kotlin.coroutines.* /** * Represents an environment in which [Application] runs + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationEnvironment) */ public expect interface ApplicationEnvironment { /** * Instance of [Logger] to be used for logging. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationEnvironment.log) */ public val log: Logger /** * Configuration for the [Application] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationEnvironment.config) */ public val config: ApplicationConfig /** * Provides events on Application lifecycle + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationEnvironment.monitor) */ @Deprecated( message = "Moved to Application", diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/application/CreatePluginUtils.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/application/CreatePluginUtils.kt index ba2758da727..d97e9efa914 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/application/CreatePluginUtils.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/application/CreatePluginUtils.kt @@ -25,6 +25,9 @@ import io.ktor.util.pipeline.* * * You can learn more from [Custom plugins](https://ktor.io/docs/custom-plugins.html). * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.createApplicationPlugin) + * * @param name A name of a plugin that is used to get its instance. * @param configurationPath is path in configuration file to configuration of this plugin. * @param createConfiguration Defines how the initial [PluginConfigT] of your new plugin can be created. @@ -56,6 +59,9 @@ public fun createApplicationPlugin( * * You can learn more from [Custom plugins](https://ktor.io/docs/custom-plugins.html). * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.createApplicationPlugin) + * * @param name A name of a plugin that is used to get its instance. * @param createConfiguration Defines how the initial [PluginConfigT] of your new plugin can be created. * Note that it may be modified later when a user of your plugin calls [Application.install]. @@ -102,6 +108,9 @@ private class ApplicationPluginImpl( * * You can learn more from [Custom plugins](https://ktor.io/docs/custom-plugins.html). * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.createRouteScopedPlugin) + * * @param name A name of a plugin that is used to get its instance * when it is installed to [io.ktor.server.routing.RoutingRoot]. * @param createConfiguration Defines how the initial [PluginConfigT] of your new plugin can be created. Please @@ -133,6 +142,9 @@ public fun createRouteScopedPlugin( * * You can learn more from [Custom plugins](https://ktor.io/docs/custom-plugins.html). * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.createRouteScopedPlugin) + * * @param name A name of a plugin that is used to get its instance * when it is installed to [io.ktor.server.routing.RoutingRoot]. * @param configurationPath is path in configuration file to configuration of this plugin. @@ -187,6 +199,9 @@ private class RouteScopedPluginImpl( * * You can learn more from [Custom plugins](https://ktor.io/docs/custom-plugins.html). * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.createApplicationPlugin) + * * @param name A name of a plugin that is used to get an instance of the plugin installed to the [Application]. * @param body Allows you to define handlers ([onCall], [onCallReceive], [onCallRespond] and so on) that * can modify the behaviour of an [Application] where your plugin is installed. @@ -214,6 +229,9 @@ public fun createApplicationPlugin( * * You can learn more from [Custom plugins](https://ktor.io/docs/custom-plugins.html). * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.createRouteScopedPlugin) + * * @param name A name of a plugin that is used to get an instance of the plugin installed to the [io.ktor.server.routing.RoutingNode]. * @param body Allows you to define handlers ([onCall], [onCallReceive], [onCallRespond] and so on) that * can modify the behaviour of an [Application] where your plugin is installed. diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/application/DefaultApplicationEvents.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/application/DefaultApplicationEvents.kt index 3ab770efe49..30a8e0b51eb 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/application/DefaultApplicationEvents.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/application/DefaultApplicationEvents.kt @@ -14,30 +14,42 @@ import kotlin.native.concurrent.* * * Note, that application itself cannot receive this event because it fires before application is created * It is meant to be used by engines. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationStarting) */ public val ApplicationStarting: EventDefinition = EventDefinition() /** * Event definition for Application Started event + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationStarted) */ public val ApplicationStarted: EventDefinition = EventDefinition() /** * Fired when the server is ready to accept connections + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ServerReady) */ public val ServerReady: EventDefinition = EventDefinition() /** * Event definition for an event that is fired when the application is going to stop + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationStopPreparing) */ public val ApplicationStopPreparing: EventDefinition = EventDefinition() /** * Event definition for Application Stopping event + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationStopping) */ public val ApplicationStopping: EventDefinition = EventDefinition() /** * Event definition for Application Stopped event + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationStopped) */ public val ApplicationStopped: EventDefinition = EventDefinition() diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/application/Hook.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/application/Hook.kt index fc2ac30a605..b2df7f0c4ab 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/application/Hook.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/application/Hook.kt @@ -8,11 +8,15 @@ import io.ktor.utils.io.* /** * A hook that can be registered in [PluginBuilder]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.Hook) */ @KtorDsl public interface Hook { /** * Specifies how to install a hook in the [pipeline]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.Hook.install) */ public fun install(pipeline: ApplicationCallPipeline, handler: HookHandler) } diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/application/KtorCallContexts.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/application/KtorCallContexts.kt index dc74db9cd96..dc1f4d99ca1 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/application/KtorCallContexts.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/application/KtorCallContexts.kt @@ -13,6 +13,8 @@ import io.ktor.utils.io.* * The context associated with the call that is currently being processed by server. * Every call handler ([PluginBuilder.onCall], [PluginBuilder.onCallReceive], [PluginBuilder.onCallRespond], and so on) * of your plugin has a derivative of [CallContext] as a receiver. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.CallContext) **/ @KtorDsl public open class CallContext internal constructor( @@ -27,6 +29,9 @@ public open class CallContext internal constructor( * A context associated with the call handling by your application. [OnCallContext] is a receiver for [PluginBuilder.onCall] handler * of your [PluginBuilder]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.OnCallContext) + * * @see CallContext **/ @KtorDsl @@ -37,6 +42,8 @@ public class OnCallContext internal constructor( /** * Contains type information about the current request or response body when performing a transformation. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.TransformBodyContext) * */ @KtorDsl public class TransformBodyContext(public val requestedType: TypeInfo?) @@ -45,6 +52,9 @@ public class TransformBodyContext(public val requestedType: TypeInfo?) * A context associated with the call.receive() action. Allows you to transform the received body. * [OnCallReceiveContext] is a receiver for [PluginBuilder.onCallReceive] handler of your [PluginBuilder]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.OnCallReceiveContext) + * * @see CallContext **/ @KtorDsl @@ -55,6 +65,8 @@ public class OnCallReceiveContext internal constructor( /** * Specifies how to transform a request body that is being received from a client. * If another plugin has already made the transformation, then your [transformBody] handler is not executed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.OnCallReceiveContext.transformBody) **/ public suspend fun transformBody(transform: suspend TransformBodyContext.(body: ByteReadChannel) -> Any) { val receiveBody = context.subject as? ByteReadChannel ?: return @@ -69,6 +81,9 @@ public class OnCallReceiveContext internal constructor( * A context associated with the call.respond() action. Allows you to transform the response body. * [OnCallRespondContext] is a receiver for [PluginBuilder.onCallRespond] handler of your [PluginBuilder]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.OnCallRespondContext) + * * @see CallContext **/ @KtorDsl @@ -78,6 +93,8 @@ public class OnCallRespondContext internal constructor( ) : CallContext(pluginConfig, context) { /** * Specifies how to transform a response body that is being sent to a client. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.OnCallRespondContext.transformBody) **/ public suspend fun transformBody(transform: suspend TransformBodyContext.(body: Any) -> Any) { val transformContext = TransformBodyContext(context.call.response.responseType) diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/application/PipelineCall.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/application/PipelineCall.kt index b4365f24f66..77afed23d1d 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/application/PipelineCall.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/application/PipelineCall.kt @@ -20,37 +20,53 @@ private val RECEIVE_TYPE_KEY: AttributeKey = AttributeKey("ReceiveType /** * A single act of communication between a client and server. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationCall) + * * @see [io.ktor.server.request.ApplicationRequest] * @see [io.ktor.server.response.ApplicationResponse] */ public interface ApplicationCall : CoroutineScope { /** * [Attributes] attached to this call. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationCall.attributes) */ public val attributes: Attributes /** * An [ApplicationRequest] that is a client request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationCall.request) */ public val request: ApplicationRequest /** * An [PipelineResponse] that is a server response. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationCall.response) */ public val response: ApplicationResponse /** * An application being called. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationCall.application) */ public val application: Application /** * Parameters associated with this call. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationCall.parameters) */ public val parameters: Parameters /** * Receives content for this request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationCall.receiveNullable) + * * @param typeInfo instance specifying type to be received. * @return instance of [T] received from this call. * @throws ContentTransformationException when content cannot be transformed to the requested type. @@ -59,6 +75,9 @@ public interface ApplicationCall : CoroutineScope { /** * Sends a [message] as a response. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationCall.respond) + * * @see [io.ktor.server.response.PipelineResponse] */ public suspend fun respond(message: Any?, typeInfo: TypeInfo?) @@ -66,6 +85,9 @@ public interface ApplicationCall : CoroutineScope { /** * A single act of communication between a client and server. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.PipelineCall) + * * @see [io.ktor.server.request.PipelineRequest] * @see [io.ktor.server.response.PipelineResponse] */ @@ -73,11 +95,15 @@ public interface PipelineCall : ApplicationCall { /** * An [PipelineRequest] that is a client request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.PipelineCall.request) */ public override val request: PipelineRequest /** * An [PipelineResponse] that is a server response. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.PipelineCall.response) */ public override val response: PipelineResponse @@ -109,11 +135,15 @@ public interface PipelineCall : ApplicationCall { /** * Indicates if a response is sent. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.isHandled) */ public val ApplicationCall.isHandled: Boolean get() = response.isCommitted /** * The [TypeInfo] recorded from the last [call.receive()] call. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.receiveType) */ public var ApplicationCall.receiveType: TypeInfo get() = attributes[RECEIVE_TYPE_KEY] @@ -123,5 +153,7 @@ public var ApplicationCall.receiveType: TypeInfo /** * Convenience extension property for pipeline interceptors with Application call contexts. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.call) */ public val PipelineContext<*, C>.call: C get() = context diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/application/PluginBuilder.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/application/PluginBuilder.kt index 2fa5053c7bf..8024d4e16b0 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/application/PluginBuilder.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/application/PluginBuilder.kt @@ -16,6 +16,8 @@ import kotlin.random.* /** * A utility class to build an [ApplicationPlugin] instance. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.PluginBuilder) **/ @KtorDsl @Suppress("UNUSED_PARAMETER", "DEPRECATION") @@ -25,11 +27,15 @@ public abstract class PluginBuilder internal constructor( /** * A reference to the [Application] where the plugin is installed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.PluginBuilder.application) */ public abstract val application: Application /** * A configuration of the current plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.PluginBuilder.pluginConfig) */ public abstract val pluginConfig: PluginConfig @@ -41,12 +47,16 @@ public abstract class PluginBuilder internal constructor( /** * Allows you to access the environment of the currently running application where the plugin is installed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.PluginBuilder.environment) **/ public val environment: ApplicationEnvironment get() = pipeline.environment /** * A configuration of your current application (incl. host, port and anything else you can define in * application.conf). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.PluginBuilder.applicationConfig) **/ public val applicationConfig: ApplicationConfig get() = environment.config @@ -76,6 +86,9 @@ public abstract class PluginBuilder internal constructor( * } * ``` * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.PluginBuilder.onCall) + * * @see [createApplicationPlugin] * * @param block An action that needs to be executed when your application receives an HTTP call. @@ -94,6 +107,9 @@ public abstract class PluginBuilder internal constructor( /** * Specifies the [block] handler that allows you to obtain and transform data received from the client. * This [block] is invoked for every attempt to receive the request body. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.PluginBuilder.onCallReceive) + * * @see [createApplicationPlugin] * * @param block An action that needs to be executed when your application receives data from a client. @@ -112,6 +128,9 @@ public abstract class PluginBuilder internal constructor( /** * Specifies the [block] handler that allows you to transform data before sending it to the client. * This handler is executed when the `call.respond` function is invoked in a route handler. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.PluginBuilder.onCallRespond) + * * @see [createApplicationPlugin] * * @param block An action that needs to be executed when your server is sending a response to a client. @@ -132,6 +151,9 @@ public abstract class PluginBuilder internal constructor( * Specifies a [handler] for a specific [hook]. * A [hook] can be a specific place in time or event during the request * processing like application shutdown, an exception during call processing, etc. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.PluginBuilder.on) + * * @see [createApplicationPlugin] * * Example: @@ -155,6 +177,9 @@ public abstract class PluginBuilder internal constructor( /** * Specifies the [block] handler that allows you to obtain and transform data received from the client. * This [block] is invoked for every attempt to receive the request body. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.PluginBuilder.onCallReceive) + * * @see [createApplicationPlugin] * * @param block An action that needs to be executed when your application receives data from a client. @@ -168,6 +193,9 @@ public abstract class PluginBuilder internal constructor( /** * Specifies the [block] handler that allows you to transform data before sending it to the client. * This handler is executed when the `call.respond` function is invoked in a route handler. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.PluginBuilder.onCallRespond) + * * @see [createApplicationPlugin] * * @param block An action that needs to be executed when your server is sending a response to a client. diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/application/PluginExceptions.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/application/PluginExceptions.kt index 6cbb704ba17..25fbe053b21 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/application/PluginExceptions.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/application/PluginExceptions.kt @@ -6,6 +6,8 @@ package io.ktor.server.application /** * An exception that is thrown when the current body in the HTTP pipeline is invalid. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.InvalidBodyException) */ public class InvalidBodyException(message: String) : Exception(message) diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/application/PluginInstance.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/application/PluginInstance.kt index 6f48d437758..1192b54a81c 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/application/PluginInstance.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/application/PluginInstance.kt @@ -6,5 +6,7 @@ package io.ktor.server.application /** * An instance of the plugin installed to your application. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.PluginInstance) * */ public class PluginInstance internal constructor(internal val builder: PluginBuilder<*>) diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/application/RouteScopedPlugin.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/application/RouteScopedPlugin.kt index 7cf579e4f81..13ddd91aa31 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/application/RouteScopedPlugin.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/application/RouteScopedPlugin.kt @@ -8,6 +8,9 @@ import io.ktor.server.routing.* /** * Defines a [Plugin](https://ktor.io/docs/plugins.html) that can be installed into a [RoutingNode]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.BaseRouteScopedPlugin) + * * @param TConfiguration is the configuration object type for this Plugin * @param TPlugin is the instance type of the Plugin object */ @@ -16,6 +19,9 @@ public interface BaseRouteScopedPlugin : /** * Defines a Plugin that can be installed into [RoutingNode] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.RouteScopedPlugin) + * * @param TConfiguration is the configuration object type for this Plugin */ public interface RouteScopedPlugin : BaseRouteScopedPlugin @@ -23,6 +29,9 @@ public interface RouteScopedPlugin : BaseRouteScopedPlugin /** * Finds the plugin [F] in the current [RoutingNode]. If not found, search in the parent [RoutingNode]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.findPluginInRoute) + * * @return [F] instance or `null` if not found */ public fun RoutingNode.findPluginInRoute(plugin: Plugin<*, *, F>): F? { diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/application/RouteScopedPluginBuilder.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/application/RouteScopedPluginBuilder.kt index 2533a03f78a..9c834920210 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/application/RouteScopedPluginBuilder.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/application/RouteScopedPluginBuilder.kt @@ -9,12 +9,16 @@ import io.ktor.util.* /** * Utility class to build a [RouteScopedPlugin] instance. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.RouteScopedPluginBuilder) **/ public abstract class RouteScopedPluginBuilder(key: AttributeKey) : PluginBuilder(key) { /** * A [RoutingNode] to which this plugin was installed. Can be `null` if plugin in installed into [Application]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.RouteScopedPluginBuilder.route) **/ public abstract val route: RoutingNode? } diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/application/hooks/CommonHooks.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/application/hooks/CommonHooks.kt index 8bab62fa1b4..2fcfaeaf299 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/application/hooks/CommonHooks.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/application/hooks/CommonHooks.kt @@ -19,6 +19,8 @@ import kotlin.reflect.* /** * A hook that is invoked as a first step in processing a call. * Useful for validating, updating a call based on proxy information, etc. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.hooks.CallSetup) */ public object CallSetup : Hook Unit> { override fun install(pipeline: ApplicationCallPipeline, handler: suspend (ApplicationCall) -> Unit) { @@ -30,6 +32,8 @@ public object CallSetup : Hook Unit> { /** * A hook that is invoked when a call fails with an exception. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.hooks.CallFailed) */ public object CallFailed : Hook Unit> { @@ -54,6 +58,8 @@ public object CallFailed : Hook>( private val event: Event @@ -75,6 +81,8 @@ public class MonitoringEvent>( * Useful for metrics, logging, etc. * * Can be renamed or removed from public API in the future. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.hooks.Metrics) */ @InternalAPI public object Metrics : Hook Unit> { @@ -87,6 +95,8 @@ public object Metrics : Hook Unit> { /** * A hook that is invoked when a response body comes through all transformations and is ready to be sent. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.hooks.ResponseBodyReadyForSend) */ public object ResponseBodyReadyForSend : Hook Unit> { @@ -109,6 +119,8 @@ public object ResponseBodyReadyForSend : /** * A hook that is invoked when response was successfully sent to a client. * Useful for cleaning up opened resources or finishing measurements. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.hooks.ResponseSent) */ public object ResponseSent : Hook<(ApplicationCall) -> Unit> { override fun install(pipeline: ApplicationCallPipeline, handler: (ApplicationCall) -> Unit) { @@ -121,6 +133,8 @@ public object ResponseSent : Hook<(ApplicationCall) -> Unit> { /** * A hook that is invoked when a request is about to be received. It gives control over the raw request body. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.hooks.ReceiveRequestBytes) */ public object ReceiveRequestBytes : Hook<(call: ApplicationCall, body: ByteReadChannel) -> ByteReadChannel> { override fun install( @@ -138,6 +152,8 @@ public object ReceiveRequestBytes : Hook<(call: ApplicationCall, body: ByteReadC /** * A hook that is invoked before `Transform` phase. * Useful for some plugins which used for templates as views within application. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.hooks.BeforeResponseTransform) */ @InternalAPI public class BeforeResponseTransform(private val clazz: KClass) : diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/config/ApplicationConfig.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/config/ApplicationConfig.kt index 2765910fca0..9cd6825e8df 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/config/ApplicationConfig.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/config/ApplicationConfig.kt @@ -6,27 +6,40 @@ package io.ktor.server.config /** * Represents an application config node + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.config.ApplicationConfig) */ public interface ApplicationConfig { /** * Get config property with [path] or fail + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.config.ApplicationConfig.property) + * * @throws ApplicationConfigurationException */ public fun property(path: String): ApplicationConfigValue /** * Get config property value for [path] or return `null` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.config.ApplicationConfig.propertyOrNull) */ public fun propertyOrNull(path: String): ApplicationConfigValue? /** * Get config child node or fail + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.config.ApplicationConfig.config) + * * @throws ApplicationConfigurationException */ public fun config(path: String): ApplicationConfig /** * Get a list of child nodes for [path] or fail + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.config.ApplicationConfig.configList) + * * @throws ApplicationConfigurationException */ public fun configList(path: String): List @@ -36,6 +49,9 @@ public interface ApplicationConfig { * All entries represent leaf nodes' keys, meaning that there would be no nested * objects directly included as values for returned keys. * It's still possible that entries may be a list and the lists may contain objects. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.config.ApplicationConfig.keys) + * * @return set of paths with non-null values, built up by recursing the entire tree of * config and creating an entry for each leaf value. */ @@ -44,27 +60,37 @@ public interface ApplicationConfig { /** * Returns map representation of this config. * Values can be `String`, `Map`, `List` and `List>` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.config.ApplicationConfig.toMap) */ public fun toMap(): Map } /** * Represents an application config value + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.config.ApplicationConfigValue) */ public interface ApplicationConfigValue { /** * Get property string value + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.config.ApplicationConfigValue.getString) */ public fun getString(): String /** * Get property list value + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.config.ApplicationConfigValue.getList) */ public fun getList(): List } /** * Thrown when an application is misconfigured + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.config.ApplicationConfigurationException) */ public class ApplicationConfigurationException(message: String, cause: Throwable?) : Exception(message, cause) { public constructor(message: String) : this(message, null) @@ -73,6 +99,9 @@ public class ApplicationConfigurationException(message: String, cause: Throwable /** * Try read String value from [ApplicationConfig]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.config.tryGetString) + * * @return null if key is missing */ public fun ApplicationConfig.tryGetString(key: String): String? = @@ -81,6 +110,9 @@ public fun ApplicationConfig.tryGetString(key: String): String? = /** * Try read String value from [ApplicationConfig]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.config.tryGetStringList) + * * @return null if key is missing */ public fun ApplicationConfig.tryGetStringList(key: String): List? = diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/config/ConfigLoaders.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/config/ConfigLoaders.kt index 8f5fb846f61..6f4afa27947 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/config/ConfigLoaders.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/config/ConfigLoaders.kt @@ -10,11 +10,16 @@ internal expect val CONFIG_PATH: List * Loads an application configuration. * An implementation of this interface should return [ApplicationConfig] if applicable configuration is found * or `null` otherwise. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.config.ConfigLoader) */ public interface ConfigLoader { /** * Tries loading an application configuration from the specified [path]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.config.ConfigLoader.load) + * * @return configuration or null if the path is not found or configuration format is not supported. */ public fun load(path: String?): ApplicationConfig? @@ -22,6 +27,8 @@ public interface ConfigLoader { public companion object { /** * Find and load a configuration file to [ApplicationConfig]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.config.ConfigLoader.Companion.load) */ public fun load(path: String? = null): ApplicationConfig { if (path == null) { @@ -52,5 +59,7 @@ public interface ConfigLoader { /** * List of all registered [ConfigLoader] implementations. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.config.configLoaders) */ public expect val configLoaders: List diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/config/MapApplicationConfig.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/config/MapApplicationConfig.kt index 3acdc0dd27f..a457fe8ad3e 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/config/MapApplicationConfig.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/config/MapApplicationConfig.kt @@ -6,6 +6,8 @@ package io.ktor.server.config /** * Mutable application config backed by a hash map + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.config.MapApplicationConfig) */ public open class MapApplicationConfig : ApplicationConfig { /** @@ -34,6 +36,8 @@ public open class MapApplicationConfig : ApplicationConfig { /** * Set property value + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.config.MapApplicationConfig.put) */ public fun put(path: String, value: String) { map[combine(this.path, path)] = value @@ -41,6 +45,8 @@ public open class MapApplicationConfig : ApplicationConfig { /** * Put list property value + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.config.MapApplicationConfig.put) */ public fun put(path: String, values: Iterable) { var size = 0 diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/config/MergedApplicationConfig.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/config/MergedApplicationConfig.kt index cad7ed19e6d..23f810383e9 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/config/MergedApplicationConfig.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/config/MergedApplicationConfig.kt @@ -7,6 +7,8 @@ package io.ktor.server.config /** * Merge configuration combining all their keys. * If key is not found in one of the configs, search will continue in the next config in the list. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.config.merge) */ @Deprecated( "Use mergeWith/withFallback instead.", @@ -21,6 +23,9 @@ public fun List.merge(): ApplicationConfig { * Merge configuration combining all their keys. * If the key exists in this and [other] config, the value from the [other] config will be used. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.config.mergeWith) + * * @see [withFallback] */ public fun ApplicationConfig.mergeWith(other: ApplicationConfig): ApplicationConfig { @@ -31,6 +36,9 @@ public fun ApplicationConfig.mergeWith(other: ApplicationConfig): ApplicationCon * Merge configuration combining all their keys. * If the key exists in this and [other] config, the value from this config will be used. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.config.withFallback) + * * @see [mergeWith] */ public fun ApplicationConfig.withFallback(other: ApplicationConfig): ApplicationConfig { diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/ApplicationEngine.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/ApplicationEngine.kt index 0869b5c33fb..92f8c666179 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/ApplicationEngine.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/ApplicationEngine.kt @@ -10,51 +10,71 @@ import kotlinx.coroutines.* /** * An engine which runs an application. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ApplicationEngine) */ public interface ApplicationEngine { /** * A configuration for the [ApplicationEngine]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ApplicationEngine.Configuration) */ @Suppress("MemberVisibilityCanBePrivate") public open class Configuration { /** * Returns the current parallelism level (e.g. the number of available processors). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ApplicationEngine.Configuration.parallelism) */ public val parallelism: Int = availableProcessorsBridge() /** * Specifies how many threads are used to accept new connections and start call processing. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ApplicationEngine.Configuration.connectionGroupSize) */ public var connectionGroupSize: Int = parallelism / 2 + 1 /** * Specifies size of the event group for processing connections, parsing messages and doing engine's internal work + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ApplicationEngine.Configuration.workerGroupSize) */ public var workerGroupSize: Int = parallelism / 2 + 1 /** * Specifies the minimum size of a thread pool used to process application calls. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ApplicationEngine.Configuration.callGroupSize) */ public var callGroupSize: Int = parallelism /** * Specifies the maximum amount of time in milliseconds for activity to cool down + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ApplicationEngine.Configuration.shutdownGracePeriod) */ public var shutdownGracePeriod: Long = 1000 /** * Specifies the maximum amount of time in milliseconds to wait until server stops gracefully + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ApplicationEngine.Configuration.shutdownTimeout) */ public var shutdownTimeout: Long = 5000 /** * List of connectors describing where and how the server should listen. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ApplicationEngine.Configuration.connectors) */ public var connectors: MutableList = mutableListOf() /** * Uses [other] configuration and overrides this with its values. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ApplicationEngine.Configuration.takeFrom) */ public fun takeFrom(other: Configuration) { connectionGroupSize = other.connectionGroupSize @@ -71,17 +91,24 @@ public interface ApplicationEngine { * If [environment]'s [connector]s was configured to use port=0, you can use this function to get an actual port * for these connectors. * Available after a server is started. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ApplicationEngine.resolvedConnectors) */ public suspend fun resolvedConnectors(): List /** * An environment used to run this engine. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ApplicationEngine.environment) */ public val environment: ApplicationEnvironment /** * Starts this [ApplicationEngine]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ApplicationEngine.start) + * * @param wait if true, then the `start` call blocks a current thread until it finishes its execution. * If you run `start` from the main thread with `wait = false` and nothing else blocking this thread, * then your application will be terminated without handling any requests. @@ -92,6 +119,9 @@ public interface ApplicationEngine { /** * Starts this [ApplicationEngine]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ApplicationEngine.startSuspend) + * * @param wait if true, then the `start` call blocks a current thread until it finishes its execution. * If you run `start` from the main thread with `wait = false` and nothing else blocking this thread, * then your application will be terminated without handling any requests. @@ -104,6 +134,9 @@ public interface ApplicationEngine { /** * Stops this [ApplicationEngine]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ApplicationEngine.stop) + * * @param gracePeriodMillis the maximum amount of time for activity to cool down * @param timeoutMillis the maximum amount of time to wait until a server stops gracefully */ @@ -112,6 +145,9 @@ public interface ApplicationEngine { /** * Stops this [ApplicationEngine]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ApplicationEngine.stopSuspend) + * * @param gracePeriodMillis the maximum amount of time for activity to cool down * @param timeoutMillis the maximum amount of time to wait until a server stops gracefully */ diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/ApplicationEnvironmentBuilder.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/ApplicationEnvironmentBuilder.kt index c281b4a3866..a7eee02cb80 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/ApplicationEnvironmentBuilder.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/ApplicationEnvironmentBuilder.kt @@ -15,22 +15,30 @@ import kotlin.coroutines.* /** * Engine environment configuration builder + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ApplicationEnvironmentBuilder) */ @KtorDsl public expect class ApplicationEnvironmentBuilder() { /** * Application logger + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ApplicationEnvironmentBuilder.log) */ public var log: Logger /** * Application config + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ApplicationEnvironmentBuilder.config) */ public var config: ApplicationConfig /** * Build an application engine environment + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ApplicationEnvironmentBuilder.build) */ public fun build(): ApplicationEnvironment } diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/BaseApplicationCall.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/BaseApplicationCall.kt index 3d351834ba9..838f8077530 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/BaseApplicationCall.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/BaseApplicationCall.kt @@ -10,6 +10,8 @@ import io.ktor.util.* /** * Base class for implementing an [PipelineCall]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.BaseApplicationCall) */ public abstract class BaseApplicationCall(final override val application: Application) : PipelineCall { public final override val attributes: Attributes = Attributes() diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/BaseApplicationEngine.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/BaseApplicationEngine.kt index f9d8546de0f..30220aa3fbe 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/BaseApplicationEngine.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/BaseApplicationEngine.kt @@ -23,6 +23,9 @@ import kotlinx.coroutines.* * It creates default engine pipeline, provides [application] property and installs default transformations * on respond and receive * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.BaseApplicationEngine) + * * @param environment instance of [ApplicationEnvironment] for this engine * @param pipeline pipeline to use with this engine */ @@ -35,6 +38,8 @@ public abstract class BaseApplicationEngine( /** * Configuration for the [BaseApplicationEngine]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.BaseApplicationEngine.Configuration) */ public open class Configuration : ApplicationEngine.Configuration() diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/BaseApplicationRequest.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/BaseApplicationRequest.kt index c9094036015..6f26c1f4868 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/BaseApplicationRequest.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/BaseApplicationRequest.kt @@ -12,6 +12,8 @@ import kotlinx.atomicfu.* /** * Base class for implementing [PipelineRequest] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.BaseApplicationRequest) */ public abstract class BaseApplicationRequest(final override val call: PipelineCall) : PipelineRequest { diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/BaseApplicationResponse.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/BaseApplicationResponse.kt index b5c25dc2698..66a397d223d 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/BaseApplicationResponse.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/BaseApplicationResponse.kt @@ -246,12 +246,16 @@ public abstract class BaseApplicationResponse( /** * Thrown when there was already response sent but we are trying to respond again + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.BaseApplicationResponse.ResponseAlreadySentException) */ public class ResponseAlreadySentException : IllegalStateException("Response has already been sent") /** * [OutgoingContent] is trying to set some header that is not allowed for this content type. * For example, only upgrade content can set `Upgrade` header. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.BaseApplicationResponse.InvalidHeaderForContent) */ @OptIn(ExperimentalCoroutinesApi::class) public class InvalidHeaderForContent( @@ -266,6 +270,8 @@ public abstract class BaseApplicationResponse( /** * Content's body size doesn't match the provided one in `Content-Length` header + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.BaseApplicationResponse.BodyLengthIsTooSmall) */ @OptIn(ExperimentalCoroutinesApi::class) public class BodyLengthIsTooSmall( @@ -280,6 +286,8 @@ public abstract class BaseApplicationResponse( /** * Content's body size doesn't match the provided one in `Content-Length` header + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.BaseApplicationResponse.BodyLengthIsTooLong) */ @OptIn(ExperimentalCoroutinesApi::class) public class BodyLengthIsTooLong( @@ -295,6 +303,8 @@ public abstract class BaseApplicationResponse( * Attribute key to access engine's response instance. * This is engine internal API and should be never used by end-users * unless you are writing your own engine implementation + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.BaseApplicationResponse.Companion.EngineResponseAttributeKey) */ public val EngineResponseAttributeKey: AttributeKey = AttributeKey("EngineResponse") @@ -302,6 +312,8 @@ public abstract class BaseApplicationResponse( /** * Install an application-wide send pipeline interceptor into [ApplicationSendPipeline.Engine] phase * to start response object processing via [respondOutgoingContent] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.BaseApplicationResponse.Companion.setupSendPipeline) */ public fun setupSendPipeline(sendPipeline: ApplicationSendPipeline) { sendPipeline.intercept(ApplicationSendPipeline.Engine) { body -> diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/CommandLine.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/CommandLine.kt index be3e8908a8c..bad93ac9215 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/CommandLine.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/CommandLine.kt @@ -34,6 +34,8 @@ public object ConfigKeys { /** * Creates an [ApplicationEnvironment] instance from command line arguments + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.CommandLineConfig) */ public fun CommandLineConfig(args: Array): CommandLineConfig { val argumentsPairs = args.mapNotNull { it.splitPair('=') } @@ -140,6 +142,9 @@ internal expect fun clearEnvironmentProperty(key: String) /** * Loads common engine configuration parameters applicable to all engine types from the specified [ApplicationConfig]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.loadCommonConfiguration) + * * @param deploymentConfig The application configuration. */ public fun ApplicationEngine.Configuration.loadCommonConfiguration(deploymentConfig: ApplicationConfig) { diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/DefaultEnginePipeline.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/DefaultEnginePipeline.kt index 8de0a67a2b4..dd0476dafc6 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/DefaultEnginePipeline.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/DefaultEnginePipeline.kt @@ -22,6 +22,8 @@ import kotlinx.io.IOException /** * Default engine pipeline for all engines. Use it only if you are writing your own application engine implementation. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.defaultEnginePipeline) */ public fun defaultEnginePipeline(config: ApplicationConfig, developmentMode: Boolean): EnginePipeline { val pipeline = EnginePipeline(developmentMode) @@ -50,6 +52,8 @@ public fun defaultEnginePipeline(config: ApplicationConfig, developmentMode: Boo /** * Logs the [error] and responds with an appropriate error status code. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.handleFailure) */ public suspend fun handleFailure(call: ApplicationCall, error: Throwable) { logError(call, error) @@ -58,6 +62,8 @@ public suspend fun handleFailure(call: ApplicationCall, error: Throwable) { /** * Logs the [error] with MDC setup. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.logError) */ public suspend fun logError(call: ApplicationCall, error: Throwable) { call.application.mdcProvider.withMDCBlock(call) { @@ -67,6 +73,8 @@ public suspend fun logError(call: ApplicationCall, error: Throwable) { /** * Map [cause] to the corresponding status code or `null` if no default exception mapping for this [cause] type + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.defaultExceptionStatusCode) */ public fun defaultExceptionStatusCode(cause: Throwable): HttpStatusCode? { return when (cause) { diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/DefaultTransform.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/DefaultTransform.kt index 0c59533899f..a8f6b0c80ef 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/DefaultTransform.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/DefaultTransform.kt @@ -22,6 +22,8 @@ internal val LOGGER = KtorSimpleLogger("io.ktor.server.engine.DefaultTransform") /** * Default send transformation + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.installDefaultTransformations) */ public fun ApplicationSendPipeline.installDefaultTransformations() { intercept(ApplicationSendPipeline.Render) { value -> @@ -32,6 +34,8 @@ public fun ApplicationSendPipeline.installDefaultTransformations() { /** * Default receive transformation + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.installDefaultTransformations) */ public fun ApplicationReceivePipeline.installDefaultTransformations() { intercept(ApplicationReceivePipeline.Transform) { body -> diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/DefaultUncaughtExceptionHandler.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/DefaultUncaughtExceptionHandler.kt index 2626d89efff..1d3ca9d94ca 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/DefaultUncaughtExceptionHandler.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/DefaultUncaughtExceptionHandler.kt @@ -13,6 +13,8 @@ import kotlin.coroutines.* /** * Handles all uncaught exceptions and logs errors with the specified [logger] * ignoring [CancellationException] and [IOException]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.DefaultUncaughtExceptionHandler) */ public class DefaultUncaughtExceptionHandler( private val logger: () -> Logger diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/EmbeddedServer.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/EmbeddedServer.kt index 05cc99fb901..0364a2e1a76 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/EmbeddedServer.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/EmbeddedServer.kt @@ -15,6 +15,9 @@ import kotlin.coroutines.* * Represents an embedded server that hosts an application. * It's an entry point to the application and handles the lifecycle of the application engine. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.EmbeddedServer) + * * @param TEngine The type of the application engine used by the server. * @param TConfiguration The type of the configuration used by the engine. */ @@ -25,6 +28,8 @@ public expect class EmbeddedServer embeddedServer( @@ -85,6 +96,8 @@ public fun CoroutineScope.embeddedServer( @@ -112,6 +125,8 @@ public fun CoroutineScope.embeddedServer( @@ -138,6 +153,8 @@ public fun embeddedServer( factory: ApplicationEngineFactory, @@ -153,6 +170,8 @@ public fun embeddedServer( factory: ApplicationEngineFactory, diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/EngineConnectorConfig.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/EngineConnectorConfig.kt index fc89a84a2c1..1b67dc088c7 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/EngineConnectorConfig.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/EngineConnectorConfig.kt @@ -6,6 +6,9 @@ package io.ktor.server.engine /** * Represents a type of a connector, e.g HTTP or HTTPS. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ConnectorType) + * * @param name name of the connector. * * Some engines can support other connector types, hence not a enum. @@ -14,11 +17,15 @@ public data class ConnectorType(val name: String) { public companion object { /** * Non-secure HTTP connector. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ConnectorType.Companion.HTTP) */ public val HTTP: ConnectorType = ConnectorType("HTTP") /** * Secure HTTP connector. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ConnectorType.Companion.HTTPS) */ public val HTTPS: ConnectorType = ConnectorType("HTTPS") } @@ -26,26 +33,36 @@ public data class ConnectorType(val name: String) { /** * Represents a connector configuration. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.EngineConnectorConfig) */ public interface EngineConnectorConfig { /** * Type of the connector, e.g HTTP or HTTPS. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.EngineConnectorConfig.type) */ public val type: ConnectorType /** * The network interface this host binds to as an IP address or a hostname. If null or 0.0.0.0, then bind to all interfaces. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.EngineConnectorConfig.host) */ public val host: String /** * The port this application should be bound to. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.EngineConnectorConfig.port) */ public val port: Int } /** * Adds a non-secure connector to this engine environment + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.connector) */ public inline fun ApplicationEngine.Configuration.connector(builder: EngineConnectorBuilder.() -> Unit) { connectors.add(EngineConnectorBuilder().apply(builder)) @@ -53,6 +70,8 @@ public inline fun ApplicationEngine.Configuration.connector(builder: EngineConne /** * Mutable implementation of EngineConnectorConfig for building connectors programmatically + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.EngineConnectorBuilder) */ public open class EngineConnectorBuilder( override val type: ConnectorType = ConnectorType.HTTP @@ -67,5 +86,7 @@ public open class EngineConnectorBuilder( /** * Returns new instance of [EngineConnectorConfig] based on [this] with modified port + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.withPort) */ public expect fun EngineConnectorConfig.withPort(otherPort: Int): EngineConnectorConfig diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/EngineContextCancellationHelper.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/EngineContextCancellationHelper.kt index 9703e936bbd..792420bc5cf 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/EngineContextCancellationHelper.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/EngineContextCancellationHelper.kt @@ -11,6 +11,8 @@ import kotlinx.coroutines.* /** * Stop server on job cancellation. The returned [CompletableJob] needs to be completed or cancelled. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.stopServerOnCancellation) */ @OptIn(InternalAPI::class) public fun ApplicationEngine.stopServerOnCancellation( @@ -26,6 +28,8 @@ public fun ApplicationEngine.stopServerOnCancellation( * Launch a coroutine with [block] body when either the parent job or the returned job is cancelled. * It is important to complete or cancel the returned [CompletableJob] * otherwise the parent job will be unable to complete successfully. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.launchOnCancellation) */ @OptIn(DelicateCoroutinesApi::class) @InternalAPI diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/EnginePipeline.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/EnginePipeline.kt index a63b71c1cd6..90277dad616 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/EnginePipeline.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/EnginePipeline.kt @@ -12,28 +12,38 @@ import io.ktor.util.pipeline.* /** * Application engine pipeline. One usually don't need to install interceptors here unless your are writing * your own engine implementation + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.EnginePipeline) */ public class EnginePipeline( override val developmentMode: Boolean = false ) : Pipeline(Before, Call) { /** * Pipeline for receiving content + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.EnginePipeline.receivePipeline) */ public val receivePipeline: ApplicationReceivePipeline = ApplicationReceivePipeline(developmentMode) /** * Pipeline for sending content + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.EnginePipeline.sendPipeline) */ public val sendPipeline: ApplicationSendPipeline = ApplicationSendPipeline(developmentMode) public companion object { /** * Before call phase + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.EnginePipeline.Companion.Before) */ public val Before: PipelinePhase = PipelinePhase("before") /** * Application call pipeline phase + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.EnginePipeline.Companion.Call) */ public val Call: PipelinePhase = PipelinePhase("call") } diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/ShutdownHook.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/ShutdownHook.kt index a6536d8b27a..38531055a31 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/ShutdownHook.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/engine/ShutdownHook.kt @@ -14,6 +14,8 @@ internal expect val SHUTDOWN_HOOK_ENABLED: Boolean * Please note that a shutdown hook only registered when the application is running. If the application * is already stopped then there will be no hook and no [stop] function invocation possible. * So [stop] block will be called once or never. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.addShutdownHook) */ public fun EmbeddedServer<*, *>.addShutdownHook(stop: () -> Unit) { if (SHUTDOWN_HOOK_ENABLED) { diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/http/LinkHeader.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/http/LinkHeader.kt index f4a92a97029..56c8a37cb83 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/http/LinkHeader.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/http/LinkHeader.kt @@ -9,10 +9,14 @@ import io.ktor.server.response.* /** * Append `Link` header to HTTP response + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.link) */ public fun ApplicationResponse.link(header: LinkHeader): Unit = headers.append(HttpHeaders.Link, header.toString()) /** * Append `Link` header to HTTP response with specified [uri] and [rel] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.link) */ public fun ApplicationResponse.link(uri: String, vararg rel: String): Unit = link(LinkHeader(uri, *rel)) diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/http/Push.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/http/Push.kt index ab479e00a00..501c44b7383 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/http/Push.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/http/Push.kt @@ -14,6 +14,8 @@ import io.ktor.utils.io.* * Produces HTTP/2 push from server to client or sets HTTP/1.x hint header * or does nothing. * Exact behaviour is up to engine implementation. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.push) */ @UseHttp2Push public fun ApplicationCall.push(pathAndQuery: String) { @@ -25,6 +27,8 @@ public fun ApplicationCall.push(pathAndQuery: String) { * Produces HTTP/2 push from server to client or sets HTTP/1.x hint header * or does nothing. * Exact behaviour is up to engine implementation. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.push) */ @UseHttp2Push public fun ApplicationCall.push(encodedPath: String, encodedParameters: Parameters) { @@ -39,6 +43,8 @@ public fun ApplicationCall.push(encodedPath: String, encodedParameters: Paramete * Produces HTTP/2 push from server to client or sets HTTP/1.x hint header * or does nothing (may call or not call [block]). * Exact behaviour is up to engine implementation. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.push) */ @OptIn(InternalAPI::class) @UseHttp2Push diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/http/content/DefaultTransform.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/http/content/DefaultTransform.kt index e1fe1c56f56..a31c1b6e098 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/http/content/DefaultTransform.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/http/content/DefaultTransform.kt @@ -12,6 +12,8 @@ import io.ktor.utils.io.* /** * Default outgoing content transformation + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.transformDefaultContent) */ public fun transformDefaultContent(call: ApplicationCall, value: Any): OutgoingContent? = when (value) { is OutgoingContent -> value diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/http/content/HttpStatusCodeContent.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/http/content/HttpStatusCodeContent.kt index 82b4235c359..d6e0287dfec 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/http/content/HttpStatusCodeContent.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/http/content/HttpStatusCodeContent.kt @@ -9,6 +9,9 @@ import io.ktor.http.content.* /** * Represents a simple status code response with no content + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.HttpStatusCodeContent) + * * @param value - status code to be sent */ public class HttpStatusCodeContent(private val value: HttpStatusCode) : OutgoingContent.NoContent() { diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/http/content/SuppressionAttribute.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/http/content/SuppressionAttribute.kt index 53712f45b8a..f72febb1125 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/http/content/SuppressionAttribute.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/http/content/SuppressionAttribute.kt @@ -9,6 +9,8 @@ import io.ktor.util.* /** * Attribute that could be added to an application call to prevent its response from being compressed + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.SuppressionAttribute) */ @Deprecated( "Please use suppressCompression() and isCompressionSuppressed) instead", @@ -19,6 +21,8 @@ internal val DecompressionSuppressionAttribute: AttributeKey = Attribut /** * Suppress response body compression plugin for this [ApplicationCall]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.suppressCompression) */ @Suppress("DEPRECATION_ERROR") public fun ApplicationCall.suppressCompression() { @@ -27,6 +31,8 @@ public fun ApplicationCall.suppressCompression() { /** * Suppresses the decompression for the current application call. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.suppressDecompression) */ public fun ApplicationCall.suppressDecompression() { attributes.put(DecompressionSuppressionAttribute, true) @@ -34,6 +40,8 @@ public fun ApplicationCall.suppressDecompression() { /** * Checks if response body compression is suppressed for this [ApplicationCall]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.isCompressionSuppressed) */ @Suppress("DEPRECATION_ERROR") public val ApplicationCall.isCompressionSuppressed: Boolean get() = SuppressionAttribute in attributes @@ -43,5 +51,7 @@ public val ApplicationCall.isCompressionSuppressed: Boolean get() = SuppressionA * If decompression is suppressed, the plugin will not decompress the request body. * * To suppress decompression, use [suppressDecompression]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.isDecompressionSuppressed) */ public val ApplicationCall.isDecompressionSuppressed: Boolean get() = DecompressionSuppressionAttribute in attributes diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/logging/Logging.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/logging/Logging.kt index 8edf09d765c..2ec53abc401 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/logging/Logging.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/logging/Logging.kt @@ -11,15 +11,21 @@ import io.ktor.util.* /** * Generates a string representing this [ApplicationRequest] suitable for logging + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.logging.toLogString) */ public fun ApplicationRequest.toLogString(): String = "${httpMethod.value} - ${path()}" /** * Base interface for plugins that can setup MDC. See [CallLogging] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.logging.MDCProvider) */ public interface MDCProvider { /** * Executes [block] with [MDC] setup + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.logging.MDCProvider.withMDCBlock) */ public suspend fun withMDCBlock(call: ApplicationCall, block: suspend () -> Unit) } @@ -31,6 +37,8 @@ private object EmptyMDCProvider : MDCProvider { /** * Returns first instance of a plugin that implements [MDCProvider] * or default implementation with an empty context + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.logging.mdcProvider) */ public val Application.mdcProvider: MDCProvider @Suppress("UNCHECKED_CAST") diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/plugins/Errors.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/plugins/Errors.kt index 8b1393be592..0dd291ca7a1 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/plugins/Errors.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/plugins/Errors.kt @@ -16,6 +16,8 @@ import kotlin.reflect.* * wrong/missing request parameters, body content or header values. * Throwing this exception in a handler will lead to 400 Bad Request response * unless a custom [io.ktor.plugins.StatusPages] handler registered. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.BadRequestException) */ public open class BadRequestException(message: String, cause: Throwable? = null) : Exception(message, cause) @@ -23,11 +25,16 @@ public open class BadRequestException(message: String, cause: Throwable? = null) * This exception means that the requested resource is not found. * HTTP status 404 Not found will be replied when this exception is thrown and not caught. * 404 status page could be configured by registering a custom [io.ktor.plugins.StatusPages] handler. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.NotFoundException) */ public class NotFoundException(message: String? = "Resource not found") : Exception(message) /** * This exception is thrown when a required parameter with name [parameterName] is missing + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.MissingRequestParameterException) + * * @property parameterName of missing request parameter */ @OptIn(ExperimentalCoroutinesApi::class) @@ -43,6 +50,9 @@ public class MissingRequestParameterException( /** * This exception is thrown when a required parameter with name [parameterName] couldn't be converted to the [type] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.ParameterConversionException) + * * @property parameterName of missing request parameter * @property type this parameter is unable to convert to */ @@ -64,6 +74,8 @@ public class ParameterConversionException( * Thrown when content cannot be transformed to the desired type. * It is not defined which status code will be replied when an exception of this type is thrown and not caught. * Depending on child type it could be 4xx or 5xx status code. By default it will be 500 Internal Server Error. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.ContentTransformationException) */ public abstract class ContentTransformationException(message: String) : IOException(message) @@ -82,6 +94,8 @@ public class CannotTransformContentToTypeException( /** * Thrown when there is no conversion for a content type configured. * HTTP status 415 Unsupported Media Type will be replied when this exception is thrown and not caught. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.UnsupportedMediaTypeException) */ @OptIn(ExperimentalCoroutinesApi::class) public class UnsupportedMediaTypeException( @@ -100,6 +114,8 @@ public class UnsupportedMediaTypeException( /** * Thrown when request body is larger than the set limit. * HTTP status 413 Payload Too Large will be replied when this exception is thrown and not caught. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.PayloadTooLargeException) */ @OptIn(ExperimentalCoroutinesApi::class) public class PayloadTooLargeException( diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/plugins/OriginConnectionPoint.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/plugins/OriginConnectionPoint.kt index 1aa5e946157..840213b10f4 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/plugins/OriginConnectionPoint.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/plugins/OriginConnectionPoint.kt @@ -13,6 +13,8 @@ import kotlin.reflect.* /** * Represents request and connection parameters possibly overridden via https headers. * By default, it fallbacks to [ApplicationRequest.local] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.origin) */ public val ApplicationRequest.origin: RequestConnectionPoint @@ -20,6 +22,8 @@ public val ApplicationRequest.origin: RequestConnectionPoint /** * A key to install a mutable [RequestConnectionPoint] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.MutableOriginConnectionPointKey) */ @Deprecated("This API will be redesigned as per https://youtrack.jetbrains.com/issue/KTOR-2657") public val MutableOriginConnectionPointKey: AttributeKey = @@ -31,6 +35,8 @@ public val MutableOriginConnectionPointKey: AttributeKey(Before, Transform, After) { /** * Pipeline phases. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.ApplicationReceivePipeline.Phases) */ @Suppress("PublicApiImplicitType") public companion object Phases { /** * Executes before any transformations are made. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.ApplicationReceivePipeline.Phases.Before) */ public val Before: PipelinePhase = PipelinePhase("Before") /** * Executes transformations. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.ApplicationReceivePipeline.Phases.Transform) */ public val Transform: PipelinePhase = PipelinePhase("Transform") /** * Executes after all transformations. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.ApplicationReceivePipeline.Phases.After) */ public val After: PipelinePhase = PipelinePhase("After") } @@ -53,6 +63,9 @@ public open class ApplicationReceivePipeline( /** * Receives content for this request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.receiveOrNull) + * * @return instance of [T] received from this call, or `null` if content cannot be transformed to the requested type. */ @Deprecated( @@ -66,6 +79,9 @@ public suspend inline fun ApplicationCall.receiveOrNull(): T? /** * Receives content for this request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.receive) + * * @return instance of [T] received from this call. * @throws ContentTransformationException when content cannot be transformed to the requested type. */ @@ -74,6 +90,9 @@ public suspend inline fun ApplicationCall.receive(): T = recei /** * Receives content for this request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.receiveNullable) + * * @return instance of [T] received from this call. * @throws ContentTransformationException when content cannot be transformed to the requested type. */ @@ -81,6 +100,9 @@ public suspend inline fun ApplicationCall.receiveNullable(): T? = re /** * Receives content for this request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.receive) + * * @param type instance of `KClass` specifying type to be received. * @return instance of [T] received from this call. * @throws ContentTransformationException when content cannot be transformed to the requested type. @@ -92,6 +114,9 @@ public suspend fun ApplicationCall.receive(type: KClass): T { /** * Receives content for this request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.receive) + * * @param typeInfo instance specifying type to be received. * @return instance of [T] received from this call. * @throws ContentTransformationException when content cannot be transformed to the requested type. @@ -101,6 +126,9 @@ public suspend fun ApplicationCall.receive(typeInfo: TypeInfo): T = receiveN /** * Receives content for this request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.receiveOrNull) + * * @param [typeInfo] type to be received. * @return instance of [T] received from this call, or `null` if content cannot be transformed to the requested type. */ @@ -121,6 +149,9 @@ public suspend fun ApplicationCall.receiveOrNull(typeInfo: TypeInfo): /** * Receives content for this request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.receiveOrNull) + * * @param type instance of `KClass` specifying type to be received. * @return instance of [T] received from this call, or `null` if content cannot be transformed to the requested type.. */ @@ -139,6 +170,9 @@ public suspend fun ApplicationCall.receiveOrNull(type: KClass): T? /** * Receives incoming content for this call as [String]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.receiveText) + * * @return text received from this call. * @throws BadRequestException when Content-Type header is invalid. */ @@ -153,6 +187,9 @@ public suspend inline fun ApplicationCall.receiveText(): String { /** * Receives channel content for this call. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.receiveChannel) + * * @return instance of [ByteReadChannel] to read incoming bytes for this call. * @throws ContentTransformationException when content cannot be transformed to the [ByteReadChannel]. */ @@ -173,6 +210,8 @@ public suspend inline fun ApplicationCall.receiveChannel(): ByteReadChannel = re * ``` * call.formFieldLimit = limit * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.formFieldLimit) */ public var ApplicationCall.formFieldLimit: Long get() { @@ -184,6 +223,9 @@ public var ApplicationCall.formFieldLimit: Long /** * Receives multipart data for this call. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.receiveMultipart) + * * @return instance of [MultiPartData]. * @throws ContentTransformationException when content cannot be transformed to the [MultiPartData]. */ @@ -198,6 +240,9 @@ public suspend inline fun ApplicationCall.receiveMultipart( /** * Receives form parameters for this call. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.receiveParameters) + * * @return instance of [Parameters]. * @throws ContentTransformationException when content cannot be transformed to the [Parameters]. */ @@ -205,6 +250,8 @@ public suspend inline fun ApplicationCall.receiveParameters(): Parameters = rece /** * Thrown when content cannot be transformed to the desired type. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.ContentTransformationException) */ public typealias ContentTransformationException = io.ktor.server.plugins.ContentTransformationException @@ -221,6 +268,8 @@ internal val DoubleReceivePreventionTokenKey = /** * Thrown when a request body has already been received. * Usually it is caused by double [ApplicationCall.receive] invocation. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.RequestAlreadyConsumedException) */ public class RequestAlreadyConsumedException : IllegalStateException( "Request body has already been consumed (received)." diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/request/ApplicationRequestProperties.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/request/ApplicationRequestProperties.kt index f3d20f9779b..d31354beb83 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/request/ApplicationRequestProperties.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/request/ApplicationRequestProperties.kt @@ -13,145 +13,201 @@ import io.ktor.utils.io.charsets.* /** * Gets the first value of a [name] header or returns `null` if missing. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.header) */ public fun ApplicationRequest.header(name: String): String? = headers[name] /** * Gets a request's query string or returns an empty string if missing. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.queryString) */ public fun ApplicationRequest.queryString(): String = origin.uri.substringAfter('?', "") /** * Gets a request's content type or returns `ContentType.Any`. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.contentType) */ public fun ApplicationRequest.contentType(): ContentType = header(HttpHeaders.ContentType)?.let { ContentType.parse(it) } ?: ContentType.Any /** * Gets a request's `Content-Length` header value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.contentLength) */ public fun ApplicationRequest.contentLength(): Long? = header(HttpHeaders.ContentLength)?.toLongOrNull() /** * Gets a request's charset. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.contentCharset) */ public fun ApplicationRequest.contentCharset(): Charset? = contentType().charset() /** * A document name is a substring after the last slash but before a query string. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.document) */ public fun ApplicationRequest.document(): String = path().substringAfterLast('/') /** * Get a request's URL path without a query string. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.path) */ public fun ApplicationRequest.path(): String = origin.uri.substringBefore('?') /** * Get a request's `Authorization` header value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.authorization) */ public fun ApplicationRequest.authorization(): String? = header(HttpHeaders.Authorization) /** * Get a request's `Location` header value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.location) */ public fun ApplicationRequest.location(): String? = header(HttpHeaders.Location) /** * Get a request's `Accept` header value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.accept) */ public fun ApplicationRequest.accept(): String? = header(HttpHeaders.Accept) /** * Gets the `Accept` header content types sorted according to their qualities. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.acceptItems) */ public fun ApplicationRequest.acceptItems(): List = parseAndSortContentTypeHeader(header(HttpHeaders.Accept)) /** * Gets a request's `Accept-Encoding` header value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.acceptEncoding) */ public fun ApplicationRequest.acceptEncoding(): String? = header(HttpHeaders.AcceptEncoding) /** * Gets the `Accept-Encoding` header encoding types sorted according to their qualities. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.acceptEncodingItems) */ public fun ApplicationRequest.acceptEncodingItems(): List = parseAndSortHeader(header(HttpHeaders.AcceptEncoding)) /** * Gets a request's `Accept-Language` header value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.acceptLanguage) */ public fun ApplicationRequest.acceptLanguage(): String? = header(HttpHeaders.AcceptLanguage) /** * Gets the `Accept-Language` header languages sorted according to their qualities. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.acceptLanguageItems) */ public fun ApplicationRequest.acceptLanguageItems(): List = parseAndSortHeader(header(HttpHeaders.AcceptLanguage)) /** * Gets a request's `Accept-Charset` header value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.acceptCharset) */ public fun ApplicationRequest.acceptCharset(): String? = header(HttpHeaders.AcceptCharset) /** * Gets the `Accept-Charset` header charsets sorted according to their qualities. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.acceptCharsetItems) */ public fun ApplicationRequest.acceptCharsetItems(): List = parseAndSortHeader(header(HttpHeaders.AcceptCharset)) /** * Checks whether a request's body is chunk-encoded. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.isChunked) */ public fun ApplicationRequest.isChunked(): Boolean = header(HttpHeaders.TransferEncoding)?.compareTo("chunked", ignoreCase = true) == 0 /** * Checks whether a request body is multipart-encoded. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.isMultipart) */ public fun ApplicationRequest.isMultipart(): Boolean = contentType().match(ContentType.MultiPart.Any) /** * Gets a request's `User-Agent` header value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.userAgent) */ public fun ApplicationRequest.userAgent(): String? = header(HttpHeaders.UserAgent) /** * Gets a request's `Cache-Control` header value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.cacheControl) */ public fun ApplicationRequest.cacheControl(): String? = header(HttpHeaders.CacheControl) /** * Gets a request's host value without a port. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.host) + * * @see [port] */ public fun ApplicationRequest.host(): String = origin.serverHost /** * Gets a request's port extracted from the `Host` header value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.port) + * * @see [host] */ public fun ApplicationRequest.port(): Int = origin.serverPort /** * Gets ranges parsed from a request's `Range` header value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.ranges) */ public fun ApplicationRequest.ranges(): RangesSpecifier? = header(HttpHeaders.Range)?.let { rangesSpec -> parseRangesSpecifier(rangesSpec) } /** * Gets a request's URI, including a query string. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.uri) */ public val ApplicationRequest.uri: String get() = origin.uri /** * Gets a request HTTP method possibly overridden using the `X-Http-Method-Override` header. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.httpMethod) */ public val ApplicationRequest.httpMethod: HttpMethod get() = origin.method /** * Gets a request's HTTP version. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.httpVersion) */ public val ApplicationRequest.httpVersion: String get() = origin.version diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/request/PipelineRequest.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/request/PipelineRequest.kt index c66985dcaff..d9bd96a3cf5 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/request/PipelineRequest.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/request/PipelineRequest.kt @@ -11,6 +11,9 @@ import io.ktor.utils.io.* /** * A client's request. * To learn how to handle incoming requests, see [Handling requests](https://ktor.io/docs/requests.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.ApplicationRequest) + * * @see [io.ktor.server.application.ApplicationCall] * @see [io.ktor.server.response.ApplicationResponse] */ @@ -20,11 +23,15 @@ public interface ApplicationRequest { * Provides access to headers for the current request. * You can also get access to specific headers using dedicated extension functions, * such as [acceptEncoding], [contentType], [cacheControl], and so on. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.ApplicationRequest.headers) */ public val headers: Headers /** * An [ApplicationCall] instance this [ApplicationRequest] is attached to. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.ApplicationRequest.call) */ public val call: ApplicationCall @@ -32,26 +39,36 @@ public interface ApplicationRequest { * Provides access to connection details such as a host name, port, scheme, etc. * To get information about a request passed through an HTTP proxy or a load balancer, * install the ForwardedHeaders/XForwardedHeader plugin and use the [origin] property. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.ApplicationRequest.local) */ public val local: RequestConnectionPoint /** * Provides access to decoded parameters of a URL query string. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.ApplicationRequest.queryParameters) */ public val queryParameters: Parameters /** * Provides access to parameters of a URL query string. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.ApplicationRequest.rawQueryParameters) */ public val rawQueryParameters: Parameters /** * Provides access to cookies for this request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.ApplicationRequest.cookies) */ public val cookies: RequestCookies /** * Receives a raw body payload as a channel. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.ApplicationRequest.receiveChannel) */ public fun receiveChannel(): ByteReadChannel } @@ -59,28 +76,39 @@ public interface ApplicationRequest { /** * A client's request that is used in [ApplicationPlugin]. * To learn how to handle incoming requests, see [Handling requests](https://ktor.io/docs/requests.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.PipelineRequest) + * * @see [PipelineCall] * @see [io.ktor.server.response.PipelineResponse] */ public interface PipelineRequest : ApplicationRequest { /** * An [PipelineCall] instance this [PipelineRequest] is attached to. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.PipelineRequest.call) */ public override val call: PipelineCall /** * A pipeline for receiving content. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.PipelineRequest.pipeline) */ public val pipeline: ApplicationReceivePipeline /** * Overrides request headers. Will remove header [name] if passed [values] is `null` or set [values] otherwise. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.PipelineRequest.setHeader) */ @InternalAPI public fun setHeader(name: String, values: List?) /** * Overrides request body. It's a caller responsibility to close the original channel if it's not needed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.PipelineRequest.setReceiveChannel) */ @InternalAPI public fun setReceiveChannel(channel: ByteReadChannel) @@ -88,6 +116,8 @@ public interface PipelineRequest : ApplicationRequest { /** * Internal helper function to encode raw parameters. Should not be used directly. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.encodeParameters) */ public fun ApplicationRequest.encodeParameters(parameters: Parameters): Parameters { return ParametersBuilder().apply { diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/request/RequestCookies.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/request/RequestCookies.kt index 154591db550..e034788092c 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/request/RequestCookies.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/request/RequestCookies.kt @@ -9,6 +9,9 @@ import io.ktor.util.collections.* /** * Server request's cookies. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.RequestCookies) + * * @see [ApplicationRequest.cookies] * @property request application request to fetch cookies from */ @@ -19,11 +22,15 @@ public open class RequestCookies(protected val request: ApplicationRequest) { * Provides access to raw cookie values. * These values are not decoded so could have percent encoded values, quotes, escape characters, and so on. * It is recommended to use [get] instead. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.RequestCookies.rawCookies) */ public val rawCookies: Map by lazy { fetchCookies() } /** * Gets a [name] cookie value decoded using an [encoding] strategy. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.RequestCookies.get) */ public operator fun get(name: String, encoding: CookieEncoding = CookieEncoding.URI_ENCODING): String? { val rawValue = rawCookies[name] ?: return null diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/response/ApplicationResponseFunctions.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/response/ApplicationResponseFunctions.kt index 9c292f0b8fc..d08fbfbbcc5 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/response/ApplicationResponseFunctions.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/response/ApplicationResponseFunctions.kt @@ -19,6 +19,9 @@ import kotlin.jvm.* /** * Sends a [message] as a response. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.respond) + * * @see [io.ktor.server.response.ApplicationResponse] */ public suspend inline fun ApplicationCall.respond(message: T) { @@ -27,6 +30,9 @@ public suspend inline fun ApplicationCall.respond(message: T) /** * Sends a [message] as a response. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.respondNullable) + * * @see [io.ktor.server.response.ApplicationResponse] */ public suspend inline fun ApplicationCall.respondNullable(message: T) { @@ -35,6 +41,9 @@ public suspend inline fun ApplicationCall.respondNullable(message: T /** * Sends a [message] as a response with the specified [status] code. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.respond) + * * @see [io.ktor.server.response.ApplicationResponse] */ @JvmName("respondWithType") @@ -45,6 +54,9 @@ public suspend inline fun ApplicationCall.respond(status: Http /** * Sends a [message] of type [messageType] as a response with the specified [status] code. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.respond) + * * @see [io.ktor.server.response.ApplicationResponse] */ public suspend fun ApplicationCall.respond( @@ -58,6 +70,9 @@ public suspend fun ApplicationCall.respond( /** * Sends a [message] as a response with the specified [status] code. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.respondNullable) + * * @see [io.ktor.server.response.ApplicationResponse] */ public suspend inline fun ApplicationCall.respondNullable(status: HttpStatusCode, message: T) { @@ -67,6 +82,9 @@ public suspend inline fun ApplicationCall.respondNullable(status: Ht /** * Responds to a client with a `301 Moved Permanently` or `302 Found` redirect. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.respondRedirect) + * * @see [io.ktor.server.response.ApplicationResponse] */ public suspend fun ApplicationCall.respondRedirect(url: String, permanent: Boolean = false) { @@ -76,6 +94,9 @@ public suspend fun ApplicationCall.respondRedirect(url: String, permanent: Boole /** * Responds to a client with a `301 Moved Permanently` or `302 Found` redirect. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.respondRedirect) + * * @see [io.ktor.server.response.ApplicationResponse] */ public suspend fun ApplicationCall.respondRedirect(url: Url, permanent: Boolean = false) { @@ -85,6 +106,9 @@ public suspend fun ApplicationCall.respondRedirect(url: Url, permanent: Boolean /** * Responds to a client with a `301 Moved Permanently` or `302 Found` redirect. * Unlike the other [respondRedirect], it provides a way to build a URL based on current call using the [block] function. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.respondRedirect) + * * @see [io.ktor.server.response.ApplicationResponse] */ public suspend inline fun ApplicationCall.respondRedirect(permanent: Boolean = false, block: URLBuilder.() -> Unit) { @@ -93,6 +117,9 @@ public suspend inline fun ApplicationCall.respondRedirect(permanent: Boolean = f /** * Responds to a client with a plain [text] response. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.respondText) + * * @see [io.ktor.server.response.ApplicationResponse] * @param contentType is an optional [ContentType], default is [ContentType.Text.Plain] * @param status is an optional [HttpStatusCode], default is [HttpStatusCode.OK] @@ -109,6 +136,9 @@ public suspend fun ApplicationCall.respondText( /** * Responds to a client with a plain text response, using the specified [provider] to build a text. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.respondText) + * * @see [io.ktor.server.response.ApplicationResponse] * @param contentType is an optional [ContentType], default is [ContentType.Text.Plain] * @param status is an optional [HttpStatusCode], default is [HttpStatusCode.OK] @@ -124,6 +154,9 @@ public suspend fun ApplicationCall.respondText( /** * Responds to a client with a raw bytes response, using the specified [provider] to build a byte array. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.respondBytes) + * * @see [io.ktor.server.response.ApplicationResponse] * @param contentType is an optional [ContentType], unspecified by default * @param status is an optional [HttpStatusCode], default is [HttpStatusCode.OK] @@ -138,6 +171,9 @@ public suspend fun ApplicationCall.respondBytes( /** * Responds to a client with a raw bytes response, using specified [bytes]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.respondBytes) + * * @see [io.ktor.server.response.ApplicationResponse] * @param contentType is an optional [ContentType], unspecified by default * @param status is an optional [HttpStatusCode], default is [HttpStatusCode.OK] @@ -154,6 +190,9 @@ public suspend fun ApplicationCall.respondBytes( /** * Responds to an [ApplicationCall] with the content from the provided kotlinx-io [Source]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.respondSource) + * * @param source The binary data source of the content to be responded with. * @param contentType An optional [ContentType], unspecified by default * @param status An optional [HttpStatusCode], default is [HttpStatusCode.OK] @@ -173,6 +212,8 @@ public suspend fun ApplicationCall.respondSource( * * The [producer] parameter will be called later when an engine is ready to produce content. You don't need to close it. * The provided [ByteWriteChannel] will be closed automatically. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.respondBytesWriter) */ public suspend fun ApplicationCall.respondBytesWriter( contentType: ContentType? = null, @@ -191,6 +232,8 @@ public suspend fun ApplicationCall.respondBytesWriter( * * Additionally, if a content type is `Text` and a charset is not set for a content type, * it appends `; charset=UTF-8` to the content type. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.defaultTextContentType) */ public fun ApplicationCall.defaultTextContentType(contentType: ContentType?): ContentType { val result = when (contentType) { diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/response/ApplicationResponseProperties.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/response/ApplicationResponseProperties.kt index a76a229aa78..b56b44e9444 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/response/ApplicationResponseProperties.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/response/ApplicationResponseProperties.kt @@ -10,37 +10,51 @@ import io.ktor.http.* /** * Appends a header with the specified [name] and [value] to a response. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.header) */ public fun ApplicationResponse.header(name: String, value: String): Unit = headers.append(name, value) /** * Appends a header with the specified [name] and [value] to a response. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.header) */ public fun ApplicationResponse.header(name: String, value: Int): Unit = headers.append(name, value.toString()) /** * Appends a header with the specified [name] and [value] to a response. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.header) */ public fun ApplicationResponse.header(name: String, value: Long): Unit = headers.append(name, value.toString()) /** * Appends the `E-Tag` header with the specified [value] to a response. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.etag) */ public fun ApplicationResponse.etag(value: String): Unit = header(HttpHeaders.ETag, value) /** * Appends the `Cache-Control` header with the specified [value] to a response. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.cacheControl) */ public fun ApplicationResponse.cacheControl(value: CacheControl): Unit = header(HttpHeaders.CacheControl, value.toString()) /** * Appends the `Cache-Control` header with the specified [value] to a response. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.cacheControl) */ public fun HeadersBuilder.cacheControl(value: CacheControl): Unit = set(HttpHeaders.CacheControl, value.toString()) /** * Appends the `Content-Range` header with the specified [range] and [fullLength] to a response. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.contentRange) */ public fun HeadersBuilder.contentRange( range: LongRange?, @@ -52,6 +66,8 @@ public fun HeadersBuilder.contentRange( /** * Appends the `Content-Range` header with the specified [range] and [fullLength] to a response. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.contentRange) */ public fun ApplicationResponse.contentRange( range: LongRange?, @@ -63,6 +79,8 @@ public fun ApplicationResponse.contentRange( /** * Appends the `Content-Range` header with the specified [range] and [fullLength] to a response. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.contentRange) */ public fun ApplicationResponse.contentRange( range: LongRange?, diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/response/ApplicationSendPipeline.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/response/ApplicationSendPipeline.kt index 024d8e29fbf..913fb8a1c9b 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/response/ApplicationSendPipeline.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/response/ApplicationSendPipeline.kt @@ -9,22 +9,30 @@ import io.ktor.util.pipeline.* /** * Server response send pipeline. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.ApplicationSendPipeline) */ public open class ApplicationSendPipeline( override val developmentMode: Boolean = false ) : Pipeline(Before, Transform, Render, ContentEncoding, TransferEncoding, After, Engine) { /** * Send pipeline phases. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.ApplicationSendPipeline.Phases) */ @Suppress("PublicApiImplicitType") public companion object Phases { /** * The earliest phase that happens before any other + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.ApplicationSendPipeline.Phases.Before) */ public val Before: PipelinePhase = PipelinePhase("Before") /** * A transformation phase that can proceed with any supported data like String. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.ApplicationSendPipeline.Phases.Transform) */ public val Transform: PipelinePhase = PipelinePhase("Transform") @@ -32,26 +40,36 @@ public open class ApplicationSendPipeline( * A phase to render any current pipeline subject into [io.ktor.http.content.OutgoingContent]. * * Beyond this phase, only [io.ktor.http.content.OutgoingContent] should be produced by any interceptor. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.ApplicationSendPipeline.Phases.Render) */ public val Render: PipelinePhase = PipelinePhase("Render") /** * A phase for processing `Content-Encoding`, like compression and partial content. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.ApplicationSendPipeline.Phases.ContentEncoding) */ public val ContentEncoding: PipelinePhase = PipelinePhase("ContentEncoding") /** * A phase for handling `Transfer-Encoding`, like if chunked encoding is being done manually and not by engine. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.ApplicationSendPipeline.Phases.TransferEncoding) */ public val TransferEncoding: PipelinePhase = PipelinePhase("TransferEncoding") /** * The latest application phase that happens right before an engine sends a response. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.ApplicationSendPipeline.Phases.After) */ public val After: PipelinePhase = PipelinePhase("After") /** * A phase for Engine to send the response out to the client. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.ApplicationSendPipeline.Phases.Engine) */ public val Engine: PipelinePhase = PipelinePhase("Engine") } diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/response/DefaultResponsePushBuilder.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/response/DefaultResponsePushBuilder.kt index 5a863bc9fcf..4ee635ab332 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/response/DefaultResponsePushBuilder.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/response/DefaultResponsePushBuilder.kt @@ -12,6 +12,9 @@ import io.ktor.utils.io.* /** * An HTTP/2 push builder. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.DefaultResponsePushBuilder) + * * @property method HTTP method * @property url builder * @property headers builder @@ -40,6 +43,8 @@ public class DefaultResponsePushBuilder( /** * A list of version information (for conditional headers). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.DefaultResponsePushBuilder.versions) */ override var versions: ArrayList = if (versions.isEmpty()) ArrayList() else ArrayList(versions) diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/response/PipelineResponse.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/response/PipelineResponse.kt index 8caabc698bc..79a875950bd 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/response/PipelineResponse.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/response/PipelineResponse.kt @@ -10,48 +10,67 @@ import io.ktor.server.application.* /** * A server's response. * To learn how to send responses inside route handlers, see [Sending responses](https://ktor.io/docs/responses.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.ApplicationResponse) + * * @see [ApplicationCall] * @see [io.ktor.server.request.ApplicationRequest] */ public interface ApplicationResponse { /** * Provides access to headers for the current response. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.ApplicationResponse.headers) */ public val headers: ResponseHeaders /** * An [ApplicationCall] instance this [ApplicationResponse] is attached to. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.ApplicationResponse.call) */ public val call: ApplicationCall /** * Indicates that this response is already committed and no further changes are allowed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.ApplicationResponse.isCommitted) */ public val isCommitted: Boolean /** * Indicates that this response is already fully sent to the client. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.ApplicationResponse.isSent) */ public val isSent: Boolean /** * Provides access to cookies for this response. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.ApplicationResponse.cookies) */ public val cookies: ResponseCookies /** * Returns a response status code or `null` if a status code is not set. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.ApplicationResponse.status) */ public fun status(): HttpStatusCode? /** * Specifies a status code for a response. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.ApplicationResponse.status) */ public fun status(value: HttpStatusCode) /** * Produces HTTP/2 push from a server to a client or sets an HTTP/1.x hint header * or does nothing. Exact behaviour is up to engine implementation. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.ApplicationResponse.push) */ @UseHttp2Push public fun push(builder: ResponsePushBuilder) @@ -60,17 +79,24 @@ public interface ApplicationResponse { /** * A server's response that is used in [ApplicationPlugin]. * To learn how to send responses inside route handlers, see [Sending responses](https://ktor.io/docs/responses.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.PipelineResponse) + * * @see [PipelineCall] * @see [io.ktor.server.request.PipelineRequest] */ public interface PipelineResponse : ApplicationResponse { /** * An [PipelineCall] instance this [PipelineResponse] is attached to. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.PipelineResponse.call) */ public override val call: PipelineCall /** * A pipeline for sending content. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.PipelineResponse.pipeline) */ public val pipeline: ApplicationSendPipeline } diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/response/ResponseCookies.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/response/ResponseCookies.kt index 3f18593c8b6..58a8aa20ab5 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/response/ResponseCookies.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/response/ResponseCookies.kt @@ -9,11 +9,16 @@ import io.ktor.util.date.* /** * Server's response cookies. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.ResponseCookies) + * * @see [ApplicationResponse.cookies] */ public class ResponseCookies(private val response: PipelineResponse) { /** * Gets a cookie from a response's `Set-Cookie` header. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.ResponseCookies.get) */ public operator fun get(name: String): Cookie? = response.headers .values("Set-Cookie") @@ -22,6 +27,8 @@ public class ResponseCookies(private val response: PipelineResponse) { /** * Appends a cookie [item] using the `Set-Cookie` response header. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.ResponseCookies.append) */ public fun append(item: Cookie) { response.headers.append("Set-Cookie", renderSetCookieHeader(item)) @@ -29,6 +36,8 @@ public class ResponseCookies(private val response: PipelineResponse) { /** * Appends a cookie using the `Set-Cookie` response header from the specified parameters. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.ResponseCookies.append) */ public fun append( name: String, @@ -60,6 +69,8 @@ public class ResponseCookies(private val response: PipelineResponse) { /** * Appends an already expired cookie. Useful to remove client cookies. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.ResponseCookies.appendExpired) */ @Deprecated( "This method doesn't bypass all flags and extensions so it will be removed in future " + diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/response/ResponseHeaders.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/response/ResponseHeaders.kt index 8b9e6b92c98..e2b6cadcad0 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/response/ResponseHeaders.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/response/ResponseHeaders.kt @@ -8,6 +8,9 @@ import io.ktor.http.* /** * Server's response headers. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.ResponseHeaders) + * * @see [ApplicationResponse.headers] */ public abstract class ResponseHeaders { @@ -19,21 +22,29 @@ public abstract class ResponseHeaders { /** * Checks whether a [name] response header is set. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.ResponseHeaders.contains) */ public operator fun contains(name: String): Boolean = get(name) != null /** * Gets a first response header with the specified [name] or returns `null`. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.ResponseHeaders.get) */ public open operator fun get(name: String): String? = getEngineHeaderValues(name).firstOrNull() /** * Gets values of a response header with the specified [name]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.ResponseHeaders.values) */ public fun values(name: String): List = getEngineHeaderValues(name) /*** * Builds a [Headers] instance from a response header values. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.ResponseHeaders.allValues) */ public fun allValues(): Headers = Headers.build { getEngineHeaderNames().toSet().forEach { @@ -43,6 +54,9 @@ public abstract class ResponseHeaders { /** * Appends a response header with the specified [name] and [value]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.ResponseHeaders.append) + * * @param safeOnly prevents from setting unsafe headers; `true` by default */ public fun append(name: String, value: String, safeOnly: Boolean = true) { @@ -75,6 +89,9 @@ public abstract class ResponseHeaders { /** * Appends a response header with the specified [name] and [value] if this is no header with [name] yet. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.appendIfAbsent) + * * @param safeOnly prevents from setting unsafe headers; `true` by default */ public fun ResponseHeaders.appendIfAbsent(name: String, value: String, safeOnly: Boolean = true) { diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/response/ResponsePushBuilder.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/response/ResponsePushBuilder.kt index a1001e705bc..139cb9e6f79 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/response/ResponsePushBuilder.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/response/ResponsePushBuilder.kt @@ -10,6 +10,9 @@ import io.ktor.http.content.* /** * An HTTP/2 push builder interface. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.ResponsePushBuilder) + * * @property url push URL * @property headers request headers * @property method request method diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/response/ResponseType.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/response/ResponseType.kt index 8eac7c51c13..ef62c457673 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/response/ResponseType.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/response/ResponseType.kt @@ -13,6 +13,8 @@ private val ResponseTypeAttributeKey: AttributeKey = AttributeKey("Res /** * A type of response object that is passed in the [respond] function. * Can be useful for custom serializations. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.responseType) */ public var ApplicationResponse.responseType: TypeInfo? get() = call.attributes.getOrNull(ResponseTypeAttributeKey) diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/response/UseHttp2Push.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/response/UseHttp2Push.kt index 793e0109cb8..b8460e07618 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/response/UseHttp2Push.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/response/UseHttp2Push.kt @@ -13,6 +13,8 @@ package io.ktor.server.response * to use it, so feel free to opt in this annotation to eliminate this warning, if * you are sure that you need it. For example, it makes sense to use with * a non-browser client that for sure supports HTTP/2 push. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.UseHttp2Push) */ @RequiresOptIn( "HTTP/2 push is no longer supported by some web browsers.", diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/HostsRoutingBuilder.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/HostsRoutingBuilder.kt index 91c0ab46bb2..aa2cf901cda 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/HostsRoutingBuilder.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/HostsRoutingBuilder.kt @@ -15,6 +15,9 @@ import io.ktor.server.plugins.* * When passes, it puts a request host and port into * call parameters by the [HostRouteSelector.HostNameParameter] and [HostRouteSelector.PortParameter] keys. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.host) + * * @param host exact host name that is treated literally * @param port to be tested or `0` to pass all ports */ @@ -29,6 +32,9 @@ public fun Route.host(host: String, port: Int = 0, build: Route.() -> Unit): Rou * When passes, it puts a request host and port into * call parameters by the [HostRouteSelector.HostNameParameter] and [HostRouteSelector.PortParameter] keys. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.host) + * * @param hostPattern is a regular expression to match request host * @param port to be tested or `0` to pass all ports */ @@ -43,6 +49,9 @@ public fun Route.host(hostPattern: Regex, port: Int = 0, build: Route.() -> Unit * When passes, it puts request host and port into * call parameters by the [HostRouteSelector.HostNameParameter] and [HostRouteSelector.PortParameter] keys. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.host) + * * @param hosts a list of exact host names that are treated literally * @param ports a list of ports to be passed or empty to pass all ports * @@ -63,6 +72,9 @@ public fun Route.host( * When passes, it puts request host and port into * call parameters by the [HostRouteSelector.HostNameParameter] and [HostRouteSelector.PortParameter] keys. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.host) + * * @param hosts a list of exact host names that are treated literally * @param hostPatterns a list of regular expressions to match request host * @param ports a list of ports to be passed or empty to pass all ports @@ -85,6 +97,9 @@ public fun Route.host( * When passes, it puts a request host and port into * call parameters by the [HostRouteSelector.HostNameParameter] and [HostRouteSelector.PortParameter] keys. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.port) + * * @param ports a list of ports to be passed * * @throws IllegalArgumentException if no ports were specified @@ -98,6 +113,9 @@ public fun Route.port(vararg ports: Int, build: Route.() -> Unit): Route { /** * Evaluates a route against a request's host and port. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.HostRouteSelector) + * * @param hostList contains exact host names * @param hostPatterns contains host patterns to match * @param portsList contains possible ports or empty to match all ports @@ -141,11 +159,15 @@ public data class HostRouteSelector( public companion object { /** * A parameter name for [ApplicationCall.parameters] for a request host. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.HostRouteSelector.Companion.HostNameParameter) */ public const val HostNameParameter: String = "\$RequestHost" /** * A parameter name for [ApplicationCall.parameters] for a request port. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.HostRouteSelector.Companion.PortParameter) */ public const val PortParameter: String = "\$RequestPort" } diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/IgnoreTrailingSlash.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/IgnoreTrailingSlash.kt index 404c0ff964c..721927b0f8d 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/IgnoreTrailingSlash.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/IgnoreTrailingSlash.kt @@ -19,6 +19,9 @@ internal var ApplicationCall.ignoreTrailingSlash: Boolean /** * A plugin that enables ignoring a trailing slash when resolving URLs. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.IgnoreTrailingSlash) + * * @see [Application.routing] */ public val IgnoreTrailingSlash: ApplicationPlugin = createApplicationPlugin("IgnoreTrailingSlash") { diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/LocalPortRoutingBuilder.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/LocalPortRoutingBuilder.kt index 6b72954b530..7af7534523e 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/LocalPortRoutingBuilder.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/LocalPortRoutingBuilder.kt @@ -17,6 +17,9 @@ import io.ktor.server.application.* * For multi-tenant applications, you may want to use [io.ktor.server.routing.port], * which takes HTTP headers into consideration. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.localPort) + * * @param port the port to match against * * @throws IllegalArgumentException if the port is outside the range of TCP/UDP ports @@ -31,6 +34,9 @@ public fun Route.localPort(port: Int, build: Route.() -> Unit): Route { /** * Evaluates a route against the port on which a call is received. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.LocalPortRouteSelector) + * * @param port the port to match against */ public data class LocalPortRouteSelector(val port: Int) : RouteSelector() { @@ -46,6 +52,8 @@ public data class LocalPortRouteSelector(val port: Int) : RouteSelector() { public companion object { /** * A parameter name for [ApplicationCall.parameters] for a request host. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.LocalPortRouteSelector.Companion.LocalPortParameter) */ public const val LocalPortParameter: String = "\$LocalPort" } diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RegexRouting.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RegexRouting.kt index d8a3688409e..4d6857334f4 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RegexRouting.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RegexRouting.kt @@ -24,6 +24,8 @@ import kotlin.jvm.* * } * } * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.route) */ @KtorDsl public fun Route.route(path: Regex, build: Route.() -> Unit): Route = @@ -42,6 +44,8 @@ public fun Route.route(path: Regex, build: Route.() -> Unit): Route = * } * } * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.route) */ @KtorDsl public fun Route.route(path: Regex, method: HttpMethod, build: Route.() -> Unit): Route { @@ -60,6 +64,8 @@ public fun Route.route(path: Regex, method: HttpMethod, build: Route.() -> Unit) * ... * } * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.get) */ @KtorDsl public fun Route.get(path: Regex, body: RoutingHandler): Route { @@ -77,6 +83,8 @@ public fun Route.get(path: Regex, body: RoutingHandler): Route { * ... * } * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.post) */ @KtorDsl public fun Route.post(path: Regex, body: RoutingHandler): Route { @@ -94,6 +102,8 @@ public fun Route.post(path: Regex, body: RoutingHandler): Route { * ... * } * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.post) */ @KtorDsl @JvmName("postTypedPath") @@ -115,6 +125,8 @@ public inline fun Route.post( * ... * } * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.head) */ @KtorDsl public fun Route.head(path: Regex, body: RoutingHandler): Route { @@ -132,6 +144,8 @@ public fun Route.head(path: Regex, body: RoutingHandler): Route { * ... * } * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.put) */ @KtorDsl public fun Route.put(path: Regex, body: RoutingHandler): Route { @@ -149,6 +163,8 @@ public fun Route.put(path: Regex, body: RoutingHandler): Route { * ... * } * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.put) */ @KtorDsl @JvmName("putTypedPath") @@ -170,6 +186,8 @@ public inline fun Route.put( * ... * } * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.patch) */ @KtorDsl public fun Route.patch(path: Regex, body: RoutingHandler): Route { @@ -187,6 +205,8 @@ public fun Route.patch(path: Regex, body: RoutingHandler): Route { * ... * } * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.patch) */ @KtorDsl @JvmName("patchTypedPath") @@ -208,6 +228,8 @@ public inline fun Route.patch( * ... * } * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.delete) */ @KtorDsl public fun Route.delete(path: Regex, body: RoutingHandler): Route { @@ -225,6 +247,8 @@ public fun Route.delete(path: Regex, body: RoutingHandler): Route { * ... * } * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.options) */ @KtorDsl public fun Route.options(path: Regex, body: RoutingHandler): Route { diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RouteSelector.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RouteSelector.kt index 2012db5a214..ba6c8838892 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RouteSelector.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RouteSelector.kt @@ -11,6 +11,9 @@ import io.ktor.server.request.* /** * A result of a route evaluation against a call. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RouteSelectorEvaluation) + * * @param succeeded indicates if a route matches the current [RoutingResolveContext] */ @Suppress("RemoveRedundantQualifierName", "PublicApiImplicitType") @@ -20,6 +23,9 @@ public sealed class RouteSelectorEvaluation( /** * A success result of a route evaluation against a call. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RouteSelectorEvaluation.Success) + * * @param quality indicates a quality of this route as compared to other sibling routes * @param parameters is an instance of [Parameters] with parameters filled by [RouteSelector] * @param segmentIncrement is a value indicating how many path segments has been consumed by a selector @@ -33,6 +39,9 @@ public sealed class RouteSelectorEvaluation( /** * A failed result of a route evaluation against a call. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RouteSelectorEvaluation.Failure) + * * @param quality indicates a quality of this route as compared to other sibling routes * @param failureStatusCode response status code in case of failure. * Usually one of 400, 404, 405. Ignored on successful evaluation @@ -59,97 +68,133 @@ public sealed class RouteSelectorEvaluation( /** * Quality of [RouteSelectorEvaluation] when a constant value is matched. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RouteSelectorEvaluation.Companion.qualityConstant) */ public const val qualityConstant: Double = 1.0 /** * Quality of [RouteSelectorEvaluation] when a query parameter is matched. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RouteSelectorEvaluation.Companion.qualityQueryParameter) */ public const val qualityQueryParameter: Double = 1.0 /** * Quality of [RouteSelectorEvaluation] when a parameter with prefix or suffix is matched. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RouteSelectorEvaluation.Companion.qualityParameterWithPrefixOrSuffix) */ public const val qualityParameterWithPrefixOrSuffix: Double = 0.9 /** * Generic quality of [RouteSelectorEvaluation] to use as reference when some specific parameter is matched. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RouteSelectorEvaluation.Companion.qualityParameter) */ public const val qualityParameter: Double = 0.8 /** * Quality of [RouteSelectorEvaluation] when a path parameter is matched. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RouteSelectorEvaluation.Companion.qualityPathParameter) */ public const val qualityPathParameter: Double = qualityParameter /** * Quality of [RouteSelectorEvaluation] when a HTTP method parameter is matched. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RouteSelectorEvaluation.Companion.qualityMethodParameter) */ @Suppress("unused") public const val qualityMethodParameter: Double = qualityParameter /** * Quality of [RouteSelectorEvaluation] when a wildcard is matched. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RouteSelectorEvaluation.Companion.qualityWildcard) */ public const val qualityWildcard: Double = 0.5 /** * Quality of [RouteSelectorEvaluation] when an optional parameter is missing. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RouteSelectorEvaluation.Companion.qualityMissing) */ public const val qualityMissing: Double = 0.2 /** * Quality of [RouteSelectorEvaluation] when a tailcard match is occurred. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RouteSelectorEvaluation.Companion.qualityTailcard) */ public const val qualityTailcard: Double = 0.1 /** * Quality of [RouteSelectorEvaluation] that doesn't have its own quality but uses quality of its children. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RouteSelectorEvaluation.Companion.qualityTransparent) */ public const val qualityTransparent: Double = -1.0 /** * Quality of [RouteSelectorEvaluation] when an HTTP method doesn't match. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RouteSelectorEvaluation.Companion.qualityFailedMethod) */ public const val qualityFailedMethod: Double = 0.02 /** * Quality of [RouteSelectorEvaluation] when parameter (query, header, etc) doesn't match. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RouteSelectorEvaluation.Companion.qualityFailedParameter) */ public const val qualityFailedParameter: Double = 0.01 /** * Routing evaluation failed to succeed, route doesn't match a context. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RouteSelectorEvaluation.Companion.Failed) */ public val Failed: RouteSelectorEvaluation.Failure = RouteSelectorEvaluation.Failure(0.0, HttpStatusCode.NotFound) /** * Routing evaluation failed to succeed on a path selector. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RouteSelectorEvaluation.Companion.FailedPath) */ public val FailedPath: RouteSelectorEvaluation.Failure = RouteSelectorEvaluation.Failure(0.0, HttpStatusCode.NotFound) /** * Routing evaluation failed to succeed on a method selector. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RouteSelectorEvaluation.Companion.FailedMethod) */ public val FailedMethod: RouteSelectorEvaluation.Failure = RouteSelectorEvaluation.Failure(qualityFailedMethod, HttpStatusCode.MethodNotAllowed) /** * Routing evaluation failed to succeed on a query, header, or other parameter selector. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RouteSelectorEvaluation.Companion.FailedParameter) */ public val FailedParameter: RouteSelectorEvaluation.Failure = RouteSelectorEvaluation.Failure(qualityFailedParameter, HttpStatusCode.BadRequest) /** * Routing evaluation succeeded for a missing optional value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RouteSelectorEvaluation.Companion.Missing) */ public val Missing: RouteSelectorEvaluation = RouteSelectorEvaluation.Success(RouteSelectorEvaluation.qualityMissing) /** * Routing evaluation succeeded for a constant value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RouteSelectorEvaluation.Companion.Constant) */ public val Constant: RouteSelectorEvaluation = RouteSelectorEvaluation.Success(RouteSelectorEvaluation.qualityConstant) @@ -157,18 +202,24 @@ public sealed class RouteSelectorEvaluation( /** * Routing evaluation succeeded for a [qualityTransparent] value. Useful for helper DSL methods that may wrap * routes but should not change priority of routing. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RouteSelectorEvaluation.Companion.Transparent) */ public val Transparent: RouteSelectorEvaluation = RouteSelectorEvaluation.Success(RouteSelectorEvaluation.qualityTransparent) /** * Routing evaluation succeeded for a single path segment with a constant value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RouteSelectorEvaluation.Companion.ConstantPath) */ public val ConstantPath: RouteSelectorEvaluation = RouteSelectorEvaluation.Success(RouteSelectorEvaluation.qualityConstant, segmentIncrement = 1) /** * Routing evaluation succeeded for a wildcard path segment. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RouteSelectorEvaluation.Companion.WildcardPath) */ public val WildcardPath: RouteSelectorEvaluation = RouteSelectorEvaluation.Success(RouteSelectorEvaluation.qualityWildcard, segmentIncrement = 1) @@ -178,18 +229,25 @@ public sealed class RouteSelectorEvaluation( /** * Serves as the base type for routing selectors. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RouteSelector) + * * @param quality indicates how good this selector is compared to siblings */ public abstract class RouteSelector { /** * Evaluates this selector against [context] and a path segment at [segmentIndex]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RouteSelector.evaluate) */ public abstract suspend fun evaluate(context: RoutingResolveContext, segmentIndex: Int): RouteSelectorEvaluation } /** * A selector for a routing root. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RootRouteSelector) */ public class RootRouteSelector(rootPath: String = "") : RouteSelector() { @@ -231,6 +289,9 @@ public class RootRouteSelector(rootPath: String = "") : RouteSelector() { /** * Evaluates a route against a constant query parameter value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.ConstantParameterRouteSelector) + * * @param name is a name of the query parameter * @param value is a value of the query parameter */ @@ -251,6 +312,9 @@ public data class ConstantParameterRouteSelector( /** * Evaluates a route against a query parameter value and captures its value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.ParameterRouteSelector) + * * @param name is a name of the query parameter */ public data class ParameterRouteSelector( @@ -273,6 +337,9 @@ public data class ParameterRouteSelector( /** * Evaluates a route against an optional query parameter value and captures its value, if found. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.OptionalParameterRouteSelector) + * * @param name is a name of the query parameter */ public data class OptionalParameterRouteSelector( @@ -295,6 +362,9 @@ public data class OptionalParameterRouteSelector( /** * Evaluates a route against a constant path segment. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.PathSegmentConstantRouteSelector) + * * @param value is a value of the path segment */ public data class PathSegmentConstantRouteSelector( @@ -313,6 +383,8 @@ public data class PathSegmentConstantRouteSelector( /** * Evaluates a route against a single trailing slash. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.TrailingSlashRouteSelector) */ public object TrailingSlashRouteSelector : RouteSelector() { @@ -331,6 +403,9 @@ public object TrailingSlashRouteSelector : RouteSelector() { /** * Evaluates a route against a parameter path segment and captures its value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.PathSegmentParameterRouteSelector) + * * @param name is the name of the parameter to capture values to * @param prefix is an optional suffix * @param suffix is an optional prefix @@ -357,6 +432,9 @@ public data class PathSegmentParameterRouteSelector( /** * Evaluates a route against an optional parameter path segment and captures its value, if any. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.PathSegmentOptionalParameterRouteSelector) + * * @param name is the name of the parameter to capture values to * @param prefix is an optional suffix * @param suffix is an optional prefix @@ -383,6 +461,8 @@ public data class PathSegmentOptionalParameterRouteSelector( /** * Evaluates a route against any single path segment. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.PathSegmentWildcardRouteSelector) */ public object PathSegmentWildcardRouteSelector : RouteSelector() { override suspend fun evaluate(context: RoutingResolveContext, segmentIndex: Int): RouteSelectorEvaluation { @@ -397,6 +477,9 @@ public object PathSegmentWildcardRouteSelector : RouteSelector() { /** * Evaluates a route against any number of trailing path segments, and captures their values. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.PathSegmentTailcardRouteSelector) + * * @param name is the name of the parameter to capture values to * @property prefix before the tailcard (static text) */ @@ -447,6 +530,9 @@ public data class PathSegmentTailcardRouteSelector( /** * Evaluates a route as a result of the OR operation using two other selectors. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.OrRouteSelector) + * * @param first is a first selector * @param second is a second selector */ @@ -470,6 +556,9 @@ public data class OrRouteSelector( /** * Evaluates a route as a result of the AND operation using two other selectors. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.AndRouteSelector) + * * @param first is a first selector * @param second is a second selector */ @@ -501,6 +590,9 @@ public data class AndRouteSelector( /** * Evaluates a route against an [HttpMethod]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.HttpMethodRouteSelector) + * * @param method is an instance of [HttpMethod] */ public data class HttpMethodRouteSelector( @@ -519,6 +611,9 @@ public data class HttpMethodRouteSelector( /** * Evaluates a route against a header in the request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.HttpHeaderRouteSelector) + * * @param name is the name of the header * @param value is the value of the header */ @@ -567,6 +662,9 @@ internal data class ContentTypeHeaderRouteSelector( /** * Evaluates a route against a `Content-Type` in the [HttpHeaders.Accept] request header. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.HttpAcceptRouteSelector) + * * @param contentType is an instance of [ContentType] */ public data class HttpAcceptRouteSelector( @@ -584,6 +682,9 @@ public data class HttpAcceptRouteSelector( /** * Evaluates a route against a `Content-Type` in the [HttpHeaders.Accept] request header. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.HttpMultiAcceptRouteSelector) + * * @param contentTypes a list of [ContentType] to accept */ public data class HttpMultiAcceptRouteSelector( diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RoutingBuilder.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RoutingBuilder.kt index 993aa939383..fdd50ceb0f1 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RoutingBuilder.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RoutingBuilder.kt @@ -14,6 +14,9 @@ import kotlin.jvm.* /** * Builds a route to match the specified [path]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.route) + * * @see [Application.routing] */ @KtorDsl @@ -22,6 +25,9 @@ public fun Route.route(path: String, build: Route.() -> Unit): Route = /** * Builds a route to match the specified HTTP [method] and [path]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.route) + * * @see [Application.routing] */ @KtorDsl @@ -32,6 +38,9 @@ public fun Route.route(path: String, method: HttpMethod, build: Route.() -> Unit /** * Builds a route to match the specified HTTP [method]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.method) + * * @see [Application.routing] */ @KtorDsl @@ -42,6 +51,9 @@ public fun Route.method(method: HttpMethod, body: Route.() -> Unit): Route { /** * Builds a route to match a parameter with the specified [name] and [value]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.param) + * * @see [Application.routing] */ @KtorDsl @@ -52,6 +64,9 @@ public fun Route.param(name: String, value: String, build: Route.() -> Unit): Ro /** * Builds a route to match a parameter with the specified [name] and captures its value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.param) + * * @see [Application.routing] */ @KtorDsl @@ -62,6 +77,9 @@ public fun Route.param(name: String, build: Route.() -> Unit): Route { /** * Builds a route to capture an optional parameter with specified [name], if it exists. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.optionalParam) + * * @see [Application.routing] */ @KtorDsl @@ -72,6 +90,9 @@ public fun Route.optionalParam(name: String, build: Route.() -> Unit): Route { /** * Builds a route to match a header with the specified [name] and [value]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.header) + * * @see [Application.routing] */ @KtorDsl @@ -82,6 +103,9 @@ public fun Route.header(name: String, value: String, build: Route.() -> Unit): R /** * Builds a route to match requests with the [HttpHeaders.Accept] header matching any of the specified [contentTypes]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.accept) + * * @see [Application.routing] */ @KtorDsl @@ -92,6 +116,9 @@ public fun Route.accept(vararg contentTypes: ContentType, build: Route.() -> Uni /** * Builds a route to match requests with the [HttpHeaders.ContentType] header matching the specified [contentType]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.contentType) + * * @see [Application.routing] */ @KtorDsl @@ -102,6 +129,9 @@ public fun Route.contentType(contentType: ContentType, build: Route.() -> Unit): /** * Builds a route to match `GET` requests with the specified [path]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.get) + * * @see [Application.routing] */ @KtorDsl @@ -111,6 +141,9 @@ public fun Route.get(path: String, body: RoutingHandler): Route { /** * Builds a route to match `GET` requests. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.get) + * * @see [Application.routing] */ @KtorDsl @@ -120,6 +153,9 @@ public fun Route.get(body: RoutingHandler): Route { /** * Builds a route to match `POST` requests with the specified [path]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.post) + * * @see [Application.routing] */ @KtorDsl @@ -129,6 +165,9 @@ public fun Route.post(path: String, body: RoutingHandler): Route { /** * Builds a route to match `POST` requests receiving a request body as content of the [R] type. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.post) + * * @see [Application.routing] */ @KtorDsl @@ -141,6 +180,9 @@ public inline fun Route.post( /** * Builds a route to match `POST` requests with the specified [path] receiving a request body as content of the [R] type. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.post) + * * @see [Application.routing] */ @KtorDsl @@ -154,6 +196,9 @@ public inline fun Route.post( /** * Builds a route to match `POST` requests. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.post) + * * @see [Application.routing] */ @KtorDsl @@ -163,6 +208,9 @@ public fun Route.post(body: RoutingHandler): Route { /** * Builds a route to match `HEAD` requests with the specified [path]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.head) + * * @see [Application.routing] */ @KtorDsl @@ -172,6 +220,9 @@ public fun Route.head(path: String, body: RoutingHandler): Route { /** * Builds a route to match `HEAD` requests. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.head) + * * @see [Application.routing] */ @KtorDsl @@ -181,6 +232,9 @@ public fun Route.head(body: RoutingHandler): Route { /** * Builds a route to match `PUT` requests with the specified [path]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.put) + * * @see [Application.routing] */ @KtorDsl @@ -190,6 +244,9 @@ public fun Route.put(path: String, body: RoutingHandler): Route { /** * Builds a route to match `PUT` requests. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.put) + * * @see [Application.routing] */ @KtorDsl @@ -199,6 +256,9 @@ public fun Route.put(body: RoutingHandler): Route { /** * Builds a route to match `PUT` requests receiving a request body as content of the [R] type. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.put) + * * @see [Application.routing] */ @KtorDsl @@ -211,6 +271,9 @@ public inline fun Route.put( /** * Builds a route to match `PUT` requests with the specified [path] receiving a request body as content of the [R] type. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.put) + * * @see [Application.routing] */ @KtorDsl @@ -224,6 +287,9 @@ public inline fun Route.put( /** * Builds a route to match `PATCH` requests with the specified [path]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.patch) + * * @see [Application.routing] */ @KtorDsl @@ -233,6 +299,9 @@ public fun Route.patch(path: String, body: RoutingHandler): Route { /** * Builds a route to match `PATCH` requests. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.patch) + * * @see [Application.routing] */ @KtorDsl @@ -242,6 +311,9 @@ public fun Route.patch(body: RoutingHandler): Route { /** * Builds a route to match `PATCH` requests receiving a request body as content of the [R] type. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.patch) + * * @see [Application.routing] */ @KtorDsl @@ -254,6 +326,9 @@ public inline fun Route.patch( /** * Builds a route to match `PATCH` requests with the specified [path] receiving a request body as content of the [R] type. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.patch) + * * @see [Application.routing] */ @KtorDsl @@ -267,6 +342,9 @@ public inline fun Route.patch( /** * Builds a route to match `DELETE` requests with the specified [path]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.delete) + * * @see [Application.routing] */ @KtorDsl @@ -276,6 +354,9 @@ public fun Route.delete(path: String, body: RoutingHandler): Route { /** * Builds a route to match `DELETE` requests. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.delete) + * * @see [Application.routing] */ @KtorDsl @@ -285,6 +366,9 @@ public fun Route.delete(body: RoutingHandler): Route { /** * Builds a route to match `OPTIONS` requests with the specified [path]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.options) + * * @see [Application.routing] */ @KtorDsl @@ -294,6 +378,9 @@ public fun Route.options(path: String, body: RoutingHandler): Route { /** * Builds a route to match `OPTIONS` requests. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.options) + * * @see [Application.routing] */ @KtorDsl @@ -303,6 +390,8 @@ public fun Route.options(body: RoutingHandler): Route { /** * Creates a routing entry for the specified path. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.createRouteFromPath) */ public fun Route.createRouteFromPath(path: String): Route { val parts = RoutingPath.parse(path).parts @@ -324,10 +413,14 @@ public fun Route.createRouteFromPath(path: String): Route { /** * A helper object for building instances of [RouteSelector] from path segments. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.PathSegmentSelectorBuilder) */ public object PathSegmentSelectorBuilder { /** * Builds a [RouteSelector] to match a path segment parameter with a prefix/suffix and name. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.PathSegmentSelectorBuilder.parseParameter) */ public fun parseParameter(value: String): RouteSelector { val prefixIndex = value.indexOf('{') @@ -352,6 +445,8 @@ public object PathSegmentSelectorBuilder { /** * Builds a [RouteSelector] to match a constant or wildcard segment parameter. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.PathSegmentSelectorBuilder.parseConstant) */ public fun parseConstant(value: String): RouteSelector = when (value) { "*" -> PathSegmentWildcardRouteSelector @@ -360,6 +455,8 @@ public object PathSegmentSelectorBuilder { /** * Parses a name out of segment specification. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.PathSegmentSelectorBuilder.parseName) */ public fun parseName(value: String): String { val prefix = value.substringBefore('{', "") diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RoutingNode.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RoutingNode.kt index 6984eceed66..9bf9c96477a 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RoutingNode.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RoutingNode.kt @@ -17,6 +17,9 @@ import kotlin.coroutines.* /** * Describes a node in a routing tree. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RoutingNode) + * * @see [Application.routing] * * @param parent is a parent node in the tree, or null for root node. @@ -34,6 +37,8 @@ public open class RoutingNode( /** * List of child routes for this node. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RoutingNode.children) */ public val children: List get() = childList @@ -45,6 +50,8 @@ public open class RoutingNode( /** * Creates a child node in this node with a given [selector] or returns an existing one with the same selector. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RoutingNode.createChild) */ public override fun createChild(selector: RouteSelector): RoutingNode { val existingEntry = childList.firstOrNull { it.selector == selector } @@ -58,11 +65,15 @@ public open class RoutingNode( /** * Allows using a route instance for building additional routes. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RoutingNode.invoke) */ public operator fun invoke(body: RoutingNode.() -> Unit): Unit = body() /** * Installs a handler into this route which is called when the route is selected for a call. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RoutingNode.handle) */ public override fun handle(body: RoutingHandler) { handlers.add(body) @@ -138,6 +149,9 @@ public open class RoutingNode( /** * A client's request that can be handled in [RoutingRoot]. * To learn how to handle incoming requests, see [Handling requests](https://ktor.io/docs/requests.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RoutingRequest) + * * @see [RoutingCall] * @see [RoutingResponse] */ @@ -159,6 +173,9 @@ public class RoutingRequest internal constructor( /** * A server's response that can be used to respond in [RoutingRoot]. * To learn how to send responses inside route handlers, see [Sending responses](https://ktor.io/docs/responses.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RoutingResponse) + * * @see [RoutingCall] * @see [RoutingRequest] */ @@ -189,6 +206,9 @@ public class RoutingResponse internal constructor( /** * A single act of communication between a client and server that is handled in [RoutingRoot]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RoutingCall) + * * @see [io.ktor.server.request.ApplicationRequest] * @see [io.ktor.server.response.ApplicationResponse] */ @@ -232,6 +252,8 @@ public class RoutingCall internal constructor( /** * The context of a [RoutingHandler] that is used to handle a [RoutingCall]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RoutingContext) */ public class RoutingContext( public val call: RoutingCall @@ -239,11 +261,15 @@ public class RoutingContext( /** * A function that handles a [RoutingCall]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RoutingHandler) */ public typealias RoutingHandler = suspend RoutingContext.() -> Unit /** * A builder for a routing tree. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.Route) */ public interface Route { public val environment: ApplicationEnvironment @@ -252,17 +278,24 @@ public interface Route { /** * Installs a handler into this route which is called when the route is selected for a call. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.Route.handle) */ public fun handle(body: RoutingHandler) /** * Creates a child node in this node with a given [selector] or returns an existing one with the same selector. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.Route.createChild) */ public fun createChild(selector: RouteSelector): Route /** * Gets a plugin instance for this pipeline, or fails with [MissingApplicationPluginException] * if the plugin is not installed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.Route.plugin) + * * @throws MissingApplicationPluginException * @param plugin [Plugin] to lookup * @return an instance of a plugin @@ -271,6 +304,9 @@ public interface Route { /** * Installs a [plugin] into this route, if it is not yet installed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.Route.install) + * * @return an instance of a plugin */ public fun install( @@ -281,6 +317,8 @@ public interface Route { /** * A builder for a routing tree root. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.Routing) */ public interface Routing : Route { @@ -288,12 +326,16 @@ public interface Routing : Route { * Registers a function used to trace route resolution. * Might be useful if you need to understand why a route isn't executed. * To learn more, see [Tracing routes](https://ktor.io/docs/tracing-routes.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.Routing.trace) */ public fun trace(block: (RoutingResolveTrace) -> Unit) } /** * Return list of endpoints with handlers under this route. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.getAllRoutes) */ public fun RoutingNode.getAllRoutes(): List { val endpoints = mutableListOf() diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RoutingPath.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RoutingPath.kt index c626e079bae..af3a1199594 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RoutingPath.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RoutingPath.kt @@ -9,18 +9,25 @@ import io.ktor.http.* /** * A parsed routing path. Consist of number of segments [parts]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RoutingPath) + * * @property parts contains parsed routing path segments */ public class RoutingPath private constructor(public val parts: List) { public companion object { /** * A constant for a root routing path. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RoutingPath.Companion.root) */ public val root: RoutingPath = RoutingPath(listOf()) /** * Parses the specified [path] and creates an instance of [RoutingPath]. * It handles wildcards and decodes escape characters properly. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RoutingPath.Companion.parse) */ public fun parse(path: String): RoutingPath { if (path == "/") return root @@ -43,6 +50,9 @@ public class RoutingPath private constructor(public val parts: List /** * Flag showing if path ends with slash + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RoutingResolveContext.hasTrailingSlash) */ public val hasTrailingSlash: Boolean = call.request.path().endsWith('/') @@ -78,6 +85,8 @@ public class RoutingResolveContext( /** * Executes resolution procedure in this context and returns [RoutingResolveResult] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RoutingResolveContext.resolve) */ public suspend fun resolve(): RoutingResolveResult { handleRoute(routing, 0, ArrayList(), MIN_QUALITY) diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RoutingResolveResult.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RoutingResolveResult.kt index 96ee6f67a76..35ba31b5564 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RoutingResolveResult.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RoutingResolveResult.kt @@ -9,16 +9,23 @@ import io.ktor.http.* /** * Represents a result of routing resolution. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RoutingResolveResult) + * * @property route specifies a routing node for successful resolution, or nearest one for failed. */ public sealed class RoutingResolveResult(public val route: RoutingNode) { /** * Provides all captured values for this result. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RoutingResolveResult.parameters) */ public abstract val parameters: Parameters /** * Represents a successful result + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RoutingResolveResult.Success) */ public class Success internal constructor( route: RoutingNode, @@ -37,6 +44,9 @@ public sealed class RoutingResolveResult(public val route: RoutingNode) { /** * Represents a failed result + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RoutingResolveResult.Failure) + * * @param reason provides information on reason of a failure */ public class Failure internal constructor( diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RoutingResolveTrace.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RoutingResolveTrace.kt index 5b72d1c0926..b1784dc01dc 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RoutingResolveTrace.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RoutingResolveTrace.kt @@ -8,6 +8,9 @@ import io.ktor.server.application.* /** * Represents a single entry in the [RoutingResolveTrace]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RoutingResolveTraceEntry) + * * @param route specifies instance of [RoutingNode] for this entry. * @param segmentIndex specifies index in [RoutingResolveTrace.segments] for this entry. * @param result specifies resolution result for this entry. @@ -24,6 +27,8 @@ public open class RoutingResolveTraceEntry( /** * Appends a child to this entry + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RoutingResolveTraceEntry.append) */ public fun append(item: RoutingResolveTraceEntry) { val items = children ?: mutableListOf().also { children = it } @@ -32,6 +37,8 @@ public open class RoutingResolveTraceEntry( /** * Builds detailed text description for this trace entry, including children. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RoutingResolveTraceEntry.buildText) */ public open fun buildText(builder: StringBuilder, indent: Int) { builder.appendLine(" ".repeat(indent) + toString()) @@ -43,6 +50,9 @@ public open class RoutingResolveTraceEntry( /** * Represents the trace of routing resolution process for diagnostics. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RoutingResolveTrace) + * * @param call instance of [PipelineCall] for which this trace was created. * @param segments list of [String]s for each path segment supplied for the routing resolution. */ @@ -62,6 +72,8 @@ public class RoutingResolveTrace(public val call: PipelineCall, public val segme /** * Begins processing a [route] at segment with [segmentIndex] in [segments]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RoutingResolveTrace.begin) */ public fun begin(route: RoutingNode, segmentIndex: Int) { stack.push(RoutingResolveTraceEntry(route, segmentIndex)) @@ -69,6 +81,8 @@ public class RoutingResolveTrace(public val call: PipelineCall, public val segme /** * Finishes processing a [route] at segment with [segmentIndex] in [segments] with the given [result]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RoutingResolveTrace.finish) */ public fun finish(route: RoutingNode, segmentIndex: Int, result: RoutingResolveResult) { val entry = stack.pop() @@ -80,6 +94,8 @@ public class RoutingResolveTrace(public val call: PipelineCall, public val segme /** * Begins and finishes processing a [route] at segment with [segmentIndex] in [segments] with the given [result]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RoutingResolveTrace.skip) */ public fun skip(route: RoutingNode, segmentIndex: Int, result: RoutingResolveResult) { register(RoutingResolveTraceEntry(route, segmentIndex, result)) @@ -93,6 +109,8 @@ public class RoutingResolveTrace(public val call: PipelineCall, public val segme /** * Builds detailed text description for this trace, including all entries. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RoutingResolveTrace.buildText) */ public fun buildText(): String = buildString { appendLine(this@RoutingResolveTrace.toString()) @@ -118,6 +136,8 @@ public class RoutingResolveTrace(public val call: PipelineCall, public val segme /** * Add candidate for resolving. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RoutingResolveTrace.addCandidate) */ public fun addCandidate(trait: List) { val candidate = List(trait.size) { trait[it] } diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RoutingRoot.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RoutingRoot.kt index 7519c959a6c..7e536fc9942 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RoutingRoot.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/routing/RoutingRoot.kt @@ -23,6 +23,9 @@ internal val LOGGER = KtorSimpleLogger("io.ktor.server.routing.Routing") * A root routing node of an [Application]. * You can learn more about routing in Ktor from [Routing](https://ktor.io/docs/routing-in-ktor.html). * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RoutingRoot) + * * @param application is an instance of [Application] for this routing node. */ @KtorDsl @@ -53,6 +56,8 @@ public class RoutingRoot( * Registers a function used to trace route resolution. * Might be useful if you need to understand why a route isn't executed. * To learn more, see [Tracing routes](https://ktor.io/docs/tracing-routes.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RoutingRoot.trace) */ public override fun trace(block: (RoutingResolveTrace) -> Unit) { tracers.add(block) @@ -122,17 +127,23 @@ public class RoutingRoot( /** * An installation object of the [RoutingRoot] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RoutingRoot.Plugin) */ @Suppress("PublicApiImplicitType") public companion object Plugin : BaseApplicationPlugin { /** * A definition for an event that is fired when routing-based call processing starts. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RoutingRoot.Plugin.RoutingCallStarted) */ public val RoutingCallStarted: EventDefinition = EventDefinition() /** * A definition for an event that is fired when routing-based call processing is finished. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.RoutingRoot.Plugin.RoutingCallFinished) */ public val RoutingCallFinished: EventDefinition = EventDefinition() @@ -148,6 +159,8 @@ public class RoutingRoot( /** * Gets an [Application] for this [RoutingNode] by scanning the hierarchy to the root. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.application) */ public val Route.application: Application get() = when (this) { @@ -160,6 +173,8 @@ public val Route.application: Application /** * Installs a [RoutingRoot] plugin for the this [Application] and runs a [configuration] script on it. * You can learn more about routing in Ktor from [Routing](https://ktor.io/docs/routing-in-ktor.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.routing.routing) */ @KtorDsl public fun Application.routing(configuration: Routing.() -> Unit): RoutingRoot = diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/util/Parameters.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/util/Parameters.kt index f2ca31ea7df..5f24242f86d 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/util/Parameters.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/util/Parameters.kt @@ -24,6 +24,9 @@ import kotlin.reflect.* * } * ``` * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.util.getValue) + * * @throws MissingRequestParameterException if no values associated with name * @throws ParameterConversionException when conversion from String to [R] fails */ @@ -33,6 +36,9 @@ public inline operator fun Parameters.getValue(thisRef: Any?, /** * Get parameters value associated with this [name] or fail with [MissingRequestParameterException] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.util.getOrFail) + * * @throws MissingRequestParameterException if no values associated with this [name] */ @Suppress("NOTHING_TO_INLINE") @@ -43,6 +49,9 @@ public inline fun Parameters.getOrFail(name: String): String { /** * Get parameter value associated with this [name] converting to type [R] using [DefaultConversionService] * or fail with [MissingRequestParameterException] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.util.getOrFail) + * * @throws MissingRequestParameterException if no values associated with this [name] * @throws ParameterConversionException when conversion from String to [R] fails */ diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/util/Paths.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/util/Paths.kt index 29d79819c7c..471090dec19 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/util/Paths.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/util/Paths.kt @@ -9,6 +9,8 @@ import io.ktor.util.* /** * Process path components such as `.` and `..`, replacing redundant path components including all leading. * It also discards all reserved characters and component names that are reserved (such as `CON`, `NUL`). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.util.normalizePathComponents) */ public fun List.normalizePathComponents(): List { for (index in indices) { diff --git a/ktor-server/ktor-server-core/common/src/io/ktor/server/util/URLBuilder.kt b/ktor-server/ktor-server-core/common/src/io/ktor/server/util/URLBuilder.kt index 6e024f9c5d5..eb0cadef0c2 100644 --- a/ktor-server/ktor-server-core/common/src/io/ktor/server/util/URLBuilder.kt +++ b/ktor-server/ktor-server-core/common/src/io/ktor/server/util/URLBuilder.kt @@ -11,6 +11,8 @@ import io.ktor.server.request.* /** * Creates an url using current call's schema, path and parameters as initial + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.util.createFromCall) */ public fun URLBuilder.Companion.createFromCall(call: ApplicationCall): URLBuilder { val origin = call.request.origin @@ -27,12 +29,16 @@ public fun URLBuilder.Companion.createFromCall(call: ApplicationCall): URLBuilde /** * Construct a URL + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.util.url) */ public fun url(block: URLBuilder.() -> Unit): String = URLBuilder().apply(block).buildString() /** * Creates an url using current call's schema, path and parameters as initial * and then invokes [block] function on the url builder so amend parameters + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.util.url) */ public inline fun ApplicationCall.url(block: URLBuilder.() -> Unit = {}): String = URLBuilder.createFromCall(this).apply(block).buildString() diff --git a/ktor-server/ktor-server-core/jsAndWasmShared/src/io/ktor/server/application/ApplicationEnvironment.jsAndWasmShared.kt b/ktor-server/ktor-server-core/jsAndWasmShared/src/io/ktor/server/application/ApplicationEnvironment.jsAndWasmShared.kt index 15ec46cad12..ae8f676533d 100644 --- a/ktor-server/ktor-server-core/jsAndWasmShared/src/io/ktor/server/application/ApplicationEnvironment.jsAndWasmShared.kt +++ b/ktor-server/ktor-server-core/jsAndWasmShared/src/io/ktor/server/application/ApplicationEnvironment.jsAndWasmShared.kt @@ -13,16 +13,22 @@ public actual interface ApplicationEnvironment { /** * Configuration for the [Application] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationEnvironment.config) */ public actual val config: ApplicationConfig /** * Instance of [Logger] to be used for logging. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationEnvironment.log) */ public actual val log: Logger /** * Provides events on Application lifecycle + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationEnvironment.monitor) */ @Deprecated( message = "Moved to Application", diff --git a/ktor-server/ktor-server-core/jsAndWasmShared/src/io/ktor/server/config/ConfigLoaders.jsAndWasmShared.kt b/ktor-server/ktor-server-core/jsAndWasmShared/src/io/ktor/server/config/ConfigLoaders.jsAndWasmShared.kt index 533bb2eac8c..5e1b0e319b7 100644 --- a/ktor-server/ktor-server-core/jsAndWasmShared/src/io/ktor/server/config/ConfigLoaders.jsAndWasmShared.kt +++ b/ktor-server/ktor-server-core/jsAndWasmShared/src/io/ktor/server/config/ConfigLoaders.jsAndWasmShared.kt @@ -13,6 +13,8 @@ internal actual val CONFIG_PATH: List /** * List of all registered [ConfigLoader] implementations. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.config.configLoaders) */ public actual val configLoaders: List get() = _configLoaders diff --git a/ktor-server/ktor-server-core/jsAndWasmShared/src/io/ktor/server/engine/ApplicationEngineEnvironment.jsAndWasmShared.kt b/ktor-server/ktor-server-core/jsAndWasmShared/src/io/ktor/server/engine/ApplicationEngineEnvironment.jsAndWasmShared.kt index e9f704e6b81..182e85a1408 100644 --- a/ktor-server/ktor-server-core/jsAndWasmShared/src/io/ktor/server/engine/ApplicationEngineEnvironment.jsAndWasmShared.kt +++ b/ktor-server/ktor-server-core/jsAndWasmShared/src/io/ktor/server/engine/ApplicationEngineEnvironment.jsAndWasmShared.kt @@ -12,22 +12,30 @@ import io.ktor.utils.io.* /** * Engine environment configuration builder + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ApplicationEnvironmentBuilder) */ @KtorDsl public actual class ApplicationEnvironmentBuilder { /** * Application logger + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ApplicationEnvironmentBuilder.log) */ public actual var log: Logger = KtorSimpleLogger("io.ktor.server.Application") /** * Application config + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ApplicationEnvironmentBuilder.config) */ public actual var config: ApplicationConfig = MapApplicationConfig() /** * Build an application engine environment + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ApplicationEnvironmentBuilder.build) */ public actual fun build(): ApplicationEnvironment { return ApplicationEnvironmentImplNix(log, config) diff --git a/ktor-server/ktor-server-core/jsAndWasmShared/src/io/ktor/server/engine/EngineConnectorConfing.jsAndWasmShared.kt b/ktor-server/ktor-server-core/jsAndWasmShared/src/io/ktor/server/engine/EngineConnectorConfing.jsAndWasmShared.kt index d02a3895c0f..c433d075fa3 100644 --- a/ktor-server/ktor-server-core/jsAndWasmShared/src/io/ktor/server/engine/EngineConnectorConfing.jsAndWasmShared.kt +++ b/ktor-server/ktor-server-core/jsAndWasmShared/src/io/ktor/server/engine/EngineConnectorConfing.jsAndWasmShared.kt @@ -6,6 +6,8 @@ package io.ktor.server.engine /** * Returns new instance of [EngineConnectorConfig] based on [this] with modified port + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.withPort) */ public actual fun EngineConnectorConfig.withPort( otherPort: Int diff --git a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/application/ApplicationEnvironment.kt b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/application/ApplicationEnvironment.kt index 6531e5629c0..6de21b6620c 100644 --- a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/application/ApplicationEnvironment.kt +++ b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/application/ApplicationEnvironment.kt @@ -11,6 +11,8 @@ import kotlin.coroutines.* /** * Represents an environment in which [Application] runs + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationEnvironment) */ public actual interface ApplicationEnvironment { @@ -18,21 +20,29 @@ public actual interface ApplicationEnvironment { * [ClassLoader] used to load application. * * Useful for various reflection-based services, like dependency injection. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationEnvironment.classLoader) */ public val classLoader: ClassLoader /** * Instance of [Logger] to be used for logging. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationEnvironment.log) */ public actual val log: Logger /** * Configuration for the [Application] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationEnvironment.config) */ public actual val config: ApplicationConfig /** * Provides events on Application lifecycle + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationEnvironment.monitor) */ @Deprecated( message = "Moved to Application", diff --git a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/config/HoconApplicationConfig.kt b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/config/HoconApplicationConfig.kt index 9160a232d65..a8808c2f9da 100644 --- a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/config/HoconApplicationConfig.kt +++ b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/config/HoconApplicationConfig.kt @@ -9,12 +9,17 @@ import java.io.* /** * Loads a [Config] from a hocon file. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.config.HoconConfigLoader) */ public class HoconConfigLoader : ConfigLoader { /** * Tries loading an application configuration from the specified [path]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.config.HoconConfigLoader.load) + * * @return configuration or null if the path is not found or configuration format is not supported. */ override fun load(path: String?): ApplicationConfig? { @@ -39,6 +44,8 @@ public class HoconConfigLoader : ConfigLoader { /** * Implements [ApplicationConfig] by loading configuration from HOCON data structures + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.config.HoconApplicationConfig) */ public open class HoconApplicationConfig(private val config: Config) : ApplicationConfig { override fun property(path: String): ApplicationConfigValue { @@ -77,17 +84,23 @@ public open class HoconApplicationConfig(private val config: Config) : Applicati /** * Returns a string value for [path] or `null` if missing + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.config.tryGetString) */ public fun Config.tryGetString(path: String): String? = if (hasPath(path)) getString(path) else null /** * Returns a list of values for [path] or `null` if missing + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.config.tryGetStringList) */ public fun Config.tryGetStringList(path: String): List? = if (hasPath(path)) getStringList(path) else null /** * Returns [ApplicationConfig] by loading configuration from a resource specified by [configPath] * or a default resource if [configPath] is `null` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.config.ApplicationConfig) */ public fun ApplicationConfig(configPath: String?): ApplicationConfig = ConfigLoader.load(configPath) diff --git a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/engine/ApplicationEngineJvm.kt b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/engine/ApplicationEngineJvm.kt index b0865cdd878..64419343645 100644 --- a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/engine/ApplicationEngineJvm.kt +++ b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/engine/ApplicationEngineJvm.kt @@ -9,6 +9,9 @@ import java.util.concurrent.* /** * Stops this [ApplicationEngine] * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.stop) + * * @param gracePeriod the maximum amount of time for activity to cool down * @param timeout the maximum amount of time to wait until server stops gracefully * @param timeUnit the [TimeUnit] for [gracePeriod] and [timeout] diff --git a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/engine/ApplicationEnvironmentJvm.kt b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/engine/ApplicationEnvironmentJvm.kt index 58512371801..843cbc9e434 100644 --- a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/engine/ApplicationEnvironmentJvm.kt +++ b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/engine/ApplicationEnvironmentJvm.kt @@ -12,26 +12,36 @@ import org.slf4j.* /** * Builder for configuring the environment of the Ktor application. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ApplicationEnvironmentBuilder) */ @KtorDsl public actual class ApplicationEnvironmentBuilder { /** * Root class loader. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ApplicationEnvironmentBuilder.classLoader) */ public var classLoader: ClassLoader = ApplicationEnvironmentBuilder::class.java.classLoader /** * Application logger. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ApplicationEnvironmentBuilder.log) */ public actual var log: Logger = LoggerFactory.getLogger("io.ktor.server.Application") /** * Configuration for the application. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ApplicationEnvironmentBuilder.config) */ public actual var config: ApplicationConfig = MapApplicationConfig() /** * Builds and returns an instance of the application engine environment based on the configured settings. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ApplicationEnvironmentBuilder.build) */ public actual fun build(): ApplicationEnvironment { return ApplicationEnvironmentImplJvm(classLoader, log, config) diff --git a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/engine/EmbeddedServerJvm.kt b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/engine/EmbeddedServerJvm.kt index 62930d38834..0d59c85720c 100644 --- a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/engine/EmbeddedServerJvm.kt +++ b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/engine/EmbeddedServerJvm.kt @@ -83,6 +83,8 @@ actual constructor( /** * Reload application: destroy it first and then create again + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.EmbeddedServer.reload) */ public fun reload() { applicationInstanceLock.write { diff --git a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/engine/EngineConnectorConfigJvm.kt b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/engine/EngineConnectorConfigJvm.kt index 0abeece2055..abdfc2b6760 100644 --- a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/engine/EngineConnectorConfigJvm.kt +++ b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/engine/EngineConnectorConfigJvm.kt @@ -9,6 +9,8 @@ import java.security.* /** * Adds a secure connector to this engine environment + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.sslConnector) */ public inline fun ApplicationEngine.Configuration.sslConnector( keyStore: KeyStore, @@ -22,6 +24,8 @@ public inline fun ApplicationEngine.Configuration.sslConnector( /** * Mutable implementation of EngineSSLConnectorConfig for building connectors programmatically + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.EngineSSLConnectorBuilder) */ public class EngineSSLConnectorBuilder( override var keyStore: KeyStore, @@ -38,30 +42,42 @@ public class EngineSSLConnectorBuilder( /** * Represents an SSL connector configuration. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.EngineSSLConnectorConfig) */ public interface EngineSSLConnectorConfig : EngineConnectorConfig { /** * KeyStore where a certificate is stored + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.EngineSSLConnectorConfig.keyStore) */ public val keyStore: KeyStore /** * File where the keystore is located + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.EngineSSLConnectorConfig.keyStorePath) */ public val keyStorePath: File? /** * TLS key alias + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.EngineSSLConnectorConfig.keyAlias) */ public val keyAlias: String /** * Keystore password provider + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.EngineSSLConnectorConfig.keyStorePassword) */ public val keyStorePassword: () -> CharArray /** * Private key password provider + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.EngineSSLConnectorConfig.privateKeyPassword) */ public val privateKeyPassword: () -> CharArray @@ -71,6 +87,8 @@ public interface EngineSSLConnectorConfig : EngineConnectorConfig { * The engine tries to use [trustStore] first and uses [trustStorePath] as a fallback. * * If [trustStore] and [trustStorePath] are both null, the endpoint's certificate will not be verified. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.EngineSSLConnectorConfig.trustStore) */ public val trustStore: KeyStore? @@ -80,17 +98,23 @@ public interface EngineSSLConnectorConfig : EngineConnectorConfig { * The engine tries to use [trustStore] first and uses [trustStorePath] as a fallback. * * If [trustStore] and [trustStorePath] are both null, the endpoint's certificate will not be verified. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.EngineSSLConnectorConfig.trustStorePath) */ public val trustStorePath: File? /** * Enabled protocol versions + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.EngineSSLConnectorConfig.enabledProtocols) */ public val enabledProtocols: List? } /** * Returns new instance of [EngineConnectorConfig] based on [this] with modified port + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.withPort) */ public actual fun EngineConnectorConfig.withPort(otherPort: Int): EngineConnectorConfig = when (this) { is EngineSSLConnectorBuilder -> object : EngineSSLConnectorConfig by this { diff --git a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/engine/ShutDownUrl.kt b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/engine/ShutDownUrl.kt index 0bf5f936205..4b99388a235 100644 --- a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/engine/ShutDownUrl.kt +++ b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/engine/ShutDownUrl.kt @@ -19,12 +19,17 @@ import kotlin.system.* * - By installing the plugin. * You can learn more from [Shutdown URL](https://ktor.io/docs/shutdown-url.html). * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ShutDownUrl) + * * @property url to handle * @property exitCode is a function to compute a process exit code */ public class ShutDownUrl(public val url: String, public val exitCode: ApplicationCall.() -> Int) { /** * Shuts down an application using the specified [call]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ShutDownUrl.doShutdown) */ public suspend fun doShutdown(call: ApplicationCall) { call.application.log.warn("Shutdown URL was called: server is going down") @@ -51,6 +56,8 @@ public class ShutDownUrl(public val url: String, public val exitCode: Applicatio /** * A plugin to install into an engine pipeline. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ShutDownUrl.EnginePlugin) */ public object EnginePlugin : BaseApplicationPlugin { override val key: AttributeKey = AttributeKey("shutdown.url") @@ -72,16 +79,22 @@ public class ShutDownUrl(public val url: String, public val exitCode: Applicatio /** * A configuration for the [ShutDownUrl] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ShutDownUrl.Config) */ @KtorDsl public class Config { /** * Specifies a URI used to handle a shutdown request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ShutDownUrl.Config.shutDownUrl) */ public var shutDownUrl: String = "/ktor/application/shutdown" /** * A function that provides a process exit code by an application call. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ShutDownUrl.Config.exitCodeSupplier) */ public var exitCodeSupplier: ApplicationCall.() -> Int = { 0 } } @@ -90,6 +103,8 @@ public class ShutDownUrl(public val url: String, public val exitCode: Applicatio /** * An installation object of the [ShutDownUrl] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ShutDownUrl.Companion.ApplicationCallPlugin) */ public val ApplicationCallPlugin: BaseApplicationPlugin = createApplicationPlugin("shutdown.url", ::Config) { diff --git a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/HttpDateJvm.kt b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/HttpDateJvm.kt index 745d9ac823b..4cef0fdd8c2 100644 --- a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/HttpDateJvm.kt +++ b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/HttpDateJvm.kt @@ -11,6 +11,8 @@ import java.util.* /** * Format as HTTP date (GMT) + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.toHttpDateString) */ public fun Temporal.toHttpDateString(): String = httpDateFormat.format(this) @@ -18,6 +20,8 @@ private val GreenwichMeanTime: ZoneId = ZoneId.of("GMT") /** * Default HTTP date format + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.httpDateFormat) */ public val httpDateFormat: DateTimeFormatter = DateTimeFormatter .ofPattern("EEE, dd MMM yyyy HH:mm:ss z") diff --git a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/content/CachingOptionsJvm.kt b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/content/CachingOptionsJvm.kt index 340c6436a5b..aa56a605934 100644 --- a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/content/CachingOptionsJvm.kt +++ b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/content/CachingOptionsJvm.kt @@ -11,6 +11,8 @@ import java.time.* /** * Creates [CachingOptions] instance with [ZonedDateTime] expiration time + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.CachingOptions) */ public fun CachingOptions(cacheControl: CacheControl? = null, expires: ZonedDateTime): CachingOptions = CachingOptions(cacheControl, expires.toGMTDate()) diff --git a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/content/JarFileContent.kt b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/content/JarFileContent.kt index bc92d788cca..e7708314530 100644 --- a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/content/JarFileContent.kt +++ b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/content/JarFileContent.kt @@ -16,6 +16,9 @@ import java.util.jar.* /** * Represents an [OutgoingContent] for a resource inside a Jar file * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.JarFileContent) + * * @param jarFile is an instance of [File] representing a Jar * @param resourcePath is an instance of a resource inside a Jar file */ diff --git a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/content/LastModifiedJavaTime.kt b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/content/LastModifiedJavaTime.kt index 09427bb2cd1..e68a0d7bcd2 100644 --- a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/content/LastModifiedJavaTime.kt +++ b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/content/LastModifiedJavaTime.kt @@ -14,18 +14,24 @@ import java.time.* /** * Construct [LastModifiedVersion] version from a [ZonedDateTime] instance + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.LastModifiedVersion) */ public fun LastModifiedVersion(lastModified: ZonedDateTime): LastModifiedVersion = LastModifiedVersion(lastModified.toGMTDate()) /** * Construct [LastModifiedVersion] version from a [FileTime] instance + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.LastModifiedVersion) */ public fun LastModifiedVersion(lastModified: FileTime): LastModifiedVersion = LastModifiedVersion(GMTDate(lastModified.toMillis())) /** * Construct [LastModifiedVersion] version from a [Long] instance + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.LastModifiedVersion) */ public fun LastModifiedVersion(lastModified: Long): LastModifiedVersion = LastModifiedVersion(GMTDate(lastModified)) diff --git a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/content/LocalFileContent.kt b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/content/LocalFileContent.kt index abf59447551..e8b3b7cfbbd 100644 --- a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/content/LocalFileContent.kt +++ b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/content/LocalFileContent.kt @@ -16,6 +16,9 @@ import kotlin.io.path.* /** * OutgoingContent representing a local [file] with a specified [contentType], [expires] date and [caching] * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.LocalFileContent) + * * @param file specifies the File to be served to a client */ public class LocalFileContent( @@ -43,6 +46,8 @@ public class LocalFileContent( /** * Creates an instance of [LocalFileContent] for a file designated by [relativePath] in a [baseDir] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.LocalFileContent) */ public fun LocalFileContent( baseDir: File, @@ -52,6 +57,8 @@ public fun LocalFileContent( /** * Creates an instance of [LocalPathContent] for a path designated by [relativePath] in a [baseDir] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.LocalFileContent) */ @Suppress("FunctionName") @Deprecated( @@ -66,6 +73,8 @@ public fun LocalFileContent( /** * Creates an instance of [LocalPathContent] for a path designated by [relativePath] in a [baseDir] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.LocalPathContent) */ public fun LocalPathContent( baseDir: Path, diff --git a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/content/PreCompressed.kt b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/content/PreCompressed.kt index 4ba5f869932..31e05deb8b4 100644 --- a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/content/PreCompressed.kt +++ b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/content/PreCompressed.kt @@ -20,6 +20,8 @@ import kotlin.io.path.* * Supported pre compressed file types and associated extensions * * **See Also:** [Accept-Encoding](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding) + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.CompressedFileType) */ public enum class CompressedFileType(public val extension: String, public val encoding: String = extension) { BROTLI("br"), diff --git a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/content/SinglePageApplication.kt b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/content/SinglePageApplication.kt index 8322309a01d..97e360c88c4 100644 --- a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/content/SinglePageApplication.kt +++ b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/content/SinglePageApplication.kt @@ -25,6 +25,8 @@ import java.io.* * } * } * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.singlePageApplication) */ public fun Route.singlePageApplication(configBuilder: SPAConfig.() -> Unit = {}) { val config = SPAConfig() @@ -53,6 +55,8 @@ public fun Route.singlePageApplication(configBuilder: SPAConfig.() -> Unit = {}) /** * Configuration for the [Route.singlePageApplication] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.SPAConfig) */ public class SPAConfig( /** @@ -86,6 +90,8 @@ public class SPAConfig( /** * Registers a [block] in [ignoredFiles] * [block] returns true if [path] should be ignored. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.ignoreFiles) */ public fun SPAConfig.ignoreFiles(block: (path: String) -> Boolean) { ignoredFiles += block @@ -94,6 +100,8 @@ public fun SPAConfig.ignoreFiles(block: (path: String) -> Boolean) { /** * Creates an application configuration for the Angular project. * Resources will be shared from the filesPath directory. The root file is index.html + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.angular) */ public fun SPAConfig.angular(filesPath: String) { this.filesPath = filesPath @@ -102,6 +110,8 @@ public fun SPAConfig.angular(filesPath: String) { /** * Creates an application configuration for the React project. * Resources will be shared from the filesPath directory. The root file is index.html + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.react) */ public fun SPAConfig.react(filesPath: String) { this.filesPath = filesPath @@ -110,6 +120,8 @@ public fun SPAConfig.react(filesPath: String) { /** * Creates an application configuration for the Vue project. * Resources will be shared from the filesPath directory. The root file is index.html + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.vue) */ public fun SPAConfig.vue(filesPath: String) { this.filesPath = filesPath @@ -118,6 +130,8 @@ public fun SPAConfig.vue(filesPath: String) { /** * Creates an application configuration for the Ember project. * Resources will be shared from the filesPath directory. The root file is index.html + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.ember) */ public fun SPAConfig.ember(filesPath: String) { this.filesPath = filesPath @@ -126,6 +140,8 @@ public fun SPAConfig.ember(filesPath: String) { /** * Creates an application configuration for the Backbone project. * Resources will be shared from the filesPath directory. The root file is index.html + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.backbone) */ public fun SPAConfig.backbone(filesPath: String) { this.filesPath = filesPath diff --git a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/content/StaticContent.kt b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/content/StaticContent.kt index 7d7e5a76a56..75a542e6286 100644 --- a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/content/StaticContent.kt +++ b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/content/StaticContent.kt @@ -26,6 +26,8 @@ import kotlin.io.path.pathString * Attribute to assign the path of a static file served in the response. The main use of this attribute is to indicate * to subsequent interceptors that a static file was served via the `ApplicationCall.isStaticContent()` extension * function. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.StaticFileLocationProperty) */ public val StaticFileLocationProperty: AttributeKey = AttributeKey("StaticFileLocation") @@ -53,6 +55,8 @@ private val StaticContentAutoHead = createRouteScopedPlugin("StaticContentAutoHe /** * A config for serving static content + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.StaticContentConfig) */ public class StaticContentConfig internal constructor() { @@ -84,6 +88,8 @@ public class StaticContentConfig internal constructor() { * * The order in types is *important*. * It will determine the priority of serving one versus serving another. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.StaticContentConfig.preCompressed) */ public fun preCompressed(vararg types: CompressedFileType) { preCompressedFileTypes = types.toList() @@ -91,6 +97,8 @@ public class StaticContentConfig internal constructor() { /** * Enables automatic response to a `HEAD` request for every file/resource that has a `GET` defined. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.StaticContentConfig.enableAutoHeadResponse) */ public fun enableAutoHeadResponse() { autoHeadResponse = true @@ -98,6 +106,8 @@ public class StaticContentConfig internal constructor() { /** * Configures default [Resource] to respond with, when requested file is not found. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.StaticContentConfig.default) */ public fun default(path: String?) { this.defaultPath = path @@ -108,6 +118,8 @@ public class StaticContentConfig internal constructor() { * If the [block] returns `null`, default behaviour of guessing [ContentType] from the header will be used. * For files, [Resource] is a requested [File]. * For resources, [Resource] is a [URL] to a requested resource. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.StaticContentConfig.contentType) */ public fun contentType(block: (Resource) -> ContentType?) { contentType = { resource -> block(resource) ?: defaultContentType(resource) } @@ -117,6 +129,8 @@ public class StaticContentConfig internal constructor() { * Configures [CacheControl] for requested static content. * For files, [Resource] is a requested [File]. * For resources, [Resource] is a [URL] to a requested resource. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.StaticContentConfig.cacheControl) */ public fun cacheControl(block: (Resource) -> List) { cacheControl = block @@ -127,6 +141,8 @@ public class StaticContentConfig internal constructor() { * Useful to add headers to the response, such as [HttpHeaders.ETag] * For files, [Resource] is a requested [File]. * For resources, [Resource] is a [URL] to a requested resource. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.StaticContentConfig.modify) */ public fun modify(block: suspend (Resource, ApplicationCall) -> Unit) { modifier = block @@ -138,6 +154,8 @@ public class StaticContentConfig internal constructor() { * Can be invoked multiple times. * For files, [Resource] is a requested [File]. * For resources, [Resource] is a [URL] to a requested resource. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.StaticContentConfig.exclude) */ public fun exclude(block: (Resource) -> Boolean) { val oldBlock = exclude @@ -154,6 +172,8 @@ public class StaticContentConfig internal constructor() { * Configures file extension fallbacks. * When set, if a file is not found, the search will repeat with the given extensions added to the file name. * The first match will be served. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.StaticContentConfig.extensions) */ public fun extensions(vararg extensions: String) { this.extensions = extensions.toList() @@ -169,6 +189,8 @@ public class StaticContentConfig internal constructor() { * If the requested file doesn't exist, or it is a directory and no [index] specified, response will be 404 Not Found. * * You can use [block] for additional set up. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.staticFiles) */ public fun Route.staticFiles( remotePath: String, @@ -209,6 +231,8 @@ public fun Route.staticFiles( * If requested resource doesn't exist and no [index] specified, response will be 404 Not Found. * * You can use [block] for additional set up. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.staticResources) */ public fun Route.staticResources( remotePath: String, @@ -249,6 +273,8 @@ public fun Route.staticResources( * If requested path doesn't exist and no [index] specified, response will be 404 Not Found. * * You can use [block] for additional set up. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.staticZip) */ public fun Route.staticZip( remotePath: String, @@ -316,6 +342,8 @@ private class ReloadingZipFileSystem( * If requested path doesn't exist and no [index] specified, response will be 404 Not Found. * * You can use [block] for additional set up. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.staticFileSystem) */ public fun Route.staticFileSystem( remotePath: String, @@ -362,6 +390,8 @@ public fun Route.staticFileSystem( * * The order in types is *important*. It will determine the priority of serving one versus serving another * * * This can't be disabled in a child route if it was enabled in the root route + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.preCompressed) */ public fun Route.preCompressed( vararg types: CompressedFileType = CompressedFileType.entries.toTypedArray(), @@ -376,6 +406,8 @@ public fun Route.preCompressed( /** * Base folder for relative files calculations for static content + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.staticRootFolder) */ public var Route.staticRootFolder: File? get() = attributes.getOrNull(staticRootFolderKey) ?: parent?.staticRootFolder @@ -394,12 +426,16 @@ private fun File?.combine(file: File) = when { /** * Create a block for static content + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.static) */ @Deprecated("Please use `staticFiles` or `staticResources` instead") public fun Route.static(configure: Route.() -> Unit): Route = apply(configure) /** * Create a block for static content at specified [remotePath] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.static) */ @Deprecated("Please use `staticFiles` or `staticResources` instead") public fun Route.static(remotePath: String, configure: Route.() -> Unit): Route = @@ -407,6 +443,8 @@ public fun Route.static(remotePath: String, configure: Route.() -> Unit): Route /** * Specifies [localPath] as a default file to serve when folder is requested + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.default) */ @Deprecated("Please use `staticFiles` instead") @@ -414,6 +452,8 @@ public fun Route.default(localPath: String): Unit = default(File(localPath)) /** * Specifies [localPath] as a default file to serve when folder is requested + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.default) */ @Deprecated("Please use `staticFiles` instead") public fun Route.default(localPath: File) { @@ -426,6 +466,8 @@ public fun Route.default(localPath: File) { /** * Sets up routing to serve [localPath] file as [remotePath] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.file) */ @Deprecated("Please use `staticFiles` instead") @@ -434,6 +476,8 @@ public fun Route.file(remotePath: String, localPath: String = remotePath): Unit /** * Sets up routing to serve [localPath] file as [remotePath] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.file) */ @Deprecated("Please use `staticFiles` instead") public fun Route.file(remotePath: String, localPath: File) { @@ -446,6 +490,8 @@ public fun Route.file(remotePath: String, localPath: File) { /** * Sets up routing to serve all files from [folder] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.files) */ @Deprecated("Please use `staticFiles` instead") @@ -453,6 +499,8 @@ public fun Route.files(folder: String): Unit = files(File(folder)) /** * Sets up routing to serve all files from [folder] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.files) */ @Deprecated("Please use `staticFiles` instead") public fun Route.files(folder: File) { @@ -469,6 +517,8 @@ private val staticBasePackageName = AttributeKey("BasePackage") /** * Base package for relative resources calculations for static content + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.staticBasePackage) */ @Deprecated("Please use `staticResources` instead") @@ -490,6 +540,8 @@ private fun String?.combinePackage(resourcePackage: String?) = when { /** * Sets up routing to serve [resource] as [remotePath] in [resourcePackage] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.resource) */ @Deprecated("Please use `staticResources` instead") @@ -507,6 +559,8 @@ public fun Route.resource(remotePath: String, resource: String = remotePath, res /** * Sets up routing to serve all resources in [resourcePackage] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.resources) */ @Deprecated("Please use `staticResources` instead") @@ -525,6 +579,8 @@ public fun Route.resources(resourcePackage: String? = null) { /** * Specifies [resource] as a default resources to serve when folder is requested + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.defaultResource) */ @Deprecated("Please use `staticResources` instead") @@ -542,6 +598,8 @@ public fun Route.defaultResource(resource: String, resourcePackage: String? = nu /** * Checks if the application call is requesting static content + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.isStaticContent) */ public fun ApplicationCall.isStaticContent(): Boolean = attributes.contains(StaticFileLocationProperty) @@ -718,11 +776,15 @@ private suspend fun ApplicationCall.respondStaticResource( /** * Wrapper on [FileSystem] for more specific delegation since we use only [getPath] method from it. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.FileSystemPaths) */ public interface FileSystemPaths { public companion object { /** * Creates a [FileSystemPaths] instance from a [FileSystem]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.FileSystemPaths.Companion.paths) */ public fun FileSystem.paths(): FileSystemPaths = object : FileSystemPaths { override fun getPath(first: String, vararg more: String): Path = this@paths.getPath(first, *more) @@ -732,6 +794,8 @@ public interface FileSystemPaths { /** * Converts a path string, or a sequence of strings that when joined form a path string, to a Path. * Equal to [FileSystem.getPath]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.FileSystemPaths.getPath) */ public fun getPath(first: String, vararg more: String): Path } diff --git a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/content/StaticContentResolution.kt b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/content/StaticContentResolution.kt index 4f672bc7133..16a7a9686b3 100644 --- a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/content/StaticContentResolution.kt +++ b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/content/StaticContentResolution.kt @@ -15,6 +15,9 @@ import java.net.* import java.util.concurrent.ConcurrentHashMap /** + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.resolveResource) + * * @param path is a relative path to the resource * @param resourcePackage is a base package the path to be appended to * @param mimeResolve is a function that resolves content type by file extension, optional @@ -71,6 +74,8 @@ internal fun Application.resolveResource( /** * Attempt to find a local file or a file inside of zip. This is not required but very good to have * to improve performance and unnecessary [java.io.InputStream] creation. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.http.content.resourceClasspathResource) */ @InternalAPI public fun resourceClasspathResource( diff --git a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/request/ApplicationReceiveFunctionsJvm.kt b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/request/ApplicationReceiveFunctionsJvm.kt index 469cd36291f..87da6d39fa5 100644 --- a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/request/ApplicationReceiveFunctionsJvm.kt +++ b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/request/ApplicationReceiveFunctionsJvm.kt @@ -9,6 +9,9 @@ import java.io.* /** * Receives stream content for this call. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.request.receiveStream) + * * @return instance of [InputStream] to read incoming bytes for this call. * @throws ContentTransformationException when content cannot be transformed to the [InputStream]. */ diff --git a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/response/ApplicationResponseFunctionsJvm.kt b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/response/ApplicationResponseFunctionsJvm.kt index 4fda24c56d9..44f26d18c18 100644 --- a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/response/ApplicationResponseFunctionsJvm.kt +++ b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/response/ApplicationResponseFunctionsJvm.kt @@ -16,6 +16,8 @@ import java.nio.file.* * * The [writer] parameter will be called later when engine is ready to produce content. * Provided [Writer] will be closed automatically. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.respondTextWriter) */ public suspend fun ApplicationCall.respondTextWriter( contentType: ContentType? = null, @@ -31,6 +33,8 @@ public suspend fun ApplicationCall.respondTextWriter( * * The [producer] parameter will be called later when engine is ready to produce content. You don't need to close it. * Provided [OutputStream] will be closed automatically. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.respondOutputStream) */ public suspend fun ApplicationCall.respondOutputStream( contentType: ContentType? = null, @@ -43,6 +47,8 @@ public suspend fun ApplicationCall.respondOutputStream( /** * Responds to a client with a contents of a file with the name [fileName] in the [baseDir] folder + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.respondFile) */ public suspend fun ApplicationCall.respondFile( baseDir: File, @@ -55,6 +61,8 @@ public suspend fun ApplicationCall.respondFile( /** * Responds to a client with a contents of a path designated by [relativePath] in the [baseDir] folder + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.respondPath) */ public suspend fun ApplicationCall.respondPath( baseDir: Path, @@ -67,6 +75,8 @@ public suspend fun ApplicationCall.respondPath( /** * Responds to a client with a contents of a [file] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.respondFile) */ public suspend fun ApplicationCall.respondFile(file: File, configure: OutgoingContent.() -> Unit = {}) { val message = LocalFileContent(file).apply(configure) @@ -75,6 +85,8 @@ public suspend fun ApplicationCall.respondFile(file: File, configure: OutgoingCo /** * Responds to a client with a contents of a [path] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.respondPath) */ public suspend fun ApplicationCall.respondPath(path: Path, configure: OutgoingContent.() -> Unit = {}) { val message = LocalPathContent(path).apply(configure) @@ -86,6 +98,8 @@ public suspend fun ApplicationCall.respondPath(path: Path, configure: OutgoingCo * * The [writer] parameter will be called later when engine is ready to produce content. * Provided [Writer] will be closed automatically. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.respondTextWriter) */ public suspend fun ApplicationCall.respondTextWriter( contentType: ContentType? = null, @@ -102,6 +116,8 @@ public suspend fun ApplicationCall.respondTextWriter( * * The [producer] parameter will be called later when engine is ready to produce content. You don't need to close it. * Provided [OutputStream] will be closed automatically. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.respondOutputStream) */ public suspend fun ApplicationCall.respondOutputStream( contentType: ContentType? = null, diff --git a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/response/ApplicationResponsePropertiesJvm.kt b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/response/ApplicationResponsePropertiesJvm.kt index f756598671f..aaad1821eed 100644 --- a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/response/ApplicationResponsePropertiesJvm.kt +++ b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/response/ApplicationResponsePropertiesJvm.kt @@ -11,27 +11,37 @@ import java.time.temporal.* /** * Append HTTP response header with temporal [date] (date, time and so on) + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.header) */ public fun ApplicationResponse.header(name: String, date: Temporal): Unit = headers.append(name, date.toHttpDateString()) /** * Append response `Last-Modified` HTTP header value from [dateTime] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.lastModified) */ public fun ApplicationResponse.lastModified(dateTime: ZonedDateTime): Unit = header(HttpHeaders.LastModified, dateTime) /** * Append response `Expires` HTTP header [value] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.expires) */ public fun ApplicationResponse.expires(value: LocalDateTime): Unit = header(HttpHeaders.Expires, value) /** * Set 'Last-Modified` header value from [dateTime] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.lastModified) */ public fun HeadersBuilder.lastModified(dateTime: ZonedDateTime): Unit = set(HttpHeaders.LastModified, dateTime.toHttpDateString()) /** * Set 'Expires` header value from [expires] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.response.expires) */ public fun HeadersBuilder.expires(expires: LocalDateTime): Unit = set(HttpHeaders.Expires, expires.toHttpDateString()) diff --git a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/util/DateUtilsJvm.kt b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/util/DateUtilsJvm.kt index d35f311b966..3b43d39a42e 100644 --- a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/util/DateUtilsJvm.kt +++ b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/util/DateUtilsJvm.kt @@ -12,29 +12,39 @@ import java.util.concurrent.* /** * Convert [Instant] to [GMTDate] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.util.toGMTDate) */ public fun Instant.toGMTDate(): GMTDate = GMTDate(TimeUnit.SECONDS.toMillis(atZone(ZoneOffset.UTC).toEpochSecond())) /** * Convert [ZonedDateTime] to [GMTDate] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.util.toGMTDate) */ public fun ZonedDateTime.toGMTDate(): GMTDate = toInstant().toGMTDate() /** * Creates [LocalDateTime] from this [Date] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.util.toLocalDateTime) */ @InternalAPI public fun Date.toLocalDateTime(): LocalDateTime = LocalDateTime.ofInstant(toInstant(), ZoneId.systemDefault()) /** * Creates [ZonedDateTime] from this [Date] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.util.toZonedDateTime) */ @InternalAPI public fun Date.toZonedDateTime(): ZonedDateTime = ZonedDateTime.ofInstant(toInstant(), GreenwichMeanTime) /** * [ZoneId] for GMT + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.util.GreenwichMeanTime) */ @InternalAPI public val GreenwichMeanTime: ZoneId = ZoneId.of("GMT") diff --git a/ktor-server/ktor-server-core/jvm/test/io/ktor/tests/server/engine/OverridingClassLoaderTest.kt b/ktor-server/ktor-server-core/jvm/test/io/ktor/tests/server/engine/OverridingClassLoaderTest.kt index dc352161f07..b12773180c0 100644 --- a/ktor-server/ktor-server-core/jvm/test/io/ktor/tests/server/engine/OverridingClassLoaderTest.kt +++ b/ktor-server/ktor-server-core/jvm/test/io/ktor/tests/server/engine/OverridingClassLoaderTest.kt @@ -68,6 +68,8 @@ class OverridingClassLoaderTest { /** * A class that loads resources as they generally do. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ChildLoadedClass) */ @Suppress("UNUSED") class ChildLoadedClass( diff --git a/ktor-server/ktor-server-core/posix/src/io/ktor/server/application/NixApplicationEnvironment.kt b/ktor-server/ktor-server-core/posix/src/io/ktor/server/application/NixApplicationEnvironment.kt index 15ec46cad12..ae8f676533d 100644 --- a/ktor-server/ktor-server-core/posix/src/io/ktor/server/application/NixApplicationEnvironment.kt +++ b/ktor-server/ktor-server-core/posix/src/io/ktor/server/application/NixApplicationEnvironment.kt @@ -13,16 +13,22 @@ public actual interface ApplicationEnvironment { /** * Configuration for the [Application] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationEnvironment.config) */ public actual val config: ApplicationConfig /** * Instance of [Logger] to be used for logging. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationEnvironment.log) */ public actual val log: Logger /** * Provides events on Application lifecycle + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.application.ApplicationEnvironment.monitor) */ @Deprecated( message = "Moved to Application", diff --git a/ktor-server/ktor-server-core/posix/src/io/ktor/server/config/ConfigLoadersNix.kt b/ktor-server/ktor-server-core/posix/src/io/ktor/server/config/ConfigLoadersNix.kt index 533bb2eac8c..5e1b0e319b7 100644 --- a/ktor-server/ktor-server-core/posix/src/io/ktor/server/config/ConfigLoadersNix.kt +++ b/ktor-server/ktor-server-core/posix/src/io/ktor/server/config/ConfigLoadersNix.kt @@ -13,6 +13,8 @@ internal actual val CONFIG_PATH: List /** * List of all registered [ConfigLoader] implementations. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.config.configLoaders) */ public actual val configLoaders: List get() = _configLoaders diff --git a/ktor-server/ktor-server-core/posix/src/io/ktor/server/engine/ApplicationEngineEnvironmentNix.kt b/ktor-server/ktor-server-core/posix/src/io/ktor/server/engine/ApplicationEngineEnvironmentNix.kt index e9f704e6b81..182e85a1408 100644 --- a/ktor-server/ktor-server-core/posix/src/io/ktor/server/engine/ApplicationEngineEnvironmentNix.kt +++ b/ktor-server/ktor-server-core/posix/src/io/ktor/server/engine/ApplicationEngineEnvironmentNix.kt @@ -12,22 +12,30 @@ import io.ktor.utils.io.* /** * Engine environment configuration builder + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ApplicationEnvironmentBuilder) */ @KtorDsl public actual class ApplicationEnvironmentBuilder { /** * Application logger + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ApplicationEnvironmentBuilder.log) */ public actual var log: Logger = KtorSimpleLogger("io.ktor.server.Application") /** * Application config + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ApplicationEnvironmentBuilder.config) */ public actual var config: ApplicationConfig = MapApplicationConfig() /** * Build an application engine environment + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.ApplicationEnvironmentBuilder.build) */ public actual fun build(): ApplicationEnvironment { return ApplicationEnvironmentImplNix(log, config) diff --git a/ktor-server/ktor-server-core/posix/src/io/ktor/server/engine/EngineConnectorConfingNative.kt b/ktor-server/ktor-server-core/posix/src/io/ktor/server/engine/EngineConnectorConfingNative.kt index d02a3895c0f..c433d075fa3 100644 --- a/ktor-server/ktor-server-core/posix/src/io/ktor/server/engine/EngineConnectorConfingNative.kt +++ b/ktor-server/ktor-server-core/posix/src/io/ktor/server/engine/EngineConnectorConfingNative.kt @@ -6,6 +6,8 @@ package io.ktor.server.engine /** * Returns new instance of [EngineConnectorConfig] based on [this] with modified port + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.engine.withPort) */ public actual fun EngineConnectorConfig.withPort( otherPort: Int diff --git a/ktor-server/ktor-server-jetty-jakarta/jvm/src/io/ktor/server/jetty/jakarta/Embedded.kt b/ktor-server/ktor-server-jetty-jakarta/jvm/src/io/ktor/server/jetty/jakarta/Embedded.kt index 32b8f0003d4..e42b395889c 100644 --- a/ktor-server/ktor-server-jetty-jakarta/jvm/src/io/ktor/server/jetty/jakarta/Embedded.kt +++ b/ktor-server/ktor-server-jetty-jakarta/jvm/src/io/ktor/server/jetty/jakarta/Embedded.kt @@ -10,6 +10,8 @@ import io.ktor.server.engine.* /** * An [ApplicationEngineFactory] providing a Jetty-based [ApplicationEngine] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.jetty.jakarta.Jetty) */ public object Jetty : ApplicationEngineFactory { diff --git a/ktor-server/ktor-server-jetty-jakarta/jvm/src/io/ktor/server/jetty/jakarta/EngineMain.kt b/ktor-server/ktor-server-jetty-jakarta/jvm/src/io/ktor/server/jetty/jakarta/EngineMain.kt index 352c74172ea..79bfd290c73 100644 --- a/ktor-server/ktor-server-jetty-jakarta/jvm/src/io/ktor/server/jetty/jakarta/EngineMain.kt +++ b/ktor-server/ktor-server-jetty-jakarta/jvm/src/io/ktor/server/jetty/jakarta/EngineMain.kt @@ -9,11 +9,15 @@ import io.ktor.server.engine.* /** * Jetty engine + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.jetty.jakarta.EngineMain) */ public object EngineMain { /** * Main function for starting EngineMain with Jetty * Creates an embedded Jetty application with an environment built from command line arguments. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.jetty.jakarta.EngineMain.main) */ @JvmStatic public fun main(args: Array) { diff --git a/ktor-server/ktor-server-jetty-jakarta/jvm/src/io/ktor/server/jetty/jakarta/JettyApplicationEngine.kt b/ktor-server/ktor-server-jetty-jakarta/jvm/src/io/ktor/server/jetty/jakarta/JettyApplicationEngine.kt index 90588d76c69..18eb849c86d 100644 --- a/ktor-server/ktor-server-jetty-jakarta/jvm/src/io/ktor/server/jetty/jakarta/JettyApplicationEngine.kt +++ b/ktor-server/ktor-server-jetty-jakarta/jvm/src/io/ktor/server/jetty/jakarta/JettyApplicationEngine.kt @@ -11,6 +11,8 @@ import kotlinx.coroutines.* /** * [ApplicationEngine] implementation for running in a standalone Jetty + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.jetty.jakarta.JettyApplicationEngine) */ public class JettyApplicationEngine( environment: ApplicationEnvironment, diff --git a/ktor-server/ktor-server-jetty-jakarta/jvm/src/io/ktor/server/jetty/jakarta/JettyApplicationEngineBase.kt b/ktor-server/ktor-server-jetty-jakarta/jvm/src/io/ktor/server/jetty/jakarta/JettyApplicationEngineBase.kt index c672da27495..cfe34d9386d 100644 --- a/ktor-server/ktor-server-jetty-jakarta/jvm/src/io/ktor/server/jetty/jakarta/JettyApplicationEngineBase.kt +++ b/ktor-server/ktor-server-jetty-jakarta/jvm/src/io/ktor/server/jetty/jakarta/JettyApplicationEngineBase.kt @@ -15,6 +15,8 @@ import kotlin.time.Duration.Companion.seconds /** * [ApplicationEngine] base type for running in a standalone Jetty + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.jetty.jakarta.JettyApplicationEngineBase) */ public open class JettyApplicationEngineBase( environment: ApplicationEnvironment, @@ -29,16 +31,22 @@ public open class JettyApplicationEngineBase( /** * Jetty-specific engine configuration + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.jetty.jakarta.JettyApplicationEngineBase.Configuration) */ public class Configuration : BaseApplicationEngine.Configuration() { /** * Property function that will be called during Jetty server initialization * with the server instance as receiver. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.jetty.jakarta.JettyApplicationEngineBase.Configuration.configureServer) */ public var configureServer: Server.() -> Unit = {} /** * The duration of time that a connection can be idle before the connector takes action to close the connection. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.jetty.jakarta.JettyApplicationEngineBase.Configuration.idleTimeout) */ public var idleTimeout: Duration = 30.seconds } diff --git a/ktor-server/ktor-server-jetty-jakarta/jvm/test/io/ktor/tests/server/jetty/jakarta/MultipleDispatchOnTimeout.kt b/ktor-server/ktor-server-jetty-jakarta/jvm/test/io/ktor/tests/server/jetty/jakarta/MultipleDispatchOnTimeout.kt index d5982a23975..d730dce7c8f 100644 --- a/ktor-server/ktor-server-jetty-jakarta/jvm/test/io/ktor/tests/server/jetty/jakarta/MultipleDispatchOnTimeout.kt +++ b/ktor-server/ktor-server-jetty-jakarta/jvm/test/io/ktor/tests/server/jetty/jakarta/MultipleDispatchOnTimeout.kt @@ -24,6 +24,8 @@ class MultipleDispatchOnTimeout { * We are testing that the servlet container does not trigger an extra error dispatch for calls that timeout from * the perspective of the servlet container. The fact that it does so is apparently specified here on this url: * https://docs.oracle.com/javaee/6/api/javax/servlet/AsyncContext.html + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.tests.server.jetty.jakarta.MultipleDispatchOnTimeout.calls with duration longer than default timeout do not trigger a redispatch) */ @Test fun `calls with duration longer than default timeout do not trigger a redispatch`() { diff --git a/ktor-server/ktor-server-jetty-jakarta/ktor-server-jetty-test-http2-jakarta/jvm/test/io/ktor/tests/server/jetty/http2/jakarta/MultipleDispatchOnTimeout.kt b/ktor-server/ktor-server-jetty-jakarta/ktor-server-jetty-test-http2-jakarta/jvm/test/io/ktor/tests/server/jetty/http2/jakarta/MultipleDispatchOnTimeout.kt index 56a7c0e945c..48c97996349 100644 --- a/ktor-server/ktor-server-jetty-jakarta/ktor-server-jetty-test-http2-jakarta/jvm/test/io/ktor/tests/server/jetty/http2/jakarta/MultipleDispatchOnTimeout.kt +++ b/ktor-server/ktor-server-jetty-jakarta/ktor-server-jetty-test-http2-jakarta/jvm/test/io/ktor/tests/server/jetty/http2/jakarta/MultipleDispatchOnTimeout.kt @@ -24,6 +24,8 @@ class MultipleDispatchOnTimeout { * We are testing that the servlet container does not trigger an extra error dispatch for calls that timeout from * the perspective of the servlet container. The fact that it does so is apparently specified here on this url: * https://docs.oracle.com/javaee/6/api/javax/servlet/AsyncContext.html + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.tests.server.jetty.http2.jakarta.MultipleDispatchOnTimeout.calls with duration longer than default timeout do not trigger a redispatch) */ @Test fun `calls with duration longer than default timeout do not trigger a redispatch`() { diff --git a/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/Embedded.kt b/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/Embedded.kt index cb50a95e4b9..683dc3b7337 100644 --- a/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/Embedded.kt +++ b/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/Embedded.kt @@ -10,6 +10,8 @@ import io.ktor.server.engine.* /** * An [ApplicationEngineFactory] providing a Jetty-based [ApplicationEngine] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.jetty.Jetty) */ @Deprecated( "The ktor-server-jetty module is deprecated and will be removed in the next major release as it " + diff --git a/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/EngineMain.kt b/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/EngineMain.kt index 09067b51ef5..0fe4a6f7fd6 100644 --- a/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/EngineMain.kt +++ b/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/EngineMain.kt @@ -9,6 +9,8 @@ import io.ktor.server.engine.* /** * Jetty engine + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.jetty.EngineMain) */ @Deprecated( "The ktor-server-jetty module is deprecated and will be removed in the next major release as it " + @@ -18,6 +20,8 @@ public object EngineMain { /** * Main function for starting EngineMain with Jetty * Creates an embedded Jetty application with an environment built from command line arguments. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.jetty.EngineMain.main) */ @JvmStatic public fun main(args: Array) { diff --git a/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/JettyApplicationEngine.kt b/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/JettyApplicationEngine.kt index 42ed97adf68..5501edf4dca 100644 --- a/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/JettyApplicationEngine.kt +++ b/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/JettyApplicationEngine.kt @@ -11,6 +11,8 @@ import kotlinx.coroutines.* /** * [ApplicationEngine] implementation for running in a standalone Jetty + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.jetty.JettyApplicationEngine) */ public class JettyApplicationEngine( environment: ApplicationEnvironment, diff --git a/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/JettyApplicationEngineBase.kt b/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/JettyApplicationEngineBase.kt index f0f17ccfd28..677c7fbded7 100644 --- a/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/JettyApplicationEngineBase.kt +++ b/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/JettyApplicationEngineBase.kt @@ -15,6 +15,8 @@ import kotlin.time.Duration.Companion.seconds /** * [ApplicationEngine] base type for running in a standalone Jetty + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.jetty.JettyApplicationEngineBase) */ public open class JettyApplicationEngineBase( environment: ApplicationEnvironment, @@ -29,16 +31,22 @@ public open class JettyApplicationEngineBase( /** * Jetty-specific engine configuration + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.jetty.JettyApplicationEngineBase.Configuration) */ public class Configuration : BaseApplicationEngine.Configuration() { /** * Property function that will be called during Jetty server initialization * with the server instance as receiver. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.jetty.JettyApplicationEngineBase.Configuration.configureServer) */ public var configureServer: Server.() -> Unit = {} /** * The duration of time that a connection can be idle before the connector takes action to close the connection. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.jetty.JettyApplicationEngineBase.Configuration.idleTimeout) */ public var idleTimeout: Duration = 30.seconds } diff --git a/ktor-server/ktor-server-jetty/jvm/test/io/ktor/tests/server/jetty/MultipleDispatchOnTimeout.kt b/ktor-server/ktor-server-jetty/jvm/test/io/ktor/tests/server/jetty/MultipleDispatchOnTimeout.kt index 2ed6766ba03..1f951a13d4f 100644 --- a/ktor-server/ktor-server-jetty/jvm/test/io/ktor/tests/server/jetty/MultipleDispatchOnTimeout.kt +++ b/ktor-server/ktor-server-jetty/jvm/test/io/ktor/tests/server/jetty/MultipleDispatchOnTimeout.kt @@ -24,6 +24,8 @@ class MultipleDispatchOnTimeout { * We are testing that the servlet container does not trigger an extra error dispatch for calls that timeout from * the perspective of the servlet container. The fact that it does so is apparently specified here on this url: * https://docs.oracle.com/javaee/6/api/javax/servlet/AsyncContext.html + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.tests.server.jetty.MultipleDispatchOnTimeout.calls with duration longer than default timeout do not trigger a redispatch) */ @Test fun `calls with duration longer than default timeout do not trigger a redispatch`() { diff --git a/ktor-server/ktor-server-jetty/ktor-server-jetty-test-http2/jvm/test/io/ktor/tests/server/jetty/http2/MultipleDispatchOnTimeout.kt b/ktor-server/ktor-server-jetty/ktor-server-jetty-test-http2/jvm/test/io/ktor/tests/server/jetty/http2/MultipleDispatchOnTimeout.kt index db9b6a9c88c..ad9ac6c1065 100644 --- a/ktor-server/ktor-server-jetty/ktor-server-jetty-test-http2/jvm/test/io/ktor/tests/server/jetty/http2/MultipleDispatchOnTimeout.kt +++ b/ktor-server/ktor-server-jetty/ktor-server-jetty-test-http2/jvm/test/io/ktor/tests/server/jetty/http2/MultipleDispatchOnTimeout.kt @@ -24,6 +24,8 @@ class MultipleDispatchOnTimeout { * We are testing that the servlet container does not trigger an extra error dispatch for calls that timeout from * the perspective of the servlet container. The fact that it does so is apparently specified here on this url: * https://docs.oracle.com/javaee/6/api/javax/servlet/AsyncContext.html + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.tests.server.jetty.http2.MultipleDispatchOnTimeout.calls with duration longer than default timeout do not trigger a redispatch) */ @Test fun `calls with duration longer than default timeout do not trigger a redispatch`() { diff --git a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/CIO.kt b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/CIO.kt index ef6e390f842..92a6b44517a 100644 --- a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/CIO.kt +++ b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/CIO.kt @@ -24,6 +24,8 @@ private val identityErrorHandler = { t: Throwable, c: Continuation<*> -> /** * Suspend until the future completion. * Resumes with the same exception if the future completes exceptionally + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.netty.suspendAwait) */ public suspend fun Future.suspendAwait(): T { return suspendAwait(identityErrorHandler) @@ -41,6 +43,8 @@ private val wrappingErrorHandler = { t: Throwable, c: Continuation<*> -> /** * Suspend until the future completion. * Wraps futures completion exceptions into [ChannelWriteException] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.netty.suspendWriteAwait) */ public suspend fun Future.suspendWriteAwait(): T { return suspendAwait(wrappingErrorHandler) @@ -48,6 +52,8 @@ public suspend fun Future.suspendWriteAwait(): T { /** * Suspend until the future completion handling exception from the future using [exception] function + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.netty.suspendAwait) */ public suspend fun Future.suspendAwait(exception: (Throwable, Continuation) -> Unit): T { @Suppress("BlockingMethodInNonBlockingContext") diff --git a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/Embedded.kt b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/Embedded.kt index 84d91913ec7..ceec9350c1d 100644 --- a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/Embedded.kt +++ b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/Embedded.kt @@ -10,6 +10,8 @@ import io.ktor.server.engine.* /** * An [ApplicationEngineFactory] providing a Netty-based [ApplicationEngine] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.netty.Netty) */ public object Netty : ApplicationEngineFactory { diff --git a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/EngineMain.kt b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/EngineMain.kt index 1fc73c5ae88..59de8d027ff 100644 --- a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/EngineMain.kt +++ b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/EngineMain.kt @@ -9,11 +9,15 @@ import io.ktor.server.engine.* /** * Netty engine + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.netty.EngineMain) */ public object EngineMain { /** * Main function for starting EngineMain with Netty * Creates an embedded Netty application with an environment built from command line arguments. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.netty.EngineMain.main) */ @JvmStatic public fun main(args: Array) { diff --git a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/EventLoopGroupProxy.kt b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/EventLoopGroupProxy.kt index ac7cceb66d0..479d3e6b01a 100644 --- a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/EventLoopGroupProxy.kt +++ b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/EventLoopGroupProxy.kt @@ -17,6 +17,8 @@ import kotlin.reflect.* /** * Transparently allows for the creation of [EventLoopGroup]'s utilising the optimal implementation for * a given operating system, subject to availability, or falling back to [NioEventLoopGroup] if none is available. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.netty.EventLoopGroupProxy) */ public class EventLoopGroupProxy( public val channel: KClass, diff --git a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/NettyApplicationEngine.kt b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/NettyApplicationEngine.kt index cd05159e516..d41e0a894f3 100644 --- a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/NettyApplicationEngine.kt +++ b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/NettyApplicationEngine.kt @@ -33,6 +33,8 @@ private val AFTER_CALL_PHASE = PipelinePhase("After") /** * [ApplicationEngine] implementation for running in a standalone Netty + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.netty.NettyApplicationEngine) */ public class NettyApplicationEngine( environment: ApplicationEnvironment, @@ -44,31 +46,43 @@ public class NettyApplicationEngine( /** * Configuration for the [NettyApplicationEngine] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.netty.NettyApplicationEngine.Configuration) */ public class Configuration : BaseApplicationEngine.Configuration() { /** * Number of concurrently running requests from the same http pipeline + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.netty.NettyApplicationEngine.Configuration.runningLimit) */ public var runningLimit: Int = 32 /** * Do not create separate call event group and reuse worker group for processing calls + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.netty.NettyApplicationEngine.Configuration.shareWorkGroup) */ public var shareWorkGroup: Boolean = false /** * User-provided function to configure Netty's [ServerBootstrap] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.netty.NettyApplicationEngine.Configuration.configureBootstrap) */ public var configureBootstrap: ServerBootstrap.() -> Unit = {} /** * Timeout in seconds for sending responses to client + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.netty.NettyApplicationEngine.Configuration.responseWriteTimeoutSeconds) */ public var responseWriteTimeoutSeconds: Int = 10 /** * Timeout in seconds for reading requests from client, "0" is infinite. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.netty.NettyApplicationEngine.Configuration.requestReadTimeoutSeconds) */ public var requestReadTimeoutSeconds: Int = 0 @@ -77,37 +91,51 @@ public class NettyApplicationEngine( * dead client connections will be discarded. * The timeout period is configured by the system so configure * your host accordingly. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.netty.NettyApplicationEngine.Configuration.tcpKeepAlive) */ public var tcpKeepAlive: Boolean = false /** * The url limit including query parameters + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.netty.NettyApplicationEngine.Configuration.maxInitialLineLength) */ public var maxInitialLineLength: Int = HttpObjectDecoder.DEFAULT_MAX_INITIAL_LINE_LENGTH /** * The maximum length of all headers. * If the sum of the length of each header exceeds this value, a TooLongFrameException will be raised. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.netty.NettyApplicationEngine.Configuration.maxHeaderSize) */ public var maxHeaderSize: Int = HttpObjectDecoder.DEFAULT_MAX_HEADER_SIZE /** * The maximum length of the content or each chunk + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.netty.NettyApplicationEngine.Configuration.maxChunkSize) */ public var maxChunkSize: Int = HttpObjectDecoder.DEFAULT_MAX_CHUNK_SIZE /** * If set to `true`, enables HTTP/2 protocol for Netty engine + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.netty.NettyApplicationEngine.Configuration.enableHttp2) */ public var enableHttp2: Boolean = true /** * User-provided function to configure Netty's [HttpServerCodec] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.netty.NettyApplicationEngine.Configuration.httpServerCodec) */ public var httpServerCodec: () -> HttpServerCodec = this::defaultHttpServerCodec /** * User-provided function to configure Netty's [ChannelPipeline] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.netty.NettyApplicationEngine.Configuration.channelPipelineConfig) */ public var channelPipelineConfig: ChannelPipeline.() -> Unit = {} diff --git a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/NettyChannelInitializer.kt b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/NettyChannelInitializer.kt index 55eaed5ceb0..a3e59c34c95 100644 --- a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/NettyChannelInitializer.kt +++ b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/NettyChannelInitializer.kt @@ -25,6 +25,8 @@ import kotlin.coroutines.* /** * A [ChannelInitializer] implementation that sets up the default ktor channel pipeline + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.netty.NettyChannelInitializer) */ public class NettyChannelInitializer( private val applicationProvider: () -> Application, diff --git a/ktor-server/ktor-server-plugins/ktor-server-auth-jwt/jvm/src/io/ktor/server/auth/jwt/JWTAuth.kt b/ktor-server/ktor-server-plugins/ktor-server-auth-jwt/jvm/src/io/ktor/server/auth/jwt/JWTAuth.kt index 83bd3edfbb0..4f4b9501a1d 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-auth-jwt/jvm/src/io/ktor/server/auth/jwt/JWTAuth.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-auth-jwt/jvm/src/io/ktor/server/auth/jwt/JWTAuth.kt @@ -24,6 +24,8 @@ internal val JWTLogger: Logger = LoggerFactory.getLogger("io.ktor.auth.jwt") /** * Shortcut functions for standard registered JWT claims. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.jwt.JWTPayloadHolder) */ public abstract class JWTPayloadHolder( /** @@ -34,30 +36,40 @@ public abstract class JWTPayloadHolder( /** * Gets a value of the `iss` (issuer) claim, which specifies the issuer of the JWT. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.jwt.JWTPayloadHolder.issuer) */ public val issuer: String? get() = payload.issuer /** * Gets a value of the `sub` (subject) claim, or null if it's not available. * The `sub` claim specifies a subject of the JWT (the user). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.jwt.JWTPayloadHolder.subject) */ public val subject: String? get() = payload.subject /** * Gets the value of the `aud` (audience) claim, or an empty list if it's not available. * The `aud` claim specifies a recipient for which the JWT is intended. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.jwt.JWTPayloadHolder.audience) */ public val audience: List get() = payload.audience ?: emptyList() /** * Gets the value of the `exp` (expiration time) claim, or null if it's not available. * This claim specifies a time after which the JWT expires. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.jwt.JWTPayloadHolder.expiresAt) */ public val expiresAt: Date? get() = payload.expiresAt /** * Gets the value of the `nbf` (not before time) claim, or null if it's not available. * The `nbf` specifies a time before which the JWT must not be accepted for processing. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.jwt.JWTPayloadHolder.notBefore) */ public val notBefore: Date? get() = payload.notBefore @@ -65,6 +77,8 @@ public abstract class JWTPayloadHolder( * Gets the value of the `iat` (issued at) claim, or null if it's not available. * The `iat` claim specifies a time at which the JWT was issued. * This claim can be used to determine the age of the JWT. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.jwt.JWTPayloadHolder.issuedAt) */ public val issuedAt: Date? get() = payload.issuedAt @@ -73,12 +87,17 @@ public abstract class JWTPayloadHolder( * The `jti` claim specifies provides a unique identifier for the JWT. * This claim can be used to prevent the JWT from being replayed * (allows a token to be used only once). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.jwt.JWTPayloadHolder.jwtId) */ public val jwtId: String? get() = payload.id /** * Gets a non-RFC JWT claim by its name. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.jwt.JWTPayloadHolder.get) + * * @param name a claim's key as it appears in the JSON object * @return a claim's value or null if not available or not a string */ @@ -89,6 +108,9 @@ public abstract class JWTPayloadHolder( /** * Gets a non-RFC JWT claim by its name and attempts to decode it as the specified type. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.jwt.JWTPayloadHolder.getClaim) + * * @param name a claim's key as it appears in the JSON object * @return a claim's value or null if not available or unable to deserialize */ @@ -103,6 +125,9 @@ public abstract class JWTPayloadHolder( /** * Retrieves a non-RFC JWT claim by its name and attempts to decode it as a list of the specified type. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.jwt.JWTPayloadHolder.getListClaim) + * * @param name a claim's key as it appears in the JSON object * @return a claim's value or an empty list if not available or unable to deserialize */ @@ -117,6 +142,9 @@ public abstract class JWTPayloadHolder( /** * A JWT credential that consists of the specified [payload]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.jwt.JWTCredential) + * * @param payload JWT * @see Payload */ @@ -124,6 +152,9 @@ public class JWTCredential(payload: Payload) : JWTPayloadHolder(payload) /** * A JWT principal that consists of the specified [payload]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.jwt.JWTPrincipal) + * * @param payload JWT * @see Payload */ @@ -131,12 +162,17 @@ public class JWTPrincipal(payload: Payload) : JWTPayloadHolder(payload) /** * A JWT verifier function used to verify a token format and its signature. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.jwt.JWTConfigureFunction) */ public typealias JWTConfigureFunction = Verification.() -> Unit /** * A JWT [Authentication] provider. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.jwt.JWTAuthenticationProvider) + * * @see [jwt] */ public class JWTAuthenticationProvider internal constructor(config: Config) : AuthenticationProvider(config) { @@ -187,6 +223,8 @@ public class JWTAuthenticationProvider internal constructor(config: Config) : Au /** * A configuration for the [jwt] authentication provider. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.jwt.JWTAuthenticationProvider.Config) */ public class Config internal constructor(name: String?) : AuthenticationProvider.Config(name) { internal var authenticationFunction: AuthenticationFunction = { @@ -215,18 +253,25 @@ public class JWTAuthenticationProvider internal constructor(config: Config) : Au /** * Specifies a JWT realm to be passed in `WWW-Authenticate` header. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.jwt.JWTAuthenticationProvider.Config.realm) */ public var realm: String = "Ktor Server" /** * Retrieves an HTTP authentication header. * By default, it parses the `Authorization` header content. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.jwt.JWTAuthenticationProvider.Config.authHeader) */ public fun authHeader(block: (ApplicationCall) -> HttpAuthHeader?) { authHeader = block } /** + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.jwt.JWTAuthenticationProvider.Config.authSchemes) + * * @param [defaultScheme] default scheme used to challenge the client when no valid authentication is provided * @param [additionalSchemes] additional schemes that are accepted when validating the authentication */ @@ -236,6 +281,9 @@ public class JWTAuthenticationProvider internal constructor(config: Config) : Au /** * Provides a [JWTVerifier] used to verify a token format and signature. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.jwt.JWTAuthenticationProvider.Config.verifier) + * * @param [verifier] verifies token format and signature */ public fun verifier(verifier: JWTVerifier) { @@ -244,6 +292,8 @@ public class JWTAuthenticationProvider internal constructor(config: Config) : Au /** * Provides a [JWTVerifier] used to verify a token format and signature. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.jwt.JWTAuthenticationProvider.Config.verifier) */ public fun verifier(verifier: (HttpAuthHeader) -> JWTVerifier?) { this.verifier = verifier @@ -251,6 +301,9 @@ public class JWTAuthenticationProvider internal constructor(config: Config) : Au /** * Provides a [JWTVerifier] used to verify a token format and signature. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.jwt.JWTAuthenticationProvider.Config.verifier) + * * @param [jwkProvider] provides the JSON Web Key * @param [issuer] the issuer of the JSON Web Token * @param [configure] function is applied during [JWTVerifier] construction @@ -261,6 +314,9 @@ public class JWTAuthenticationProvider internal constructor(config: Config) : Au /** * Provides a [JWTVerifier] used to verify a token format and signature. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.jwt.JWTAuthenticationProvider.Config.verifier) + * * @param [jwkProvider] provides the JSON Web Key * @param [configure] function will be applied during [JWTVerifier] construction */ @@ -271,6 +327,9 @@ public class JWTAuthenticationProvider internal constructor(config: Config) : Au /** * Provides a [JWTVerifier] used to verify a token format and signature. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.jwt.JWTAuthenticationProvider.Config.verifier) + * * @param [issuer] of the JSON Web Token * @param [audience] restriction * @param [algorithm] for validations of token signatures @@ -293,6 +352,9 @@ public class JWTAuthenticationProvider internal constructor(config: Config) : Au /** * Provides a [JWTVerifier] used to verify a token format and signature. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.jwt.JWTAuthenticationProvider.Config.verifier) + * * @param [issuer] the issuer of JSON Web Token * @param [block] configuration of [JwkProvider] */ @@ -303,6 +365,9 @@ public class JWTAuthenticationProvider internal constructor(config: Config) : Au /** * Allows you to perform additional validations on the JWT payload. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.jwt.JWTAuthenticationProvider.Config.validate) + * * @return a principal (usually an instance of [JWTPrincipal]) or `null` */ public fun validate(validate: suspend ApplicationCall.(JWTCredential) -> Any?) { @@ -311,6 +376,8 @@ public class JWTAuthenticationProvider internal constructor(config: Config) : Au /** * Specifies what to send back if JWT authentication fails. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.jwt.JWTAuthenticationProvider.Config.challenge) */ public fun challenge(block: JWTAuthChallengeFunction) { challenge = block @@ -325,6 +392,8 @@ public class JWTAuthenticationProvider internal constructor(config: Config) : Au * JWT (JSON Web Token) is an open standard that defines a way for * securely transmitting information between parties as a JSON object. * To learn how to configure it, see [JSON Web Tokens](https://ktor.io/docs/jwt.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.jwt.jwt) */ public fun AuthenticationConfig.jwt( name: String? = null, @@ -336,6 +405,8 @@ public fun AuthenticationConfig.jwt( /** * A context for [JWTAuthChallengeFunction]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.jwt.JWTChallengeContext) */ public class JWTChallengeContext( public val call: ApplicationCall @@ -343,6 +414,8 @@ public class JWTChallengeContext( /** * Specifies what to send back if JWT authentication fails. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.jwt.JWTAuthChallengeFunction) */ public typealias JWTAuthChallengeFunction = suspend JWTChallengeContext.(defaultScheme: String, realm: String) -> Unit diff --git a/ktor-server/ktor-server-plugins/ktor-server-auth-ldap/jvm/src/io/ktor/server/auth/ldap/Ldap.kt b/ktor-server/ktor-server-plugins/ktor-server-auth-ldap/jvm/src/io/ktor/server/auth/ldap/Ldap.kt index 2680082226d..f744791790b 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-auth-ldap/jvm/src/io/ktor/server/auth/ldap/Ldap.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-auth-ldap/jvm/src/io/ktor/server/auth/ldap/Ldap.kt @@ -14,6 +14,8 @@ import javax.naming.directory.* * This function accepts a credential and validates it against a specified LDAP server. * * To learn more about LDAP authentication in Ktor, see [LDAP](https://ktor.io/docs/ldap.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.ldap.ldapAuthenticate) */ public fun ldapAuthenticate( credential: K, @@ -38,6 +40,8 @@ public fun ldapAuthenticate( * This function accepts [UserPasswordCredential] and validates it against a specified LDAP server. * * To learn more about LDAP authentication in Ktor, see [LDAP](https://ktor.io/docs/ldap.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.ldap.ldapAuthenticate) */ public fun

ldapAuthenticate( credential: UserPasswordCredential, @@ -59,6 +63,8 @@ public fun

ldapAuthenticate( * This function accepts [UserPasswordCredential] and validates it against a specified LDAP server. * * To learn more about LDAP authentication in Ktor, see [LDAP](https://ktor.io/docs/ldap.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.ldap.ldapAuthenticate) */ public fun ldapAuthenticate( credential: UserPasswordCredential, diff --git a/ktor-server/ktor-server-plugins/ktor-server-auth-ldap/jvm/test/io/ktor/tests/auth/ldap/LDAPServerExtension.kt b/ktor-server/ktor-server-plugins/ktor-server-auth-ldap/jvm/test/io/ktor/tests/auth/ldap/LDAPServerExtension.kt index d7c8102dc69..0dce4c1a90a 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-auth-ldap/jvm/test/io/ktor/tests/auth/ldap/LDAPServerExtension.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-auth-ldap/jvm/test/io/ktor/tests/auth/ldap/LDAPServerExtension.kt @@ -23,6 +23,8 @@ annotation class LDAPServerExtensionTest * * This is an adaption of the LDAP functionality found in * `org.apache.directory.server.core.integ.FrameworkRunner` for JUnit5. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.tests.auth.ldap.LDAPServerExtension) */ @CreateLdapServer(transports = [CreateTransport(protocol = "LDAP")]) class LDAPServerExtension : BeforeAllCallback, AfterAllCallback, ParameterResolver { diff --git a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/Authentication.kt b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/Authentication.kt index 738edffdfb4..ea0c5d150ac 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/Authentication.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/Authentication.kt @@ -10,6 +10,8 @@ import io.ktor.utils.io.* /** * A configuration for the [Authentication] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.AuthenticationConfig) */ @KtorDsl public class AuthenticationConfig(providers: Map = emptyMap()) { @@ -17,6 +19,9 @@ public class AuthenticationConfig(providers: Map Unit) { @@ -28,6 +33,9 @@ public class AuthenticationConfig(providers: Map Unit) { val newConfiguration = config.copy() @@ -91,6 +103,8 @@ public class Authentication(internal var config: AuthenticationConfig) { /** * An installation object of the [Authentication] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.Authentication.Companion) */ public companion object : BaseApplicationPlugin { override val key: AttributeKey = AttributeKey("AuthenticationHolder") @@ -104,17 +118,23 @@ public class Authentication(internal var config: AuthenticationConfig) { /** * Retrieves an [AuthenticationContext] for `this` call. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.authentication) */ public val ApplicationCall.authentication: AuthenticationContext get() = AuthenticationContext.from(this) /** * Retrieves an authenticated principal [Any] for `this` call. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.principal) */ public inline fun ApplicationCall.principal(): P? = principal(null) /** * Retrieves an authenticated principal [Any] for `this` call from provider with name [provider] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.principal) */ public inline fun ApplicationCall.principal(provider: String?): P? = authentication.principal(provider) @@ -124,6 +144,8 @@ public inline fun ApplicationCall.principal(provider: String?) * You can modify the existing authentication configuration only in the [authentication]'s block or * using the [Authentication.configure] function. * Changing captured instance of configuration outside of [block] may have no effect or damage application's state. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.authentication) */ public fun Application.authentication(block: AuthenticationConfig.() -> Unit) { pluginOrNull(Authentication)?.configure(block) ?: install(Authentication, block) diff --git a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationContext.kt b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationContext.kt index 4f47f8edfdc..1e9b64c69da 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationContext.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationContext.kt @@ -10,6 +10,9 @@ import kotlin.reflect.* /** * An authentication context for a call. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.AuthenticationContext) + * * @param call instance of [ApplicationCall] this context is for. */ public class AuthenticationContext(call: ApplicationCall) { @@ -24,6 +27,8 @@ public class AuthenticationContext(call: ApplicationCall) { /** * Retrieves an authenticated principal, or returns `null` if a user isn't authenticated. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.AuthenticationContext.principal) */ @Deprecated("Use accessor methods instead", level = DeprecationLevel.ERROR) public var principal: Any? @@ -35,18 +40,24 @@ public class AuthenticationContext(call: ApplicationCall) { /** * All registered errors during auth procedure (only [AuthenticationFailedCause.Error]). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.AuthenticationContext.allErrors) */ public val allErrors: List get() = errors.values.filterIsInstance() /** * All authentication failures during auth procedure including missing or invalid credentials. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.AuthenticationContext.allFailures) */ public val allFailures: List get() = errors.values.toList() /** * Appends an error to the errors list. Overwrites if already registered for the same [key]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.AuthenticationContext.error) */ public fun error(key: Any, cause: AuthenticationFailedCause) { errors[key] = cause @@ -54,11 +65,15 @@ public class AuthenticationContext(call: ApplicationCall) { /** * Gets an [AuthenticationProcedureChallenge] for this context. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.AuthenticationContext.challenge) */ public val challenge: AuthenticationProcedureChallenge = AuthenticationProcedureChallenge() /** * Sets an authenticated principal for this context. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.AuthenticationContext.principal) */ public fun principal(principal: Any) { _principal.add(null, principal) @@ -66,6 +81,8 @@ public class AuthenticationContext(call: ApplicationCall) { /** * Sets an authenticated principal for this context from provider with name [provider]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.AuthenticationContext.principal) */ public fun principal(provider: String? = null, principal: Any) { _principal.add(provider, principal) @@ -73,6 +90,8 @@ public class AuthenticationContext(call: ApplicationCall) { /** * Retrieves a principal of the type [T] from provider with name [provider], if any. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.AuthenticationContext.principal) */ public inline fun principal(provider: String? = null): T? { return principal(provider, T::class) @@ -80,6 +99,8 @@ public class AuthenticationContext(call: ApplicationCall) { /** * Retrieves a principal of the type [T], if any. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.AuthenticationContext.principal) */ public fun principal(provider: String?, klass: KClass): T? { return _principal.get(provider, klass) @@ -87,6 +108,8 @@ public class AuthenticationContext(call: ApplicationCall) { /** * Requests a challenge to be sent to the client if none of mechanisms can authenticate a user. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.AuthenticationContext.challenge) */ public fun challenge( key: Any, diff --git a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationFailedCause.kt b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationFailedCause.kt index c6e8dd1ecfc..f0d9446bd20 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationFailedCause.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationFailedCause.kt @@ -6,20 +6,29 @@ package io.ktor.server.auth /** * Represents a cause for an authentication challenge request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.AuthenticationFailedCause) */ public sealed class AuthenticationFailedCause { /** * Represents a case when no credentials are provided. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.AuthenticationFailedCause.NoCredentials) */ public data object NoCredentials : AuthenticationFailedCause() /** * Represents a case when invalid credentials are provided. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.AuthenticationFailedCause.InvalidCredentials) */ public data object InvalidCredentials : AuthenticationFailedCause() /** * Represents a case when authentication mechanism failed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.AuthenticationFailedCause.Error) + * * @param message describing the cause of the authentication failure. */ public open class Error(public val message: String) : AuthenticationFailedCause() diff --git a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationInterceptors.kt b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationInterceptors.kt index 3defb6f127b..ec90cba4deb 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationInterceptors.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationInterceptors.kt @@ -31,6 +31,8 @@ internal object AuthenticationHook : Hook Unit> { * A hook that is executed after authentication was checked. * Note that this hook is also executed for optional authentication or for routes without any authentication, * resulting in [ApplicationCall.principal] being `null`. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.AuthenticationChecked) */ public object AuthenticationChecked : Hook Unit> { internal val AfterAuthenticationPhase: PipelinePhase = PipelinePhase("AfterAuthentication") @@ -47,6 +49,8 @@ public object AuthenticationChecked : Hook Unit> { /** * A plugin that authenticates calls. Usually used via the [authenticate] function inside routing. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.AuthenticationInterceptors) */ public val AuthenticationInterceptors: RouteScopedPlugin = createRouteScopedPlugin( "AuthenticationInterceptors", @@ -187,12 +191,17 @@ private fun AuthenticationConfig.findProvider(configurationName: String?): Authe * registered for this route * [AuthenticationStrategy.Required] - client must provide authentication data for all providers registered for * this route with this strategy + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.AuthenticationStrategy) */ public enum class AuthenticationStrategy { Optional, FirstSuccessful, Required } /** * Creates a route that allows you to define authorization scope for application resources. * This function accepts names of authentication providers defined in the [Authentication] plugin configuration. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.authenticate) + * * @see [Authentication] * * @param configurations names of authentication providers defined in the [Authentication] plugin configuration. @@ -216,6 +225,9 @@ public fun Route.authenticate( /** * Creates a route that allows you to define authorization scope for application resources. * This function accepts names of authentication providers defined in the [Authentication] plugin configuration. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.authenticate) + * * @see [Authentication] * * @param configurations names of authentication providers defined in the [Authentication] plugin configuration. @@ -256,6 +268,8 @@ public fun Route.authenticate( /** * A configuration for the [AuthenticationInterceptors] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.RouteAuthenticationConfig) */ @KtorDsl public class RouteAuthenticationConfig { @@ -267,6 +281,9 @@ public class RouteAuthenticationConfig { * An authentication route node that is used by [Authentication] plugin * and usually created by the [Route.authenticate] DSL function, * so generally there is no need to instantiate it directly unless you are writing an extension. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.AuthenticationRouteSelector) + * * @param names of authentication providers to be applied to this route. */ public class AuthenticationRouteSelector(public val names: List) : RouteSelector() { diff --git a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationProcedureChallenge.kt b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationProcedureChallenge.kt index 3de806c2e22..7bd4010cda9 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationProcedureChallenge.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationProcedureChallenge.kt @@ -11,6 +11,8 @@ public typealias ChallengeFunction = suspend (AuthenticationProcedureChallenge, /** * Represents an authentication challenging procedure requested by authentication mechanism. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.AuthenticationProcedureChallenge) */ public class AuthenticationProcedureChallenge { internal val register = mutableListOf>() @@ -37,6 +39,8 @@ public class AuthenticationProcedureChallenge { /** * Represents whether a challenge is successfully sent to the client and challenging should be stopped. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.AuthenticationProcedureChallenge.completed) */ public var completed: Boolean get() = _completed.value @@ -46,6 +50,8 @@ public class AuthenticationProcedureChallenge { /** * Completes a challenging procedure. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.AuthenticationProcedureChallenge.complete) */ public fun complete() { completed = true diff --git a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationProvider.kt b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationProvider.kt index af23e96f85a..a3036cfbf00 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationProvider.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationProvider.kt @@ -8,20 +8,28 @@ import io.ktor.server.application.* /** * A predicate function that accepts an application call and returns `true` or `false`. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.ApplicationCallPredicate) */ public typealias ApplicationCallPredicate = (ApplicationCall) -> Boolean /** * An authentication function that accepts and verifies credentials and returns a principal when verification is successful. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.AuthenticationFunction) */ public typealias AuthenticationFunction = suspend ApplicationCall.(credentials: C) -> Any? /** * An authentication provider with the specified name. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.AuthenticationProvider) */ public abstract class AuthenticationProvider(config: Config) { /** * A provider name or `null` for a default provider. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.AuthenticationProvider.name) */ public val name: String? = config.name @@ -29,6 +37,8 @@ public abstract class AuthenticationProvider(config: Config) { * Authenticates a request based on [AuthenticationContext]. * Implementations should either add a new [AuthenticationContext.principal] for successful authentication * or register [AuthenticationContext.challenge] for failed ones. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.AuthenticationProvider.onAuthenticate) */ public abstract suspend fun onAuthenticate(context: AuthenticationContext) @@ -36,11 +46,16 @@ public abstract class AuthenticationProvider(config: Config) { * Authentication filters specifying if authentication is required for a particular [ApplicationCall]. * * If there is no filters, authentication is required. If any filter returns `true`, authentication is not required. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.AuthenticationProvider.skipWhen) */ public val skipWhen: List = config.filterPredicates ?: emptyList() /** * Serves as the base class for authentication providers. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.AuthenticationProvider.Config) + * * @property name is the name of the provider, or `null` for a default provider. */ public open class Config protected constructor(public val name: String?) { @@ -56,6 +71,8 @@ public abstract class AuthenticationProvider(config: Config) { * Adds an authentication filter to the list. * For every application call the specified [predicate] is applied and if it returns `true` then the * authentication provider is skipped (no auth required for this call with this provider). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.AuthenticationProvider.Config.skipWhen) */ public fun skipWhen(predicate: (ApplicationCall) -> Boolean) { val list = filterPredicates ?: mutableListOf() diff --git a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/BasicAuth.kt b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/BasicAuth.kt index f913da7c62d..011864db038 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/BasicAuth.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/BasicAuth.kt @@ -14,6 +14,9 @@ import io.ktor.utils.io.charsets.* /** * A `basic` [Authentication] provider. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.BasicAuthenticationProvider) + * * @see [basic] * @property name is the name of the provider, or `null` for a default provider. */ @@ -51,6 +54,8 @@ public class BasicAuthenticationProvider internal constructor( /** * A configuration for the [basic] authentication provider. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.BasicAuthenticationProvider.Config) */ public class Config internal constructor(name: String?) : AuthenticationProvider.Config(name) { internal var authenticationFunction: AuthenticationFunction = { @@ -61,12 +66,16 @@ public class BasicAuthenticationProvider internal constructor( /** * Specifies a realm to be passed in the `WWW-Authenticate` header. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.BasicAuthenticationProvider.Config.realm) */ public var realm: String = "Ktor Server" /** * Specifies the charset to be used. It can be either `UTF_8` or `null`. * Setting `null` turns on a legacy mode (`ISO-8859-1`). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.BasicAuthenticationProvider.Config.charset) */ public var charset: Charset? = Charsets.UTF_8 set(value) { @@ -81,6 +90,8 @@ public class BasicAuthenticationProvider internal constructor( /** * Sets a validation function that checks a specified [UserPasswordCredential] instance and * returns principal [Any] in a case of successful authentication or null if authentication fails. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.BasicAuthenticationProvider.Config.validate) */ public fun validate(body: suspend ApplicationCall.(UserPasswordCredential) -> Any?) { authenticationFunction = body @@ -92,6 +103,8 @@ public class BasicAuthenticationProvider internal constructor( * Installs the basic [Authentication] provider. * You can use basic authentication for logging in users and protecting specific routes. * To learn how to configure it, see [Basic authentication](https://ktor.io/docs/basic.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.basic) */ public fun AuthenticationConfig.basic( name: String? = null, @@ -103,6 +116,8 @@ public fun AuthenticationConfig.basic( /** * Retrieves [basic] authentication credentials for this [ApplicationRequest]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.basicAuthenticationCredentials) */ public fun ApplicationRequest.basicAuthenticationCredentials(charset: Charset? = null): UserPasswordCredential? { when (val authHeader = parseAuthorizationHeader()) { diff --git a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/BearerAuth.kt b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/BearerAuth.kt index 5b94bbc258a..79bdbd35aee 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/BearerAuth.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/BearerAuth.kt @@ -11,6 +11,9 @@ import io.ktor.server.response.* /** * A Bearer [Authentication] provider. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.BearerAuthenticationProvider) + * * @see [bearer] */ public class BearerAuthenticationProvider internal constructor(config: Config) : AuthenticationProvider(config) { @@ -47,6 +50,8 @@ public class BearerAuthenticationProvider internal constructor(config: Config) : /** * A configuration for the [bearer] authentication provider. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.BearerAuthenticationProvider.Config) */ public class Config(name: String?) : AuthenticationProvider.Config(name) { internal var authenticate: AuthenticationFunction = { @@ -64,11 +69,16 @@ public class BearerAuthenticationProvider internal constructor(config: Config) : /** * Specifies an options Bearer realm to be passed in `WWW-Authenticate` header. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.BearerAuthenticationProvider.Config.realm) */ public var realm: String? = null /** * Exchanges the token for a Principal. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.BearerAuthenticationProvider.Config.authenticate) + * * @return a principal or `null` */ public fun authenticate(authenticate: suspend ApplicationCall.(BearerTokenCredential) -> Any?) { @@ -78,6 +88,8 @@ public class BearerAuthenticationProvider internal constructor(config: Config) : /** * Retrieves an HTTP authentication header. * By default, it parses the `Authorization` header content. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.BearerAuthenticationProvider.Config.authHeader) */ public fun authHeader(getAuthHeader: (ApplicationCall) -> HttpAuthHeader?) { this.getAuthHeader = getAuthHeader @@ -86,6 +98,8 @@ public class BearerAuthenticationProvider internal constructor(config: Config) : /** * Provide the auth schemes accepted when validating the authentication. * By default, it accepts the "Bearer" scheme. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.BearerAuthenticationProvider.Config.authSchemes) */ public fun authSchemes(defaultScheme: String = AuthScheme.Bearer, vararg additionalSchemes: String) { this.defaultScheme = defaultScheme @@ -100,6 +114,8 @@ public class BearerAuthenticationProvider internal constructor(config: Config) : * Installs the Bearer [Authentication] provider. * Bearer auth requires the developer to provide a custom 'authenticate' function to authorize the token, * and return the associated principal. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.bearer) */ public fun AuthenticationConfig.bearer( name: String? = null, diff --git a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/DynamicProviderConfig.kt b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/DynamicProviderConfig.kt index bb96bed8816..f2d5fd895a5 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/DynamicProviderConfig.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/DynamicProviderConfig.kt @@ -6,6 +6,8 @@ package io.ktor.server.auth /** * A configuration that creates a provider based on the [AuthenticationConfig.provider] block. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.DynamicProviderConfig) */ public class DynamicProviderConfig(name: String?) : AuthenticationProvider.Config(name) { diff --git a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/ForbiddenResponse.kt b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/ForbiddenResponse.kt index 4c4cf4b86ca..0d11a056684 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/ForbiddenResponse.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/ForbiddenResponse.kt @@ -10,6 +10,9 @@ import io.ktor.http.content.* /** * Response content with the `403 Forbidden` status code and the `WWW-Authenticate` header of supplied [challenges] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.ForbiddenResponse) + * * @param challenges to be passed in the `WWW-Authenticate` header. */ public class ForbiddenResponse(public vararg val challenges: HttpAuthHeader) : OutgoingContent.NoContent() { diff --git a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/FormAuth.kt b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/FormAuth.kt index 74ff86be9e3..f9c79223b06 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/FormAuth.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/FormAuth.kt @@ -12,6 +12,9 @@ import io.ktor.server.response.* /** * A form-based authentication provider. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.FormAuthenticationProvider) + * * @see [form] */ public class FormAuthenticationProvider internal constructor(config: Config) : AuthenticationProvider(config) { @@ -53,6 +56,8 @@ public class FormAuthenticationProvider internal constructor(config: Config) : A /** * A configuration for the [form]-based authentication provider. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.FormAuthenticationProvider.Config) */ public class Config internal constructor(name: String?) : AuthenticationProvider.Config(name) { internal var authenticationFunction: AuthenticationFunction = { null } @@ -63,16 +68,22 @@ public class FormAuthenticationProvider internal constructor(config: Config) : A /** * Specifies a POST parameter name used to fetch a username. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.FormAuthenticationProvider.Config.userParamName) */ public var userParamName: String = "user" /** * Specifies a POST parameter name used to fetch a password. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.FormAuthenticationProvider.Config.passwordParamName) */ public var passwordParamName: String = "password" /** * Specifies a response sent to the client if authentication fails. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.FormAuthenticationProvider.Config.challenge) */ public fun challenge(function: FormAuthChallengeFunction) { challengeFunction = function @@ -80,6 +91,8 @@ public class FormAuthenticationProvider internal constructor(config: Config) : A /** * Specifies a redirect URL in a case of failed authentication. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.FormAuthenticationProvider.Config.challenge) */ public fun challenge(redirectUrl: String) { challenge { @@ -89,6 +102,8 @@ public class FormAuthenticationProvider internal constructor(config: Config) : A /** * Specifies a redirect URL in a case of failed authentication. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.FormAuthenticationProvider.Config.challenge) */ public fun challenge(redirect: Url) { challenge(redirect.toString()) @@ -97,6 +112,8 @@ public class FormAuthenticationProvider internal constructor(config: Config) : A /** * Sets a validation function that checks a specified [UserPasswordCredential] instance and * returns principal [Any] in a case of successful authentication or null if authentication fails. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.FormAuthenticationProvider.Config.validate) */ public fun validate(body: suspend ApplicationCall.(UserPasswordCredential) -> Any?) { authenticationFunction = body @@ -110,6 +127,8 @@ public class FormAuthenticationProvider internal constructor(config: Config) : A * Installs the form-based [Authentication] provider. * Form-based authentication uses a web form to collect credential information and authenticate a user. * To learn how to configure it, see [Form-based authentication](https://ktor.io/docs/form.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.form) */ public fun AuthenticationConfig.form( name: String? = null, @@ -121,11 +140,15 @@ public fun AuthenticationConfig.form( /** * A context for [FormAuthChallengeFunction]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.FormAuthChallengeContext) */ public class FormAuthChallengeContext(public val call: ApplicationCall) /** * Specifies what to send back if form-based authentication fails. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.FormAuthChallengeFunction) */ public typealias FormAuthChallengeFunction = suspend FormAuthChallengeContext.(UserPasswordCredential?) -> Unit diff --git a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/Headers.kt b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/Headers.kt index 4185f9936cc..aa11f74a085 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/Headers.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/Headers.kt @@ -12,6 +12,8 @@ import io.ktor.server.request.* /** * Parses an authorization header from a [ApplicationRequest] returning a [HttpAuthHeader]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.parseAuthorizationHeader) */ public fun ApplicationRequest.parseAuthorizationHeader(): HttpAuthHeader? = headers.parseAuthorizationHeader() diff --git a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuth2.kt b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuth2.kt index 9c5abf3f59f..ca035a9e41b 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuth2.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuth2.kt @@ -270,6 +270,8 @@ private fun decodeContent(content: String, contentType: ContentType): Parameters * Implements Resource Owner Password Credentials Grant. * * Takes [UserPasswordCredential] and validates it using OAuth2 sequence, provides [OAuthAccessTokenResponse.OAuth2] if succeeds. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.verifyWithOAuth2) */ public suspend fun verifyWithOAuth2( credential: UserPasswordCredential, @@ -298,6 +300,8 @@ public suspend fun verifyWithOAuth2( /** * List of OAuth2 request parameters for both peers. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.OAuth2RequestParameters) */ public object OAuth2RequestParameters { @@ -317,6 +321,8 @@ public object OAuth2RequestParameters { /** * List of OAuth2 server response parameters. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.OAuth2ResponseParameters) */ public object OAuth2ResponseParameters { @@ -339,22 +345,31 @@ private fun throwOAuthError(errorCode: String, parameters: Parameters): Nothing /** * Represents an error during communicating to OAuth2 server. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.OAuth2Exception) + * * @property errorCode OAuth2 server replied with */ public sealed class OAuth2Exception(message: String, public val errorCode: String?) : Exception(message) { /** * Thrown when OAuth2 server responds with the "invalid_grant" error. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.OAuth2Exception.InvalidGrant) */ public class InvalidGrant(message: String) : OAuth2Exception(message, "invalid_grant") /** * Thrown when a nonce verification failed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.OAuth2Exception.InvalidNonce) */ public class InvalidNonce : OAuth2Exception("Nonce verification failed", null) /** * Thrown when an OAuth2 server responds with a successful HTTP status and expected content type that was successfully * decoded but the response doesn't contain a error code nor access token. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.OAuth2Exception.MissingAccessToken) */ public class MissingAccessToken : OAuth2Exception( "OAuth2 server response is OK neither error nor access token provided", @@ -363,6 +378,9 @@ public sealed class OAuth2Exception(message: String, public val errorCode: Strin /** * Thrown when an OAuth2 server responds with the "unsupported_grant_type" error. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.OAuth2Exception.UnsupportedGrantType) + * * @param grantType that was passed to the server */ @OptIn(ExperimentalCoroutinesApi::class) @@ -379,6 +397,9 @@ public sealed class OAuth2Exception(message: String, public val errorCode: Strin /** * Thrown when an OAuth2 server responds with [errorCode]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.OAuth2Exception.UnknownException) + * * @param errorCode the OAuth2 server replied with */ @OptIn(ExperimentalCoroutinesApi::class) diff --git a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthCommon.kt b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthCommon.kt index 4a5e22c5b4c..57d4cf1088a 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthCommon.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthCommon.kt @@ -11,6 +11,8 @@ import io.ktor.util.* /** * OAuth versions used in configuration. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.OAuthVersion) */ public enum class OAuthVersion { @@ -20,12 +22,18 @@ public enum class OAuthVersion { /** * OAuth server settings. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.OAuthServerSettings) + * * @property name configuration name * @property version OAuth version (1a or 2) */ public sealed class OAuthServerSettings(public val name: String, public val version: OAuthVersion) { /** * OAuth1a server settings + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.OAuthServerSettings.OAuth1aServerSettings) + * * @property requestTokenUrl OAuth server token request URL * @property authorizeUrl OAuth server authorization page URL * @property accessTokenUrl OAuth server access token request URL @@ -46,6 +54,9 @@ public sealed class OAuthServerSettings(public val name: String, public val vers /** * OAuth2 server settings + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.OAuthServerSettings.OAuth2ServerSettings) + * * @property authorizeUrl OAuth server authorization page URL * @property accessTokenUrl OAuth server access token request URL * @property requestMethod HTTP request method to be used to acquire access token (see vendors documentation) @@ -84,10 +95,15 @@ public sealed class OAuthServerSettings(public val name: String, public val vers /** * OAuth callback parameters. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.OAuthCallback) */ public sealed class OAuthCallback { /** * An OAuth1a token pair callback parameters. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.OAuthCallback.TokenPair) + * * @property token OAuth1a token * @property tokenSecret OAuth1a token secret */ @@ -95,6 +111,9 @@ public sealed class OAuthCallback { /** * An OAuth2 token callback parameter. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.OAuthCallback.TokenSingle) + * * @property token OAuth2 token provided by server * @property state passed from a client (ktor server) during authorization startup */ @@ -102,6 +121,9 @@ public sealed class OAuthCallback { /** * Oauth2 error callback parameters + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.OAuthCallback.Error) + * * @property error the error code passed from the identity provider * @property errorDescription optionally passed, human-readable description of the error code */ @@ -110,10 +132,15 @@ public sealed class OAuthCallback { /** * An OAuth access token acquired from the server. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.OAuthAccessTokenResponse) */ public sealed class OAuthAccessTokenResponse { /** * OAuth1a access token acquired from the server + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.OAuthAccessTokenResponse.OAuth1a) + * * @property token itself * @property tokenSecret token secret to be used with [token] * @property extraParameters contains additional parameters provided by the server @@ -126,6 +153,9 @@ public sealed class OAuthAccessTokenResponse { /** * OAuth2 access token acquired from the server + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.OAuthAccessTokenResponse.OAuth2) + * * @property accessToken access token from server * @property tokenType OAuth2 token type (usually Bearer) * @property expiresIn token expiration timestamp @@ -159,6 +189,8 @@ public sealed class OAuthAccessTokenResponse { /** * OAuth grant types constants. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.OAuthGrantTypes) */ public object OAuthGrantTypes { diff --git a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthProcedure.kt b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthProcedure.kt index 7ea93dbe364..6ebea5d2bc2 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthProcedure.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthProcedure.kt @@ -13,12 +13,17 @@ private val Logger: Logger = KtorSimpleLogger("io.ktor.auth.oauth") /** * An OAuth provider key. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.OAuthKey) */ public val OAuthKey: Any = "OAuth" /** * An `OAuth` [Authentication] provider. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.OAuthAuthenticationProvider) + * * @see [oauth] */ public class OAuthAuthenticationProvider internal constructor(config: Config) : AuthenticationProvider(config) { @@ -34,20 +39,28 @@ public class OAuthAuthenticationProvider internal constructor(config: Config) : /** * A configuration for the [oauth] authentication provider. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.OAuthAuthenticationProvider.Config) */ public class Config internal constructor(name: String?) : AuthenticationProvider.Config(name) { /** * An HTTP client instance used to make requests to the OAuth server. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.OAuthAuthenticationProvider.Config.client) */ public lateinit var client: HttpClient /** * A lookup function to find OAuth server settings for the particular call. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.OAuthAuthenticationProvider.Config.providerLookup) */ public lateinit var providerLookup: ApplicationCall.() -> OAuthServerSettings? /** * Specifies a redirect route that is opened when authorization is completed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.OAuthAuthenticationProvider.Config.urlProvider) */ public lateinit var urlProvider: ApplicationCall.(OAuthServerSettings) -> String @@ -60,6 +73,8 @@ public class OAuthAuthenticationProvider internal constructor(config: Config) : * OAuth can be used to authorize users of your application by using external providers, * such as Google, Facebook, Twitter, and so on. * To learn how to configure it, see [OAuth](https://ktor.io/docs/oauth.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.oauth) */ public fun AuthenticationConfig.oauth( name: String? = null, @@ -72,6 +87,8 @@ public fun AuthenticationConfig.oauth( /** * Error container for when the upstream identity provider does not respond with the token credentials, and instead * responds with error query parameters. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.OAuth2RedirectError) */ public class OAuth2RedirectError(public val error: String, public val errorDescription: String?) : AuthenticationFailedCause.Error(if (errorDescription == null) error else "$error: $errorDescription") diff --git a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/Principal.kt b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/Principal.kt index 240a5be8963..7f68cdc9013 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/Principal.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/Principal.kt @@ -8,12 +8,16 @@ import kotlin.reflect.* /** * A marker interface indicating that a class represents credentials for authentication. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.Credential) */ @Deprecated("This interface can be safely removed") public interface Credential /** * A marker interface indicating that a class represents an authenticated principal. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.Principal) */ @Deprecated("This interface can be safely removed") public interface Principal diff --git a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/SessionAuth.kt b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/SessionAuth.kt index 8ad18b78764..d124a00a1e5 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/SessionAuth.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/SessionAuth.kt @@ -12,6 +12,9 @@ import kotlin.reflect.* /** * A session-based [Authentication] provider. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.SessionAuthenticationProvider) + * * @see [session] * * @property type of session @@ -54,6 +57,8 @@ public class SessionAuthenticationProvider private constructor( /** * A configuration for the [session] authentication provider. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.SessionAuthenticationProvider.Config) */ public class Config @PublishedApi internal constructor( name: String?, @@ -65,6 +70,8 @@ public class SessionAuthenticationProvider private constructor( /** * Specifies a response to send back if authentication failed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.SessionAuthenticationProvider.Config.challenge) */ public fun challenge(block: SessionAuthChallengeFunction) { challengeFunction = block @@ -72,6 +79,8 @@ public class SessionAuthenticationProvider private constructor( /** * Specifies a response to send back if authentication failed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.SessionAuthenticationProvider.Config.challenge) */ public fun challenge(redirectUrl: String) { challenge { @@ -81,6 +90,8 @@ public class SessionAuthenticationProvider private constructor( /** * Specifies a response to send back if authentication failed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.SessionAuthenticationProvider.Config.challenge) */ public fun challenge(redirect: Url) { challenge(redirect.toString()) @@ -89,6 +100,8 @@ public class SessionAuthenticationProvider private constructor( /** * Sets a validation function that checks a given [T] session instance and returns principal [Any], * or null if the session does not correspond to an authenticated principal. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.SessionAuthenticationProvider.Config.validate) */ public fun validate(block: suspend ApplicationCall.(T) -> Any?) { check(validator === UninitializedValidator) { "Only one validator could be registered" } @@ -120,6 +133,8 @@ public class SessionAuthenticationProvider private constructor( * This provider provides the ability to authenticate a user that already has an associated session. * * To learn how to configure the session provider, see [Session authentication](https://ktor.io/docs/session-auth.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.session) */ public inline fun AuthenticationConfig.session( name: String? = null @@ -132,6 +147,8 @@ public inline fun AuthenticationConfig.session( * This provider provides the ability to authenticate a user that already has an associated session. * * To learn how to configure the session provider, see [Session authentication](https://ktor.io/docs/session-auth.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.session) */ public fun AuthenticationConfig.session( name: String? = null, @@ -147,6 +164,8 @@ public fun AuthenticationConfig.session( * This provider provides the ability to authenticate a user that already has an associated session. * * To learn how to configure the session provider, see [Session authentication](https://ktor.io/docs/session-auth.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.session) */ public inline fun AuthenticationConfig.session( name: String? = null, @@ -160,6 +179,8 @@ public inline fun AuthenticationConfig.session( * This provider provides the ability to authenticate a user that already has an associated session. * * To learn how to configure the session provider, see [Session authentication](https://ktor.io/docs/session-auth.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.session) */ public fun AuthenticationConfig.session( name: String?, @@ -172,6 +193,8 @@ public fun AuthenticationConfig.session( /** * A context for [SessionAuthChallengeFunction]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.SessionChallengeContext) */ public class SessionChallengeContext( public val call: ApplicationCall @@ -179,10 +202,14 @@ public class SessionChallengeContext( /** * Specifies what to send back if session authentication fails. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.SessionAuthChallengeFunction) */ public typealias SessionAuthChallengeFunction = suspend SessionChallengeContext.(T?) -> Unit /** * A key used to register authentication challenge. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.SessionAuthChallengeKey) */ public const val SessionAuthChallengeKey: String = "SessionAuth" diff --git a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/SimpleAuth.kt b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/SimpleAuth.kt index e3846c4abe9..40ee5aea0f6 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/SimpleAuth.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/SimpleAuth.kt @@ -7,6 +7,9 @@ package io.ktor.server.auth /** * A user's principal identified by [name]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.UserIdPrincipal) + * * @see [Authentication] * @property name of user */ @@ -15,6 +18,9 @@ public data class UserIdPrincipal(val name: String) /** * A user's credentials identified by [name] and [password]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.UserPasswordCredential) + * * @see [Authentication] * @property name * @property password @@ -27,6 +33,9 @@ public data class BearerTokenCredential(val token: String) * An in-memory table that keeps usernames and password hashes. * This allows you not to compromise user passwords if your data source is leaked. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.UserHashedTableAuth) + * * @see [basic] * @see [form] * @property digester a hash function to compute password digest @@ -41,6 +50,8 @@ public class UserHashedTableAuth(public val digester: (String) -> ByteArray, pub /** * Authenticates a user by [credential] and returns a [UserIdPrincipal] instance if the [credential] pair is valid. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.UserHashedTableAuth.authenticate) */ public fun authenticate(credential: UserPasswordCredential): UserIdPrincipal? { val userPasswordHash = table[credential.name] diff --git a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/UnauthorizedResponse.kt b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/UnauthorizedResponse.kt index a1cfa165c9e..41ac6cb2543 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/UnauthorizedResponse.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/UnauthorizedResponse.kt @@ -10,6 +10,9 @@ import io.ktor.http.content.* /** * Response content with the `401 Unauthorized` status code and the `WWW-Authenticate` header of supplied [challenges]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.UnauthorizedResponse) + * * @param challenges to be passed with the `WWW-Authenticate` header. */ public class UnauthorizedResponse(public vararg val challenges: HttpAuthHeader) : OutgoingContent.NoContent() { diff --git a/ktor-server/ktor-server-plugins/ktor-server-auth/jvm/src/io/ktor/server/auth/DigestAuth.kt b/ktor-server/ktor-server-plugins/ktor-server-auth/jvm/src/io/ktor/server/auth/DigestAuth.kt index 9d65827c196..f327bbca5fd 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-auth/jvm/src/io/ktor/server/auth/DigestAuth.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-auth/jvm/src/io/ktor/server/auth/DigestAuth.kt @@ -13,6 +13,9 @@ import java.security.* /** * A `digest` [Authentication] provider. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.DigestAuthenticationProvider) + * * @property realm specifies the value to be passed in the `WWW-Authenticate` header. * @property algorithmName a message digest algorithm to be used. Usually only `MD5` is supported by clients. */ @@ -87,6 +90,8 @@ public class DigestAuthenticationProvider internal constructor( /** * A configuration for the [digest] authentication provider. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.DigestAuthenticationProvider.Config) */ public class Config internal constructor(name: String?) : AuthenticationProvider.Config(name) { internal var digestProvider: DigestProviderFunction = { userName, realm -> @@ -101,22 +106,30 @@ public class DigestAuthenticationProvider internal constructor( /** * Specifies a realm to be passed in the `WWW-Authenticate` header. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.DigestAuthenticationProvider.Config.realm) */ public var realm: String = "Ktor Server" /** * A message digest algorithm to be used. Usually only `MD5` is supported by clients. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.DigestAuthenticationProvider.Config.algorithmName) */ public var algorithmName: String = "MD5" /** * [NonceManager] to be used to generate nonce values. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.DigestAuthenticationProvider.Config.nonceManager) */ public var nonceManager: NonceManager = GenerateOnlyNonceManager /** * Sets a validation function that checks a specified [DigestCredential] instance and * returns principal [Any] in a case of successful authentication or null if authentication fails. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.DigestAuthenticationProvider.Config.validate) */ public fun validate(body: AuthenticationFunction) { authenticationFunction = body @@ -126,6 +139,8 @@ public class DigestAuthenticationProvider internal constructor( * Configures a digest provider function that should fetch or compute message digest for the specified * `userName` and `realm`. A message digest is usually computed based on username, realm and password * concatenated with the colon character ':'. For example, `"$userName:$realm:$password"`. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.DigestAuthenticationProvider.Config.digestProvider) */ public fun digestProvider(digest: DigestProviderFunction) { digestProvider = digest @@ -136,12 +151,16 @@ public class DigestAuthenticationProvider internal constructor( /** * Provides a message digest for the specified username and realm or returns `null` if a user is missing. * This function could fetch digest from a database or compute it instead. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.DigestProviderFunction) */ public typealias DigestProviderFunction = suspend (userName: String, realm: String) -> ByteArray? /** * Installs the digest [Authentication] provider. * To learn how to configure it, see [Digest authentication](https://ktor.io/docs/digest.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.digest) */ public fun AuthenticationConfig.digest( name: String? = null, @@ -153,6 +172,9 @@ public fun AuthenticationConfig.digest( /** * Digest credentials. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.DigestCredential) + * * @see [digest] * * @property realm a digest authentication realm @@ -181,6 +203,8 @@ public data class DigestCredential( /** * Retrieves [DigestCredential] for this call. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.digestAuthenticationCredentials) */ public fun ApplicationCall.digestAuthenticationCredentials(): DigestCredential? { return request.parseAuthorizationHeader()?.let { authHeader -> @@ -196,6 +220,8 @@ private val digestAuthenticationChallengeKey: Any = "DigestAuth" /** * Converts [HttpAuthHeader] to [DigestCredential]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.toDigestCredential) */ public fun HttpAuthHeader.Parameterized.toDigestCredential(): DigestCredential = DigestCredential( parameter("realm")!!, @@ -212,6 +238,8 @@ public fun HttpAuthHeader.Parameterized.toDigestCredential(): DigestCredential = /** * Verifies that credentials are valid for a given [method], [digester], and [userNameRealmPasswordDigest]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.verifier) */ public suspend fun DigestCredential.verifier( method: HttpMethod, @@ -233,6 +261,8 @@ public suspend fun DigestCredential.verifier( /** * Calculates the expected digest bytes for this [DigestCredential]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.expectedDigest) */ public fun DigestCredential.expectedDigest( method: HttpMethod, diff --git a/ktor-server/ktor-server-plugins/ktor-server-auth/jvm/src/io/ktor/server/auth/OAuth1a.kt b/ktor-server/ktor-server-plugins/ktor-server-auth/jvm/src/io/ktor/server/auth/OAuth1a.kt index 56a04b4689d..b0cb9f86aeb 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-auth/jvm/src/io/ktor/server/auth/OAuth1a.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-auth/jvm/src/io/ktor/server/auth/OAuth1a.kt @@ -248,11 +248,15 @@ private fun parametersString(parameters: List): String = /** * An OAuth1a server error. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.OAuth1aException) */ public sealed class OAuth1aException(message: String) : Exception(message) { /** * Thrown when an OAuth1a server didn't provide access token. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.OAuth1aException.MissingTokenException) */ public class MissingTokenException : OAuth1aException("The OAuth1a server didn't provide access token") } diff --git a/ktor-server/ktor-server-plugins/ktor-server-auto-head-response/common/src/io/ktor/server/plugins/autohead/AutoHeadResponse.kt b/ktor-server/ktor-server-plugins/ktor-server-auto-head-response/common/src/io/ktor/server/plugins/autohead/AutoHeadResponse.kt index f9e92964d83..d25fb70e710 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-auto-head-response/common/src/io/ktor/server/plugins/autohead/AutoHeadResponse.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-auto-head-response/common/src/io/ktor/server/plugins/autohead/AutoHeadResponse.kt @@ -16,6 +16,8 @@ import io.ktor.util.* * You can use `AutoHeadResponse` to avoid creating a separate `head` handler if you need to somehow process a response * on the client before getting the actual content. * You can learn more from [AutoHeadResponse](https://ktor.io/docs/autoheadresponse.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.autohead.AutoHeadResponse) */ public val AutoHeadResponse: ApplicationPlugin = createApplicationPlugin("AutoHeadResponse") { onCall { call -> diff --git a/ktor-server/ktor-server-plugins/ktor-server-body-limit/common/src/io/ktor/server/plugins/bodylimit/RequestBodyLimit.kt b/ktor-server/ktor-server-plugins/ktor-server-body-limit/common/src/io/ktor/server/plugins/bodylimit/RequestBodyLimit.kt index b447b852314..a123f597561 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-body-limit/common/src/io/ktor/server/plugins/bodylimit/RequestBodyLimit.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-body-limit/common/src/io/ktor/server/plugins/bodylimit/RequestBodyLimit.kt @@ -13,6 +13,8 @@ import kotlinx.coroutines.* /** * A configuration for [RequestBodyLimit] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.bodylimit.RequestBodyLimitConfig) */ public class RequestBodyLimitConfig { internal var bodyLimit: (ApplicationCall) -> Long = { Long.MAX_VALUE } @@ -20,6 +22,8 @@ public class RequestBodyLimitConfig { /** * Sets a limit for the maximum allowed size for incoming request bodies. * The block should return [Long.MAX_VALUE] if the body size is unlimited. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.bodylimit.RequestBodyLimitConfig.bodyLimit) */ public fun bodyLimit(block: (ApplicationCall) -> Long) { bodyLimit = block @@ -28,6 +32,8 @@ public class RequestBodyLimitConfig { /** * A plugin that limits the maximum allowed size for incoming request bodies. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.bodylimit.RequestBodyLimit) */ public val RequestBodyLimit: RouteScopedPlugin = createRouteScopedPlugin( "RequestBodyLimit", diff --git a/ktor-server/ktor-server-plugins/ktor-server-caching-headers/common/src/io/ktor/server/plugins/cachingheaders/CachingHeaders.kt b/ktor-server/ktor-server-plugins/ktor-server-caching-headers/common/src/io/ktor/server/plugins/cachingheaders/CachingHeaders.kt index d12f3adb799..cc77f0b4264 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-caching-headers/common/src/io/ktor/server/plugins/cachingheaders/CachingHeaders.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-caching-headers/common/src/io/ktor/server/plugins/cachingheaders/CachingHeaders.kt @@ -12,6 +12,8 @@ import io.ktor.utils.io.* /** * A configuration for the [CachingHeaders] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.cachingheaders.CachingHeadersConfig) */ @KtorDsl public class CachingHeadersConfig { @@ -25,6 +27,9 @@ public class CachingHeadersConfig { /** * Provides caching options for a given [ApplicationCall] and [OutgoingContent]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.cachingheaders.CachingHeadersConfig.options) + * * @see [CachingHeaders] */ public fun options(provider: (ApplicationCall, OutgoingContent) -> CachingOptions?) { @@ -48,6 +53,8 @@ public class CachingHeadersConfig { * ``` * * You can learn more from [Caching headers](https://ktor.io/docs/caching.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.cachingheaders.CachingHeaders) */ public val CachingHeaders: RouteScopedPlugin = createRouteScopedPlugin( "Caching Headers", @@ -83,6 +90,8 @@ public val CachingHeaders: RouteScopedPlugin = createRoute /** * Gets or sets the [CacheControl] for this call. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.cachingheaders.caching) */ public var ApplicationCall.caching: CachingOptions? get() = attributes.getOrNull(CachingProperty) diff --git a/ktor-server/ktor-server-plugins/ktor-server-call-id/common/src/io/ktor/server/plugins/callid/CallId.kt b/ktor-server/ktor-server-plugins/ktor-server-call-id/common/src/io/ktor/server/plugins/callid/CallId.kt index d10c8743409..2d9085fc454 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-call-id/common/src/io/ktor/server/plugins/callid/CallId.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-call-id/common/src/io/ktor/server/plugins/callid/CallId.kt @@ -22,6 +22,8 @@ internal val LOGGER = KtorSimpleLogger("io.ktor.server.plugins.callid.CallId") /** * A function that retrieves or generates call id using provided call + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.callid.CallIdProvider) */ public typealias CallIdProvider = (call: ApplicationCall) -> String? @@ -29,11 +31,16 @@ public typealias CallIdProvider = (call: ApplicationCall) -> String? * A function that verifies retrieved or generated call id. Should return `true` for a valid call id. * Also it could throw a [RejectedCallIdException] to reject an [ApplicationCall] otherwise an illegal call id * will be ignored or replaced with generated one. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.callid.CallIdVerifier) */ public typealias CallIdVerifier = (String) -> Boolean /** * An exception that could be thrown to reject a call due to illegal call id + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.callid.RejectedCallIdException) + * * @param illegalCallId that caused rejection */ @OptIn(ExperimentalCoroutinesApi::class) @@ -47,6 +54,8 @@ public class RejectedCallIdException( /** * A configuration for the [CallId] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.callid.CallIdConfig) */ @KtorDsl public class CallIdConfig { @@ -64,6 +73,9 @@ public class CallIdConfig { * Allows you to retrieve a call ID from [ApplicationCall]. * Returns `null` if no call ID is found in a request. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.callid.CallIdConfig.retrieve) + * * @see verify */ public fun retrieve(block: CallIdProvider) { @@ -74,6 +86,9 @@ public class CallIdConfig { * Allows you to generate a call ID if an incoming request doesn't include it. * Generates `null` if it is impossible to generate a call ID for some reason. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.callid.CallIdConfig.generate) + * * @see verify */ public fun generate(block: CallIdProvider) { @@ -95,6 +110,9 @@ public class CallIdConfig { * CALL_ID_DEFAULT_DICTIONARY: String = "abcdefghijklmnopqrstuvwxyz0123456789+/=-" * ``` * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.callid.CallIdConfig.verify) + * * @see [CallIdVerifier] */ public fun verify(predicate: CallIdVerifier) { @@ -110,6 +128,8 @@ public class CallIdConfig { * ```kotlin * CALL_ID_DEFAULT_DICTIONARY: String = "abcdefghijklmnopqrstuvwxyz0123456789+/=-" * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.callid.CallIdConfig.verify) */ public fun verify(dictionary: String, reject: Boolean = false) { val dictionarySet = dictionary.toSet() @@ -126,6 +146,9 @@ public class CallIdConfig { /** * Allows you to reply with a retrieved or generated call ID by modifying an [ApplicationCall]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.callid.CallIdConfig.reply) + * * @see [replyToHeader] */ public fun reply(block: (call: ApplicationCall, CallId: String) -> Unit) { @@ -135,6 +158,9 @@ public class CallIdConfig { /** * Allows you to retrieve a call ID and send it in the same header. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.callid.CallIdConfig.header) + * * @see [retrieveFromHeader] * @see [replyToHeader] */ @@ -146,6 +172,9 @@ public class CallIdConfig { /** * Retrieves a call ID from a specified request header named [headerName]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.callid.CallIdConfig.retrieveFromHeader) + * * @see [replyToHeader] */ public fun retrieveFromHeader(headerName: String) { @@ -155,6 +184,9 @@ public class CallIdConfig { /** * Replies with a call ID using a specified header named [headerName]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.callid.CallIdConfig.replyToHeader) + * * @see [retrieveFromHeader] */ public fun replyToHeader(headerName: String) { @@ -191,6 +223,8 @@ internal object CallIdSetup : Hook.( * 4. Finally, you can send a call ID to the client in a specific header, for example, `X-Request-Id`. * * You can learn more from [CallId](https://ktor.io/docs/call-id.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.callid.CallId) */ public val CallId: RouteScopedPlugin = createRouteScopedPlugin( "CallId", @@ -232,6 +266,8 @@ public val CallId: RouteScopedPlugin = createRouteScopedPlugin( /** * Gets a call ID retrieved or generated by the [CallId] plugin. * Returns `null` if there is no call ID is provided and no generators are configured. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.callid.callId) */ public val ApplicationCall.callId: String? get() = attributes.getOrNull(CallIdKey) @@ -252,6 +288,9 @@ private fun verifyCallIdAgainstDictionary(callId: String, dictionarySet: Set("CallStartTime") /** * Returns time in millis from the moment the call was received until now + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.calllogging.processingTimeMillis) */ public fun ApplicationCall.processingTimeMillis(clock: () -> Long = { getTimeMillis() }): Long { val startTime = attributes[CALL_START_TIME] @@ -28,6 +30,8 @@ public fun ApplicationCall.processingTimeMillis(clock: () -> Long = { getTimeMil * filter requests based on a specified condition, customize log messages, and so on. * * You can learn more from [Call logging](https://ktor.io/docs/call-logging.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.calllogging.CallLogging) */ public val CallLogging: ApplicationPlugin = createApplicationPlugin( "CallLogging", diff --git a/ktor-server/ktor-server-plugins/ktor-server-call-logging/jvm/src/io/ktor/server/plugins/calllogging/CallLoggingConfig.kt b/ktor-server/ktor-server-plugins/ktor-server-call-logging/jvm/src/io/ktor/server/plugins/calllogging/CallLoggingConfig.kt index 354858456b8..763c88bb39e 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-call-logging/jvm/src/io/ktor/server/plugins/calllogging/CallLoggingConfig.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-call-logging/jvm/src/io/ktor/server/plugins/calllogging/CallLoggingConfig.kt @@ -15,6 +15,8 @@ import org.slf4j.event.* /** * A configuration for the [CallLogging] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.calllogging.CallLoggingConfig) */ @KtorDsl public class CallLoggingConfig { @@ -28,12 +30,16 @@ public class CallLoggingConfig { /** * Specifies a logging level for the [CallLogging] plugin. * The default level is [Level.INFO]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.calllogging.CallLoggingConfig.level) */ public var level: Level = Level.INFO /** * Specifies a [Logger] used to log requests. * By default, uses [ApplicationEnvironment.log]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.calllogging.CallLoggingConfig.logger) */ public var logger: Logger? = null @@ -46,6 +52,9 @@ public class CallLoggingConfig { * } * ``` * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.calllogging.CallLoggingConfig.filter) + * * @see [CallLogging] */ public fun filter(predicate: (ApplicationCall) -> Boolean) { @@ -56,6 +65,9 @@ public class CallLoggingConfig { * Puts a diagnostic context value to [MDC] with the specified [name] and computed using the [provider] function. * A value is available in MDC only during [ApplicationCall] lifetime and is removed after a call processing. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.calllogging.CallLoggingConfig.mdc) + * * @see [CallLogging] */ public fun mdc(name: String, provider: (ApplicationCall) -> String?) { @@ -65,6 +77,9 @@ public class CallLoggingConfig { /** * Allows you to configure a call log message. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.calllogging.CallLoggingConfig.format) + * * @see [CallLogging] */ public fun format(formatter: (ApplicationCall) -> String) { @@ -74,6 +89,9 @@ public class CallLoggingConfig { /** * Allows you to configure a clock that will be used to measure call processing time. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.calllogging.CallLoggingConfig.clock) + * * @see [CallLogging] */ public fun clock(clock: () -> Long) { @@ -82,6 +100,8 @@ public class CallLoggingConfig { /** * Disables colors in a log message when a default formatter is used. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.calllogging.CallLoggingConfig.disableDefaultColors) * */ public fun disableDefaultColors() { isColorsEnabled = false @@ -89,6 +109,8 @@ public class CallLoggingConfig { /** * Disables logging for static content files. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.calllogging.CallLoggingConfig.disableForStaticContent) * */ public fun disableForStaticContent() { ignoreStaticContent = true diff --git a/ktor-server/ktor-server-plugins/ktor-server-compression/jvm/src/io/ktor/server/plugins/compression/Compression.kt b/ktor-server/ktor-server-plugins/ktor-server-compression/jvm/src/io/ktor/server/plugins/compression/Compression.kt index a20db3782ab..977021ab2d0 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-compression/jvm/src/io/ktor/server/plugins/compression/Compression.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-compression/jvm/src/io/ktor/server/plugins/compression/Compression.kt @@ -16,6 +16,8 @@ import io.ktor.utils.io.* /** * List of [ContentEncoder] names that were used to decode request body. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.compression.appliedDecoders) */ public val ApplicationRequest.appliedDecoders: List get() = call.attributes.getOrNull(DecompressionListAttribute) ?: emptyList() @@ -51,6 +53,8 @@ internal const val DEFAULT_MINIMAL_COMPRESSION_SIZE: Long = 200L * ``` * * You can learn more from [Compression](https://ktor.io/docs/compression.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.compression.Compression) */ public val Compression: RouteScopedPlugin = createRouteScopedPlugin( "Compression", diff --git a/ktor-server/ktor-server-plugins/ktor-server-compression/jvm/src/io/ktor/server/plugins/compression/Config.kt b/ktor-server/ktor-server-plugins/ktor-server-compression/jvm/src/io/ktor/server/plugins/compression/Config.kt index 9a52c269aa6..d9b18f6b9fc 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-compression/jvm/src/io/ktor/server/plugins/compression/Config.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-compression/jvm/src/io/ktor/server/plugins/compression/Config.kt @@ -12,6 +12,8 @@ import io.ktor.utils.io.* /** * A configuration for the [Compression] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.compression.CompressionOptions) */ public data class CompressionOptions( /** @@ -26,6 +28,8 @@ public data class CompressionOptions( /** * An encoder configuration for the [Compression] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.compression.CompressionEncoderConfig) */ public data class CompressionEncoderConfig( /** @@ -44,6 +48,8 @@ public data class CompressionEncoderConfig( /** * A configuration for the [Compression] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.compression.CompressionConfig) */ @KtorDsl public class CompressionConfig : ConditionsHolderBuilder { @@ -56,11 +62,15 @@ public class CompressionConfig : ConditionsHolderBuilder { /** * Specifies if the plugin should compress response, decompress request, or both. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.compression.CompressionConfig.mode) */ public var mode: Mode = Mode.All /** * Provides access to a map of encoders. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.compression.CompressionConfig.encoders) */ public val encoders: MutableMap = hashMapOf() @@ -68,6 +78,8 @@ public class CompressionConfig : ConditionsHolderBuilder { /** * Appends an [encoder] with the [block] configuration. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.compression.CompressionConfig.encoder) */ public fun encoder( encoder: ContentEncoder, @@ -82,6 +94,8 @@ public class CompressionConfig : ConditionsHolderBuilder { /** * Appends the default configuration with the `gzip`, `deflate`, and `identity` encoders. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.compression.CompressionConfig.default) */ public fun default() { gzip() @@ -106,16 +120,23 @@ public class CompressionConfig : ConditionsHolderBuilder { /** * A builder for conditions. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.compression.ConditionsHolderBuilder) */ public interface ConditionsHolderBuilder { /** * Preconditions applied to every response object to check if it should be compressed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.compression.ConditionsHolderBuilder.conditions) */ public val conditions: MutableList Boolean> } /** * A builder for compression encoder configuration. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.compression.CompressionEncoderBuilder) + * * @property name of encoder * @property encoder instance */ @@ -125,11 +146,15 @@ public class CompressionEncoderBuilder internal constructor( ) : ConditionsHolderBuilder { /** * A list of conditions for this encoder + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.compression.CompressionEncoderBuilder.conditions) */ override val conditions: ArrayList Boolean> = arrayListOf() /** * A priority for this encoder. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.compression.CompressionEncoderBuilder.priority) */ public var priority: Double = 1.0 @@ -140,6 +165,8 @@ public class CompressionEncoderBuilder internal constructor( /** * Appends the `gzip` encoder with the [block] configuration. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.compression.gzip) */ public fun CompressionConfig.gzip(block: CompressionEncoderBuilder.() -> Unit = {}) { encoder(GZipEncoder, block) @@ -147,6 +174,8 @@ public fun CompressionConfig.gzip(block: CompressionEncoderBuilder.() -> Unit = /** * Appends the `deflate` encoder with the [block] configuration and the 0.9 priority. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.compression.deflate) */ public fun CompressionConfig.deflate(block: CompressionEncoderBuilder.() -> Unit = {}) { encoder(DeflateEncoder) { @@ -157,6 +186,8 @@ public fun CompressionConfig.deflate(block: CompressionEncoderBuilder.() -> Unit /** * Appends the `identity` encoder with the [block] configuration. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.compression.identity) */ public fun CompressionConfig.identity(block: CompressionEncoderBuilder.() -> Unit = {}) { encoder(IdentityEncoder, block) @@ -168,6 +199,8 @@ public fun CompressionConfig.identity(block: CompressionEncoderBuilder.() -> Uni * If at least one condition is not met, a response isn't compressed. * * Note that adding a single condition removes the default configuration. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.compression.condition) */ public fun ConditionsHolderBuilder.condition(predicate: ApplicationCall.(OutgoingContent) -> Boolean) { conditions.add(predicate) @@ -177,6 +210,8 @@ public fun ConditionsHolderBuilder.condition(predicate: ApplicationCall.(Outgoin * Appends a minimum size condition to the encoder or the [Compression] configuration. * * Note that adding a single minimum size condition removes the default configuration. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.compression.minimumSize) */ public fun ConditionsHolderBuilder.minimumSize(minSize: Long) { condition { content -> content.contentLength?.let { it >= minSize } ?: true } @@ -186,6 +221,8 @@ public fun ConditionsHolderBuilder.minimumSize(minSize: Long) { * Appends a content type condition to the encoder or the [Compression] configuration. * * Note that adding a single condition removes the default configuration. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.compression.matchContentType) */ public fun ConditionsHolderBuilder.matchContentType(vararg mimeTypes: ContentType) { condition { content -> @@ -198,6 +235,8 @@ public fun ConditionsHolderBuilder.matchContentType(vararg mimeTypes: ContentTyp * Appends a content type exclusion condition to the encoder or the [Compression] configuration. * * Note that adding a single match condition removes the default configuration. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.compression.excludeContentType) */ public fun ConditionsHolderBuilder.excludeContentType(vararg mimeTypes: ContentType) { condition { content -> diff --git a/ktor-server/ktor-server-plugins/ktor-server-conditional-headers/common/src/io/ktor/server/plugins/conditionalheaders/ConditionalHeaders.kt b/ktor-server/ktor-server-plugins/ktor-server-conditional-headers/common/src/io/ktor/server/plugins/conditionalheaders/ConditionalHeaders.kt index 8b9b88fdb9c..b46e520a32c 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-conditional-headers/common/src/io/ktor/server/plugins/conditionalheaders/ConditionalHeaders.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-conditional-headers/common/src/io/ktor/server/plugins/conditionalheaders/ConditionalHeaders.kt @@ -15,6 +15,8 @@ import io.ktor.utils.io.* /** * A configuration for the [ConditionalHeaders] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.conditionalheaders.ConditionalHeadersConfig) */ @KtorDsl public class ConditionalHeadersConfig { @@ -31,6 +33,9 @@ public class ConditionalHeadersConfig { /** * Registers a function that can fetch a version list for a given [ApplicationCall] and [OutgoingContent]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.conditionalheaders.ConditionalHeadersConfig.version) + * * @see [ConditionalHeaders] */ public fun version(provider: suspend (ApplicationCall, OutgoingContent) -> List) { @@ -43,6 +48,8 @@ internal val VersionProvidersKey: AttributeKey { val versionProviders = application.attributes.getOrNull(VersionProvidersKey) @@ -72,6 +79,8 @@ public suspend fun ApplicationCall.versionsFor(content: OutgoingContent): List = createRouteScopedPlugin( "ConditionalHeaders", @@ -116,6 +125,8 @@ public val ConditionalHeaders: RouteScopedPlugin = cre /** * Retrieves the `LastModified` and `ETag` versions from headers. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.conditionalheaders.parseVersions) */ public fun Headers.parseVersions(): List { val lastModifiedHeaders = getAll(HttpHeaders.LastModified) ?: emptyList() diff --git a/ktor-server/ktor-server-plugins/ktor-server-content-negotiation/common/src/io/ktor/server/plugins/contentnegotiation/ContentNegotiation.kt b/ktor-server/ktor-server-plugins/ktor-server-content-negotiation/common/src/io/ktor/server/plugins/contentnegotiation/ContentNegotiation.kt index 0ce0729692f..1626eb63037 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-content-negotiation/common/src/io/ktor/server/plugins/contentnegotiation/ContentNegotiation.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-content-negotiation/common/src/io/ktor/server/plugins/contentnegotiation/ContentNegotiation.kt @@ -21,6 +21,9 @@ internal val LOGGER = KtorSimpleLogger("io.ktor.server.plugins.contentnegotiatio /** * A functional type for accepted content types contributor. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.contentnegotiation.AcceptHeaderContributor) + * * @see ContentNegotiation.Configuration.accept */ public typealias AcceptHeaderContributor = ( @@ -30,6 +33,9 @@ public typealias AcceptHeaderContributor = ( /** * A pair of [ContentType] and [quality] usually parsed from the [HttpHeaders.Accept] headers. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.contentnegotiation.ContentTypeWithQuality) + * * @param contentType * @param quality */ @@ -46,6 +52,8 @@ public data class ContentTypeWithQuality(val contentType: ContentType, val quali * Ktor supports the following formats out-of-the-box: `JSON`, `XML`, `CBOR` and `ProtoBuf`. * * You can learn more from [Content negotiation and serialization](https://ktor.io/docs/serialization.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.contentnegotiation.ContentNegotiation) */ public val ContentNegotiation: RouteScopedPlugin = createRouteScopedPlugin( "ContentNegotiation", @@ -57,6 +65,8 @@ public val ContentNegotiation: RouteScopedPlugin = cre /** * Detects a suitable charset for an application call by using the `Accept` header or fallbacks to [defaultCharset]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.contentnegotiation.suitableCharset) */ public fun ApplicationCall.suitableCharset(defaultCharset: Charset = Charsets.UTF_8): Charset { for ((charset, _) in request.acceptCharsetItems()) { diff --git a/ktor-server/ktor-server-plugins/ktor-server-content-negotiation/common/src/io/ktor/server/plugins/contentnegotiation/ContentNegotiationConfig.kt b/ktor-server/ktor-server-plugins/ktor-server-content-negotiation/common/src/io/ktor/server/plugins/contentnegotiation/ContentNegotiationConfig.kt index 09781a4b2bf..692c718bb8a 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-content-negotiation/common/src/io/ktor/server/plugins/contentnegotiation/ContentNegotiationConfig.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-content-negotiation/common/src/io/ktor/server/plugins/contentnegotiation/ContentNegotiationConfig.kt @@ -22,6 +22,8 @@ internal expect val DefaultIgnoredTypes: Set> /** * A configuration for the [ContentNegotiation] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.contentnegotiation.ContentNegotiationConfig) */ @KtorDsl public class ContentNegotiationConfig : Configuration { @@ -32,11 +34,15 @@ public class ContentNegotiationConfig : Configuration { /** * Checks that the `ContentType` header value of a response suits the `Accept` header value of a request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.contentnegotiation.ContentNegotiationConfig.checkAcceptHeaderCompliance) */ public var checkAcceptHeaderCompliance: Boolean = false /** * Registers a [contentType] to a specified [converter] with an optional converter [configuration]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.contentnegotiation.ContentNegotiationConfig.register) */ public override fun register( contentType: ContentType, @@ -58,6 +64,8 @@ public class ContentNegotiationConfig : Configuration { * content types list with the specified one from the uri argument. * Note that the returned list of accepted types will be sorted according to the quality using [sortedByQuality], * so a custom [contributor] may keep it unsorted and should not rely on input list order. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.contentnegotiation.ContentNegotiationConfig.accept) */ public fun accept(contributor: AcceptHeaderContributor) { acceptContributors.add(contributor) @@ -67,6 +75,8 @@ public class ContentNegotiationConfig : Configuration { * Adds a type to the list of types that should be ignored by [ContentNegotiation]. * * The list contains the [HttpStatusCode] type by default. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.contentnegotiation.ContentNegotiationConfig.ignoreType) */ public inline fun ignoreType() { ignoreType(T::class) @@ -74,6 +84,8 @@ public class ContentNegotiationConfig : Configuration { /** * Remove [T] from the list of types that should be ignored by [ContentNegotiation]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.contentnegotiation.ContentNegotiationConfig.removeIgnoredType) */ public inline fun removeIgnoredType() { removeIgnoredType(T::class) @@ -81,6 +93,8 @@ public class ContentNegotiationConfig : Configuration { /** * Remove [type] from the list of types that should be ignored by [ContentNegotiation]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.contentnegotiation.ContentNegotiationConfig.removeIgnoredType) */ public fun removeIgnoredType(type: KClass<*>) { ignoredTypes.remove(type) @@ -90,6 +104,8 @@ public class ContentNegotiationConfig : Configuration { * Adds a [type] to the list of types that should be ignored by [ContentNegotiation]. * * The list contains the [HttpStatusCode], [ByteArray], [String] and streaming types by default. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.contentnegotiation.ContentNegotiationConfig.ignoreType) */ public fun ignoreType(type: KClass<*>) { ignoredTypes.add(type) @@ -97,6 +113,8 @@ public class ContentNegotiationConfig : Configuration { /** * Clear all configured ignored types including defaults. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.contentnegotiation.ContentNegotiationConfig.clearIgnoredTypes) */ public fun clearIgnoredTypes() { ignoredTypes.clear() diff --git a/ktor-server/ktor-server-plugins/ktor-server-cors/common/src/io/ktor/server/plugins/cors/CORS.kt b/ktor-server/ktor-server-plugins/ktor-server-cors/common/src/io/ktor/server/plugins/cors/CORS.kt index dc6765585d0..355e1b17128 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-cors/common/src/io/ktor/server/plugins/cors/CORS.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-cors/common/src/io/ktor/server/plugins/cors/CORS.kt @@ -27,6 +27,8 @@ private val LOGGER = KtorSimpleLogger("io.ktor.server.plugins.cors.CORS") * ``` * * You can learn more from [CORS](https://ktor.io/docs/cors.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.cors.CORS) */ @Deprecated( message = "This plugin was moved to io.ktor.server.plugins.cors.routing", diff --git a/ktor-server/ktor-server-plugins/ktor-server-cors/common/src/io/ktor/server/plugins/cors/CORSConfig.kt b/ktor-server/ktor-server-plugins/ktor-server-cors/common/src/io/ktor/server/plugins/cors/CORSConfig.kt index ec8c2e0a4af..027ee3f4736 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-cors/common/src/io/ktor/server/plugins/cors/CORSConfig.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-cors/common/src/io/ktor/server/plugins/cors/CORSConfig.kt @@ -11,6 +11,8 @@ import io.ktor.utils.io.* /** * A configuration for the [io.ktor.server.plugins.cors.routing.CORS] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.cors.CORSConfig) */ @KtorDsl public class CORSConfig { @@ -20,11 +22,15 @@ public class CORSConfig { /** * The default CORS max age value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.cors.CORSConfig.Companion.CORS_DEFAULT_MAX_AGE) */ public const val CORS_DEFAULT_MAX_AGE: Long = 24L * 3600 // 1 day /** * Default HTTP methods that are always allowed by CORS. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.cors.CORSConfig.Companion.CorsDefaultMethods) */ public val CorsDefaultMethods: Set = setOf(HttpMethod.Get, HttpMethod.Post, HttpMethod.Head) @@ -32,6 +38,8 @@ public class CORSConfig { * Default HTTP headers that are always allowed by CORS * (simple request headers according to https://www.w3.org/TR/cors/#simple-header). * Note that `Content-Type` header simplicity depends on its value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.cors.CORSConfig.Companion.CorsSimpleRequestHeaders) */ public val CorsSimpleRequestHeaders: Set = caseInsensitiveSet( HttpHeaders.Accept, @@ -43,6 +51,8 @@ public class CORSConfig { /** * Default HTTP headers that are always allowed by CORS to be used in a response * (simple request headers according to https://www.w3.org/TR/cors/#simple-header). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.cors.CORSConfig.Companion.CorsSimpleResponseHeaders) */ public val CorsSimpleResponseHeaders: Set = caseInsensitiveSet( HttpHeaders.CacheControl, @@ -55,6 +65,8 @@ public class CORSConfig { /** * The allowed set of content types that are allowed by CORS without preflight check. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.cors.CORSConfig.Companion.CorsSimpleContentTypes) */ @Suppress("unused") public val CorsSimpleContentTypes: Set = @@ -71,22 +83,30 @@ public class CORSConfig { /** * Allowed [CORS] hosts. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.cors.CORSConfig.hosts) */ public val hosts: MutableSet = HashSet() /** * Allowed [CORS] headers. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.cors.CORSConfig.headers) */ @OptIn(InternalAPI::class) public val headers: MutableSet = CaseInsensitiveSet() /** * Allowed [CORS] HTTP methods. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.cors.CORSConfig.methods) */ public val methods: MutableSet = HashSet() /** * Exposed HTTP headers that could be accessed by a client. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.cors.CORSConfig.exposedHeaders) */ @OptIn(InternalAPI::class) public val exposedHeaders: MutableSet = CaseInsensitiveSet() @@ -95,6 +115,8 @@ public class CORSConfig { * Allows passing credential information (such as cookies or authentication information) * with cross-origin requests. * This property sets the `Access-Control-Allow-Credentials` response header to `true`. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.cors.CORSConfig.allowCredentials) */ public var allowCredentials: Boolean = false @@ -105,12 +127,16 @@ public class CORSConfig { /** * If present represents the prefix for headers which are permitted in CORS requests. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.cors.CORSConfig.headerPredicates) */ public val headerPredicates: MutableList<(String) -> Boolean> = mutableListOf() /** * Specifies how long the response to the preflight request can be cached * without sending another preflight request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.cors.CORSConfig.maxAgeInSeconds) */ public var maxAgeInSeconds: Long = CORS_DEFAULT_MAX_AGE set(newMaxAge) { @@ -120,6 +146,8 @@ public class CORSConfig { /** * Allows requests from the same origin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.cors.CORSConfig.allowSameOrigin) */ public var allowSameOrigin: Boolean = true @@ -128,11 +156,15 @@ public class CORSConfig { * - `text/plain` * - `application/x-www-form-urlencoded` * - `multipart/form-data` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.cors.CORSConfig.allowNonSimpleContentTypes) */ public var allowNonSimpleContentTypes: Boolean = false /** * Allows requests from any host. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.cors.CORSConfig.anyHost) */ public fun anyHost() { hosts.add("*") @@ -145,6 +177,9 @@ public class CORSConfig { * Otherwise, you can mix wildcard and non-wildcard subdomains as long as * the wildcard is always in front of the domain, e.g. `*.sub.domain.com` but not `sub.*.domain.com`. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.cors.CORSConfig.allowHost) + * * @param host host as it appears in the Host header (e.g. localhost:8080) * @param schemes protocols allowed for the origin site; defaults to http and https * @param subDomains additional subdomains for the given host @@ -194,6 +229,8 @@ public class CORSConfig { * Allows exposing the [header] using `Access-Control-Expose-Headers`. * The `Access-Control-Expose-Headers` header adds the specified headers * to the allowlist that JavaScript in browsers can access. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.cors.CORSConfig.exposeHeader) */ public fun exposeHeader(header: String) { if (header !in CorsSimpleResponseHeaders) { @@ -203,6 +240,8 @@ public class CORSConfig { /** * Allows using the `X-Http-Method-Override` header for the actual [CORS] request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.cors.CORSConfig.allowXHttpMethodOverride) */ @Suppress("unused") public fun allowXHttpMethodOverride() { @@ -211,6 +250,8 @@ public class CORSConfig { /** * Allows using an origin matching [predicate] for the actual [CORS] request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.cors.CORSConfig.allowOrigins) */ public fun allowOrigins(predicate: (String) -> Boolean) { this.originPredicates.add(predicate) @@ -218,6 +259,8 @@ public class CORSConfig { /** * Allows using headers prefixed with [headerPrefix] for the actual [CORS] request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.cors.CORSConfig.allowHeadersPrefixed) */ public fun allowHeadersPrefixed(headerPrefix: String) { val prefix = headerPrefix.lowercase() @@ -226,6 +269,8 @@ public class CORSConfig { /** * Allows using headers matching [predicate] for the actual [CORS] request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.cors.CORSConfig.allowHeaders) */ public fun allowHeaders(predicate: (String) -> Boolean) { this.headerPredicates.add(predicate) @@ -233,6 +278,8 @@ public class CORSConfig { /** * Allow using a specified [header] for the actual [CORS] request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.cors.CORSConfig.allowHeader) */ public fun allowHeader(header: String) { if (header.equals(HttpHeaders.ContentType, ignoreCase = true)) { @@ -250,6 +297,8 @@ public class CORSConfig { * * Note that CORS operates with real HTTP methods only and * doesn't handle method overridden by `X-Http-Method-Override`. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.cors.CORSConfig.allowMethod) */ public fun allowMethod(method: HttpMethod) { if (method !in CorsDefaultMethods) { @@ -259,6 +308,8 @@ public class CORSConfig { /** * Allows requests with any HTTP method. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.cors.CORSConfig.anyMethod) */ public fun anyMethod() { methods.addAll(DefaultMethods) diff --git a/ktor-server/ktor-server-plugins/ktor-server-cors/common/src/io/ktor/server/plugins/cors/KotlinTimeJvm.kt b/ktor-server/ktor-server-plugins/ktor-server-cors/common/src/io/ktor/server/plugins/cors/KotlinTimeJvm.kt index a775fd3de5c..3d96a5c1b61 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-cors/common/src/io/ktor/server/plugins/cors/KotlinTimeJvm.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-cors/common/src/io/ktor/server/plugins/cors/KotlinTimeJvm.kt @@ -10,6 +10,8 @@ import kotlin.time.Duration.Companion.seconds /** * Duration to tell the client to keep CORS options. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.cors.maxAgeDuration) */ public var CORSConfig.maxAgeDuration: Duration get() = maxAgeInSeconds.seconds diff --git a/ktor-server/ktor-server-plugins/ktor-server-cors/common/src/io/ktor/server/plugins/cors/routing/CORS.kt b/ktor-server/ktor-server-plugins/ktor-server-cors/common/src/io/ktor/server/plugins/cors/routing/CORS.kt index 1d27e3deef4..161fc8efb04 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-cors/common/src/io/ktor/server/plugins/cors/routing/CORS.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-cors/common/src/io/ktor/server/plugins/cors/routing/CORS.kt @@ -20,6 +20,8 @@ import io.ktor.server.plugins.cors.* * ``` * * You can learn more from [CORS](https://ktor.io/docs/cors.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.cors.routing.CORS) */ public val CORS: RouteScopedPlugin = createRouteScopedPlugin("CORS", ::CORSConfig) { buildPlugin() diff --git a/ktor-server/ktor-server-plugins/ktor-server-csrf/common/src/io/ktor/server/plugins/csrf/CSRF.kt b/ktor-server/ktor-server-plugins/ktor-server-csrf/common/src/io/ktor/server/plugins/csrf/CSRF.kt index 34f80112543..f9d5cab1702 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-csrf/common/src/io/ktor/server/plugins/csrf/CSRF.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-csrf/common/src/io/ktor/server/plugins/csrf/CSRF.kt @@ -30,6 +30,9 @@ import io.ktor.server.request.* * } * ``` * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.csrf.CSRF) + * * @see io.ktor.server.sessions.SameSite for preventing cookies from being used when navigating from external sites */ public val CSRF: RouteScopedPlugin = createRouteScopedPlugin("CSRF", ::CSRFConfig) { diff --git a/ktor-server/ktor-server-plugins/ktor-server-csrf/common/src/io/ktor/server/plugins/csrf/CSRFConfig.kt b/ktor-server/ktor-server-plugins/ktor-server-csrf/common/src/io/ktor/server/plugins/csrf/CSRFConfig.kt index 6b00b4efd87..d7ba78ffd6e 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-csrf/common/src/io/ktor/server/plugins/csrf/CSRFConfig.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-csrf/common/src/io/ktor/server/plugins/csrf/CSRFConfig.kt @@ -11,6 +11,8 @@ import io.ktor.utils.io.* /** * A configuration for the [io.ktor.server.plugins.csrf.CSRF] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.csrf.CSRFConfig) */ @KtorDsl public class CSRFConfig { @@ -23,6 +25,9 @@ public class CSRFConfig { * All incoming requests must have an "Origin" header matching one of the hosts * defined using this method. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.csrf.CSRFConfig.allowOrigin) + * * @param origin expected "Origin" header, revealing the URL of the site leading up * to the path (e.g. https://google.com) * @see [CSRF Cheatsheet, Verifying Origin with standard headers](https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#verifying-origin-with-standard-headers) @@ -36,6 +41,9 @@ public class CSRFConfig { * header. This avoids needing to configure the expected host name where your * application is deployed but will not work when it is deployed behind a proxy. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.csrf.CSRFConfig.originMatchesHost) + * * @see [CSRF Cheatsheet, Identifying the target origin](https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#identifying-the-target-origin) */ public fun originMatchesHost() { @@ -47,6 +55,9 @@ public class CSRFConfig { * conforms to the optional predicate. If conditions already exist for the header, they * must all be satisfied. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.csrf.CSRFConfig.checkHeader) + * * @param header the name of the header to validate * @param predicate the condition to check on the value of the header * @see [CSRF Cheatsheet, Custom request headers](https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#custom-request-headers) @@ -60,6 +71,9 @@ public class CSRFConfig { * containing the error. As with any security-related error, it is advised to log the problem and * return some generic response. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.csrf.CSRFConfig.onFailure) + * * @param handleFailure handler for CSRF error conditions */ public fun onFailure(handleFailure: suspend ApplicationCall.(String) -> Unit) { diff --git a/ktor-server/ktor-server-plugins/ktor-server-data-conversion/common/src/io/ktor/server/plugins/dataconversion/DataConversion.kt b/ktor-server/ktor-server-plugins/ktor-server-data-conversion/common/src/io/ktor/server/plugins/dataconversion/DataConversion.kt index ae85d40e779..0021cd53946 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-data-conversion/common/src/io/ktor/server/plugins/dataconversion/DataConversion.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-data-conversion/common/src/io/ktor/server/plugins/dataconversion/DataConversion.kt @@ -11,6 +11,8 @@ import io.ktor.util.converters.DataConversion /** * Object for installing [io.ktor.util.converters.DataConversion] plugin + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.dataconversion.DataConversion) */ public object DataConversion : BaseApplicationPlugin { @@ -28,6 +30,8 @@ public object DataConversion : /** * Lookup for a conversion service. Returns the default one if the plugin wasn't installed + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.dataconversion.conversionService) */ @Suppress("DEPRECATION_ERROR") public val ApplicationCallPipeline.conversionService: ConversionService diff --git a/ktor-server/ktor-server-plugins/ktor-server-default-headers/common/src/io/ktor/server/plugins/defaultheaders/DefaultHeaders.kt b/ktor-server/ktor-server-plugins/ktor-server-default-headers/common/src/io/ktor/server/plugins/defaultheaders/DefaultHeaders.kt index 747b4c5d9b0..c0dd721ef68 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-default-headers/common/src/io/ktor/server/plugins/defaultheaders/DefaultHeaders.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-default-headers/common/src/io/ktor/server/plugins/defaultheaders/DefaultHeaders.kt @@ -15,6 +15,8 @@ import kotlinx.atomicfu.atomic /** * A configuration for the [DefaultHeaders] plugin. * Allows you to configure additional default headers. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.defaultheaders.DefaultHeadersConfig) */ @KtorDsl public class DefaultHeadersConfig { @@ -25,20 +27,28 @@ public class DefaultHeadersConfig { /** * Adds a standard header with the specified [name] and [value]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.defaultheaders.DefaultHeadersConfig.header) */ public fun header(name: String, value: String): Unit = headers.append(name, value) /** * Provides a time source. Useful for testing. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.defaultheaders.DefaultHeadersConfig.clock) */ public var clock: Clock = Clock { kotlinx.datetime.Clock.System.now().toEpochMilliseconds() } /** * Utility interface for obtaining timestamp. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.defaultheaders.DefaultHeadersConfig.Clock) */ public fun interface Clock { /** * Get current timestamp. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.defaultheaders.DefaultHeadersConfig.Clock.now) */ public fun now(): Long } @@ -58,6 +68,8 @@ public class DefaultHeadersConfig { * } * ``` * You can learn more from [Default headers](https://ktor.io/docs/default-headers.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.defaultheaders.DefaultHeaders) */ public val DefaultHeaders: RouteScopedPlugin = createRouteScopedPlugin( "DefaultHeaders", diff --git a/ktor-server/ktor-server-plugins/ktor-server-double-receive/common/src/io/ktor/server/plugins/doublereceive/DoubleReceive.kt b/ktor-server/ktor-server-plugins/ktor-server-double-receive/common/src/io/ktor/server/plugins/doublereceive/DoubleReceive.kt index d3ce84a57f5..7fe2c310ebc 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-double-receive/common/src/io/ktor/server/plugins/doublereceive/DoubleReceive.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-double-receive/common/src/io/ktor/server/plugins/doublereceive/DoubleReceive.kt @@ -24,6 +24,8 @@ internal val LOGGER = KtorSimpleLogger("io.ktor.server.plugins.doublereceive.Dou * * You can learn more from [DoubleReceive](https://ktor.io/docs/double-receive.html). * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.doublereceive.DoubleReceive) */ public val DoubleReceive: RouteScopedPlugin = createRouteScopedPlugin( "DoubleReceive", diff --git a/ktor-server/ktor-server-plugins/ktor-server-double-receive/common/src/io/ktor/server/plugins/doublereceive/DoubleReceiveConfig.kt b/ktor-server/ktor-server-plugins/ktor-server-double-receive/common/src/io/ktor/server/plugins/doublereceive/DoubleReceiveConfig.kt index db9999fb49e..152ce4a39e7 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-double-receive/common/src/io/ktor/server/plugins/doublereceive/DoubleReceiveConfig.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-double-receive/common/src/io/ktor/server/plugins/doublereceive/DoubleReceiveConfig.kt @@ -11,6 +11,8 @@ import io.ktor.utils.io.* /** * A configuration for the [DoubleReceive] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.doublereceive.DoubleReceiveConfig) */ @KtorDsl public class DoubleReceiveConfig { @@ -23,6 +25,9 @@ public class DoubleReceiveConfig { * This is useful, for example, when you want to receive a request body twice with different types or receive data * as a stream multiple times. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.doublereceive.DoubleReceiveConfig.cacheRawRequest) + * * @see [DoubleReceive] */ public var cacheRawRequest: Boolean = true @@ -30,6 +35,8 @@ public class DoubleReceiveConfig { /** * Adds a filter to the [DoubleReceive] plugin. * Can be called multiple times; if any of [block]s returns `true`, a request body will not be cached in memory. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.doublereceive.DoubleReceiveConfig.excludeFromCache) */ public fun excludeFromCache(block: (call: ApplicationCall, body: Any) -> Boolean) { filters += block @@ -42,6 +49,8 @@ public class DoubleReceiveConfig { * * Can be called multiple times; if any of [block]s returns `true`, the request body will be cached in file. * Otherwise, it will be cached in memory. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.doublereceive.DoubleReceiveConfig.useFileForCache) */ public fun useFileForCache(block: (call: ApplicationCall) -> Boolean = { true }) { shouldUseFileCache += block @@ -49,6 +58,8 @@ public class DoubleReceiveConfig { /** * Excludes requests with a content size greater than [maxSize] from cache. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.doublereceive.DoubleReceiveConfig.maxSize) */ public fun maxSize(limit: Long) { excludeFromCache { call, _ -> @@ -59,6 +70,8 @@ public class DoubleReceiveConfig { /** * Excludes a specific type from caching. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.doublereceive.DoubleReceiveConfig.exclude) */ public inline fun exclude() { val excludeType = typeInfo() diff --git a/ktor-server/ktor-server-plugins/ktor-server-forwarded-header/common/src/io/ktor/server/plugins/forwardedheaders/ForwardedHeaders.kt b/ktor-server/ktor-server-plugins/ktor-server-forwarded-header/common/src/io/ktor/server/plugins/forwardedheaders/ForwardedHeaders.kt index b264a9681a5..99c04ea714c 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-forwarded-header/common/src/io/ktor/server/plugins/forwardedheaders/ForwardedHeaders.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-forwarded-header/common/src/io/ktor/server/plugins/forwardedheaders/ForwardedHeaders.kt @@ -16,12 +16,16 @@ import io.ktor.utils.io.* /** * A key for the application call attribute that is used to cache parsed header values. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.forwardedheaders.FORWARDED_PARSED_KEY) */ public val FORWARDED_PARSED_KEY: AttributeKey> = AttributeKey("ForwardedParsedKey") /** * A configuration for the [ForwardedHeaders] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.forwardedheaders.ForwardedHeadersConfig) */ @KtorDsl public class ForwardedHeadersConfig { @@ -35,6 +39,8 @@ public class ForwardedHeadersConfig { /** * Custom logic to extract the value from the Forward headers when multiple values are present. * You need to modify [MutableOriginConnectionPoint] based on headers from [ForwardedHeaderValue]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.forwardedheaders.ForwardedHeadersConfig.extractValue) */ public fun extractValue(block: (MutableOriginConnectionPoint, List) -> Unit) { forwardedHeadersHandler = block @@ -42,6 +48,8 @@ public class ForwardedHeadersConfig { /** * Takes the first value from the Forward header when multiple values are present. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.forwardedheaders.ForwardedHeadersConfig.useFirstValue) */ public fun useFirstValue() { extractValue { connectionPoint, headers -> @@ -51,6 +59,8 @@ public class ForwardedHeadersConfig { /** * Takes the last value from Forward header when multiple values are present. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.forwardedheaders.ForwardedHeadersConfig.useLastValue) */ public fun useLastValue() { extractValue { connectionPoint, headers -> @@ -60,6 +70,8 @@ public class ForwardedHeadersConfig { /** * Takes [proxiesCount] before the last value from Forward header when multiple values are present. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.forwardedheaders.ForwardedHeadersConfig.skipLastProxies) */ public fun skipLastProxies(proxiesCount: Int) { extractValue { connectionPoint, headers -> @@ -70,6 +82,8 @@ public class ForwardedHeadersConfig { /** * Removes known [hosts] from the end of the list and takes the last value * from Forward headers when multiple values are present. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.forwardedheaders.ForwardedHeadersConfig.skipKnownProxies) */ public fun skipKnownProxies(hosts: List) { extractValue { connectionPoint, headers -> @@ -133,6 +147,9 @@ public class ForwardedHeadersConfig { /** * Parsed a forwarded header value. All fields are optional as proxy could provide different fields. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.forwardedheaders.ForwardedHeaderValue) + * * @property host field value (optional) * @property by field value (optional) * @property forParam field value (optional) @@ -153,6 +170,8 @@ public data class ForwardedHeaderValue( * * To learn how to install and use [ForwardedHeaders], see * [Forwarded headers](https://ktor.io/docs/forward-headers.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.forwardedheaders.ForwardedHeaders) */ public val ForwardedHeaders: ApplicationPlugin = createApplicationPlugin( "ForwardedHeaders", diff --git a/ktor-server/ktor-server-plugins/ktor-server-forwarded-header/common/src/io/ktor/server/plugins/forwardedheaders/XForwardedHeaders.kt b/ktor-server/ktor-server-plugins/ktor-server-forwarded-header/common/src/io/ktor/server/plugins/forwardedheaders/XForwardedHeaders.kt index 259e35475f1..a34994b46de 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-forwarded-header/common/src/io/ktor/server/plugins/forwardedheaders/XForwardedHeaders.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-forwarded-header/common/src/io/ktor/server/plugins/forwardedheaders/XForwardedHeaders.kt @@ -14,12 +14,16 @@ import io.ktor.utils.io.* /** * A configuration for the [XForwardedHeaders] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.forwardedheaders.XForwardedHeadersConfig) */ @KtorDsl public class XForwardedHeadersConfig { /** * Gets headers used to identify the original host requested by the client. * Default are `X-Forwarded-Server` and `X-Forwarded-Host`. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.forwardedheaders.XForwardedHeadersConfig.hostHeaders) */ public val hostHeaders: ArrayList = arrayListOf(HttpHeaders.XForwardedHost, HttpHeaders.XForwardedServer) @@ -27,24 +31,32 @@ public class XForwardedHeadersConfig { * Gets headers used to identify the protocol (HTTP or HTTPS) that a client used * to connect to a proxy or load balancer. Default are `X-Forwarded-Proto` and `X-Forwarded-Protocol`. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.forwardedheaders.XForwardedHeadersConfig.protoHeaders) */ public val protoHeaders: MutableList = mutableListOf(HttpHeaders.XForwardedProto, "X-Forwarded-Protocol") /** * Gets headers used to identify the originating IP address of a client connecting to * a server through a proxy or a load balancer. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.forwardedheaders.XForwardedHeadersConfig.forHeaders) */ public val forHeaders: MutableList = mutableListOf(HttpHeaders.XForwardedFor) /** * Gets headers used to identify whether HTTPS/TLS is used between * the client and the front-end server. Default are `X-Forwarded-SSL` and `Front-End-Https`. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.forwardedheaders.XForwardedHeadersConfig.httpsFlagHeaders) */ public val httpsFlagHeaders: MutableList = mutableListOf("X-Forwarded-SSL", "Front-End-Https") /** * Gets headers used to identify the destination port. * The default is `X-Forwarded-Port`. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.forwardedheaders.XForwardedHeadersConfig.portHeaders) */ public val portHeaders: MutableList = mutableListOf("X-Forwarded-Port") @@ -57,6 +69,8 @@ public class XForwardedHeadersConfig { /** * Custom logic to extract the value from the X-Forward-* headers when multiple values are present. * You need to modify [MutableOriginConnectionPoint] based on headers from [XForwardedHeaderValues]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.forwardedheaders.XForwardedHeadersConfig.extractEdgeProxy) */ public fun extractEdgeProxy(block: (MutableOriginConnectionPoint, XForwardedHeaderValues) -> Unit) { xForwardedHeadersHandler = block @@ -64,6 +78,8 @@ public class XForwardedHeadersConfig { /** * Takes the first value from the `X-Forward-*` headers when multiple values are present. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.forwardedheaders.XForwardedHeadersConfig.useFirstProxy) */ public fun useFirstProxy() { extractEdgeProxy { connectionPoint, headers -> @@ -73,6 +89,8 @@ public class XForwardedHeadersConfig { /** * Takes the last value from the `X-Forward-*` headers when multiple values are present. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.forwardedheaders.XForwardedHeadersConfig.useLastProxy) */ public fun useLastProxy() { extractEdgeProxy { connectionPoint, headers -> @@ -82,6 +100,8 @@ public class XForwardedHeadersConfig { /** * Takes the [proxiesCount]-before-last value from the `X-Forward-*` headers when multiple values are present. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.forwardedheaders.XForwardedHeadersConfig.skipLastProxies) */ public fun skipLastProxies(proxiesCount: Int) { extractEdgeProxy { connectionPoint, headers -> @@ -94,6 +114,8 @@ public class XForwardedHeadersConfig { /** * Removes known [hosts] from the end of the list and takes the last value * from `X-Forward-*` headers when multiple values are present. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.forwardedheaders.XForwardedHeadersConfig.skipKnownProxies) * */ public fun skipKnownProxies(hosts: List) { extractEdgeProxy { connectionPoint, headers -> @@ -183,6 +205,8 @@ public class XForwardedHeadersConfig { /** * Values of the `X-Forward-*` headers. Each property may contain multiple comma-separated values. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.forwardedheaders.XForwardedHeaderValues) */ public data class XForwardedHeaderValues( /** @@ -213,6 +237,8 @@ public data class XForwardedHeaderValues( * * To learn how to install and use [XForwardedHeaders], see * [Forwarded headers](https://ktor.io/docs/forward-headers.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.forwardedheaders.XForwardedHeaders) */ public val XForwardedHeaders: ApplicationPlugin = createApplicationPlugin( "XForwardedHeaders", diff --git a/ktor-server/ktor-server-plugins/ktor-server-freemarker/jvm/src/io/ktor/server/freemarker/FreeMarker.kt b/ktor-server/ktor-server-plugins/ktor-server-freemarker/jvm/src/io/ktor/server/freemarker/FreeMarker.kt index 5773aefdbf5..3ebc92b3bbe 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-freemarker/jvm/src/io/ktor/server/freemarker/FreeMarker.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-freemarker/jvm/src/io/ktor/server/freemarker/FreeMarker.kt @@ -15,6 +15,9 @@ import java.io.* /** * A response content handled by the [FreeMarker] plugin. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.freemarker.FreeMarkerContent) + * * @param template name that is resolved by FreeMarker * @param model to be passed during template rendering * @param etag value for the `E-Tag` header (optional) @@ -31,6 +34,8 @@ public class FreeMarkerContent( * A plugin that allows you to use FreeMarker templates as views within your application. * Provides the ability to respond with [FreeMarkerContent]. * You can learn more from [FreeMarker](https://ktor.io/docs/freemarker.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.freemarker.FreeMarker) */ public val FreeMarker: ApplicationPlugin = createApplicationPlugin( "FreeMarker", diff --git a/ktor-server/ktor-server-plugins/ktor-server-freemarker/jvm/src/io/ktor/server/freemarker/RespondTemplate.kt b/ktor-server/ktor-server-plugins/ktor-server-freemarker/jvm/src/io/ktor/server/freemarker/RespondTemplate.kt index 548e2f531c5..0dfff3d5a5a 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-freemarker/jvm/src/io/ktor/server/freemarker/RespondTemplate.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-freemarker/jvm/src/io/ktor/server/freemarker/RespondTemplate.kt @@ -11,6 +11,9 @@ import io.ktor.server.response.* /** * Responds with the specified [template] and data [model]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.freemarker.respondTemplate) + * * @see FreeMarkerContent */ public suspend fun ApplicationCall.respondTemplate( diff --git a/ktor-server/ktor-server-plugins/ktor-server-hsts/common/src/io/ktor/server/plugins/hsts/HSTS.kt b/ktor-server/ktor-server-plugins/ktor-server-hsts/common/src/io/ktor/server/plugins/hsts/HSTS.kt index 803f4dbdcf3..2336354e7ef 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-hsts/common/src/io/ktor/server/plugins/hsts/HSTS.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-hsts/common/src/io/ktor/server/plugins/hsts/HSTS.kt @@ -13,22 +13,30 @@ import io.ktor.utils.io.* /** * A configuration for the [HSTS] settings for a host. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.hsts.HSTSHostConfig) */ @KtorDsl public open class HSTSHostConfig { /** * Specifies the `preload` HSTS directive, which allows you to include your domain name * in the HSTS preload list. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.hsts.HSTSHostConfig.preload) */ public var preload: Boolean = false /** * Specifies the `includeSubDomains` directive, which applies this policy to any subdomains as well. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.hsts.HSTSHostConfig.includeSubDomains) */ public var includeSubDomains: Boolean = true /** * Specifies how long (in seconds) the client should keep the host in a list of known HSTS hosts: + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.hsts.HSTSHostConfig.maxAgeInSeconds) */ public var maxAgeInSeconds: Long = DEFAULT_HSTS_MAX_AGE set(newMaxAge) { @@ -38,12 +46,16 @@ public open class HSTSHostConfig { /** * Allows you to add custom directives supported by a specific user agent. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.hsts.HSTSHostConfig.customDirectives) */ public val customDirectives: MutableMap = HashMap() } /** * A configuration for the [HSTS] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.hsts.HSTSConfig) */ @KtorDsl public class HSTSConfig : HSTSHostConfig() { @@ -56,6 +68,8 @@ public class HSTSConfig : HSTSHostConfig() { /** * Set specific configuration for a [host]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.hsts.HSTSConfig.withHost) */ public fun withHost(host: String, configure: HSTSHostConfig.() -> Unit) { this.hostSpecific[host] = HSTSHostConfig().apply(configure) @@ -63,6 +77,8 @@ public class HSTSConfig : HSTSHostConfig() { /** * Sets a filter that determines whether the plugin should be applied to a specific call. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.hsts.HSTSConfig.filter) */ public fun filter(block: (ApplicationCall) -> Boolean) { this.filter = block @@ -82,6 +98,8 @@ internal const val DEFAULT_HSTS_MAX_AGE: Long = 365L * 24 * 3600 // 365 days * } * ``` * You can learn more from [HSTS](https://ktor.io/docs/hsts.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.hsts.HSTS) */ public val HSTS: RouteScopedPlugin = createRouteScopedPlugin("HSTS", ::HSTSConfig) { fun constructHeaderValue(config: HSTSHostConfig) = buildString { diff --git a/ktor-server/ktor-server-plugins/ktor-server-hsts/common/src/io/ktor/server/plugins/hsts/KotlinTimeJvm.kt b/ktor-server/ktor-server-plugins/ktor-server-hsts/common/src/io/ktor/server/plugins/hsts/KotlinTimeJvm.kt index d2de68c0ec9..b2a652e2079 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-hsts/common/src/io/ktor/server/plugins/hsts/KotlinTimeJvm.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-hsts/common/src/io/ktor/server/plugins/hsts/KotlinTimeJvm.kt @@ -10,6 +10,8 @@ import kotlin.time.Duration.Companion.seconds /** * Duration to tell the client to keep the host in a list of known HSTS hosts. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.hsts.maxAgeDuration) */ public var HSTSConfig.maxAgeDuration: Duration get() = maxAgeInSeconds.seconds diff --git a/ktor-server/ktor-server-plugins/ktor-server-html-builder/common/src/io/ktor/server/html/RespondHtml.kt b/ktor-server/ktor-server-plugins/ktor-server-html-builder/common/src/io/ktor/server/html/RespondHtml.kt index 2608a20a2df..9e839fe3d5b 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-html-builder/common/src/io/ktor/server/html/RespondHtml.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-html-builder/common/src/io/ktor/server/html/RespondHtml.kt @@ -17,6 +17,8 @@ import kotlinx.html.stream.* /** * Responds to a client with an HTML response using the specified [block] to build an HTML page. * You can learn more from [HTML DSL](https://ktor.io/docs/html-dsl.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.html.respondHtml) */ public suspend fun ApplicationCall.respondHtml(status: HttpStatusCode = HttpStatusCode.OK, block: HTML.() -> Unit) { val text = buildString { @@ -28,6 +30,9 @@ public suspend fun ApplicationCall.respondHtml(status: HttpStatusCode = HttpStat /** * Represents an [OutgoingContent] build using `kotlinx.html`. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.html.HtmlContent) + * * @see [respondHtml] */ @Deprecated("This will be removed from public API", level = DeprecationLevel.ERROR) diff --git a/ktor-server/ktor-server-plugins/ktor-server-html-builder/common/src/io/ktor/server/html/RespondHtmlTemplate.kt b/ktor-server/ktor-server-plugins/ktor-server-html-builder/common/src/io/ktor/server/html/RespondHtmlTemplate.kt index 02eebb5f3f1..ffd71674540 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-html-builder/common/src/io/ktor/server/html/RespondHtmlTemplate.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-html-builder/common/src/io/ktor/server/html/RespondHtmlTemplate.kt @@ -11,6 +11,8 @@ import kotlinx.html.* /** * Responds to a client with an HTML response built based on a specified template. * You can learn more from [HTML DSL](https://ktor.io/docs/html-dsl.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.html.respondHtmlTemplate) */ public suspend fun > ApplicationCall.respondHtmlTemplate( template: TTemplate, diff --git a/ktor-server/ktor-server-plugins/ktor-server-html-builder/common/src/io/ktor/server/html/Template.kt b/ktor-server/ktor-server-plugins/ktor-server-html-builder/common/src/io/ktor/server/html/Template.kt index b316cce4bdf..b9030be9253 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-html-builder/common/src/io/ktor/server/html/Template.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-html-builder/common/src/io/ktor/server/html/Template.kt @@ -6,6 +6,9 @@ package io.ktor.server.html /** * A template that expands inside [TOuter]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.html.Template) + * * @see [respondHtmlTemplate] */ public interface Template { @@ -14,6 +17,9 @@ public interface Template { /** * A placeholder that is inserted inside [TOuter]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.html.Placeholder) + * * @see [respondHtmlTemplate] */ public open class Placeholder { @@ -32,6 +38,9 @@ public open class Placeholder { /** * A placeholder that can be used to insert the content that appears multiple times (for example, list items). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.html.PlaceholderList) + * * @see [respondHtmlTemplate] */ public open class PlaceholderList { @@ -59,6 +68,8 @@ public open class PlaceholderList { /** * An item of a [PlaceholderList] when it is expanded. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.html.PlaceholderItem) */ public class PlaceholderItem(public val index: Int, public val collection: List>) : Placeholder() { @@ -68,6 +79,8 @@ public class PlaceholderItem(public val index: Int, public val collectio /** * Inserts every element of [PlaceholderList]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.html.each) */ public fun TOuter.each( items: PlaceholderList, @@ -78,12 +91,16 @@ public fun TOuter.each( /** * Inserts [Placeholder]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.html.insert) */ public fun TOuter.insert(placeholder: Placeholder): Unit = placeholder.apply(this) /** * A placeholder that is also a [Template]. * It can be used to insert child templates and create nested layouts. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.html.TemplatePlaceholder) */ public open class TemplatePlaceholder { private var content: TTemplate.() -> Unit = { } diff --git a/ktor-server/ktor-server-plugins/ktor-server-http-redirect/common/src/io/ktor/server/plugins/httpsredirect/HttpsRedirect.kt b/ktor-server/ktor-server-plugins/ktor-server-http-redirect/common/src/io/ktor/server/plugins/httpsredirect/HttpsRedirect.kt index 10c5a060a9f..e81f90359e7 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-http-redirect/common/src/io/ktor/server/plugins/httpsredirect/HttpsRedirect.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-http-redirect/common/src/io/ktor/server/plugins/httpsredirect/HttpsRedirect.kt @@ -13,26 +13,36 @@ import io.ktor.utils.io.* /** * A configuration for the [HttpsRedirect] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.httpsredirect.HttpsRedirectConfig) */ @KtorDsl public class HttpsRedirectConfig { /** * Specifies an HTTPS port (443 by default) used to redirect HTTP requests. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.httpsredirect.HttpsRedirectConfig.sslPort) */ public var sslPort: Int = URLProtocol.HTTPS.defaultPort /** * Specifies whether to use permanent or temporary redirect. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.httpsredirect.HttpsRedirectConfig.permanentRedirect) */ public var permanentRedirect: Boolean = true /** * Allows you to disable redirection for calls matching specified conditions. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.httpsredirect.HttpsRedirectConfig.excludePredicates) */ public val excludePredicates: MutableList<(ApplicationCall) -> Boolean> = ArrayList() /** * Allows you to disable redirection for calls with a path matching [pathPrefix]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.httpsredirect.HttpsRedirectConfig.excludePrefix) */ public fun excludePrefix(pathPrefix: String) { exclude { call -> @@ -42,6 +52,8 @@ public class HttpsRedirectConfig { /** * Allows you to disable redirection for calls with a path matching [pathSuffix]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.httpsredirect.HttpsRedirectConfig.excludeSuffix) */ public fun excludeSuffix(pathSuffix: String) { exclude { call -> @@ -51,6 +63,8 @@ public class HttpsRedirectConfig { /** * Allows you to disable redirection for calls matching the specified [predicate]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.httpsredirect.HttpsRedirectConfig.exclude) */ public fun exclude(predicate: (call: ApplicationCall) -> Boolean) { excludePredicates.add(predicate) @@ -70,6 +84,8 @@ public class HttpsRedirectConfig { * ``` * * You can learn more from [HttpsRedirect](https://ktor.io/docs/https-redirect.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.httpsredirect.HttpsRedirect) */ public val HttpsRedirect: ApplicationPlugin = createApplicationPlugin( "HttpsRedirect", diff --git a/ktor-server/ktor-server-plugins/ktor-server-i18n/jvm/src/io/ktor/i18n/I18n.kt b/ktor-server/ktor-server-plugins/ktor-server-i18n/jvm/src/io/ktor/i18n/I18n.kt index f81d1196e8d..b5bf2fe0a4d 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-i18n/jvm/src/io/ktor/i18n/I18n.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-i18n/jvm/src/io/ktor/i18n/I18n.kt @@ -20,6 +20,8 @@ internal val REQUIRED_RESPONSE_LANGUAGE = AttributeKey("ResponseLanguage * I18n configuration. Currently supports [encoding] and [defaultLanguage] * * [defaultLanguage] must follow IETF BCP 47 language tag string specification + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.i18n.I18nConfiguration) */ public class I18nConfiguration { public var availableLanguages: List = listOf("en-US") @@ -33,6 +35,8 @@ public class I18nConfiguration { * defaultLanguage = "pt-BR" * encoding = StandardCharsets.UTF_8 * } + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.i18n.I18n) */ public val I18n: ApplicationPlugin = createApplicationPlugin( "I18n", diff --git a/ktor-server/ktor-server-plugins/ktor-server-i18n/jvm/src/io/ktor/i18n/Translate.kt b/ktor-server/ktor-server-plugins/ktor-server-i18n/jvm/src/io/ktor/i18n/Translate.kt index 8cbb5583957..0ff6ed43c29 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-i18n/jvm/src/io/ktor/i18n/Translate.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-i18n/jvm/src/io/ktor/i18n/Translate.kt @@ -9,6 +9,8 @@ import java.util.* /** * Translate a message key to an accepted language specified in HTTP request + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.i18n.i18n) */ public fun RoutingContext.i18n(key: String): String { val bestMatchLanguage = call.attributes[REQUIRED_RESPONSE_LANGUAGE] diff --git a/ktor-server/ktor-server-plugins/ktor-server-jte/jvm/src/io/ktor/server/jte/Jte.kt b/ktor-server/ktor-server-plugins/ktor-server-jte/jvm/src/io/ktor/server/jte/Jte.kt index c769f5abd27..65e46e058a2 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-jte/jvm/src/io/ktor/server/jte/Jte.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-jte/jvm/src/io/ktor/server/jte/Jte.kt @@ -16,6 +16,9 @@ import io.ktor.utils.io.* /** * A response content handled by the [Jte] plugin. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.jte.JteContent) + * * @param template file name that is resolved by the Jte [TemplateEngine] * @param params to be passed to the template * @param etag value for the `E-Tag` header (optional) @@ -30,6 +33,8 @@ public class JteContent( /** * A configuration for the [Jte] plugin, where the Jte [TemplateEngine] can be customized. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.jte.JteConfig) */ @KtorDsl public class JteConfig { @@ -40,6 +45,8 @@ public class JteConfig { * A plugin that allows you to use jte templates as views within your application. * Provides the ability to respond with [JteContent]. * You can learn more from [JTE](https://ktor.io/docs/jte.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.jte.Jte) */ public val Jte: ApplicationPlugin = createApplicationPlugin("jte", ::JteConfig) { diff --git a/ktor-server/ktor-server-plugins/ktor-server-jte/jvm/src/io/ktor/server/jte/RespondTemplate.kt b/ktor-server/ktor-server-plugins/ktor-server-jte/jvm/src/io/ktor/server/jte/RespondTemplate.kt index 4f7de3460b7..72d333cad1b 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-jte/jvm/src/io/ktor/server/jte/RespondTemplate.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-jte/jvm/src/io/ktor/server/jte/RespondTemplate.kt @@ -11,6 +11,9 @@ import io.ktor.server.response.* /** * Responds with the specified [template] passing [params]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.jte.respondTemplate) + * * @see JteContent */ public suspend fun ApplicationCall.respondTemplate( @@ -23,6 +26,9 @@ public suspend fun ApplicationCall.respondTemplate( /** * Responds with the specified [template] passing [params] as a vararg of [Pair]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.jte.respondTemplate) + * * @see JteContent */ public suspend fun ApplicationCall.respondTemplate( diff --git a/ktor-server/ktor-server-plugins/ktor-server-method-override/common/src/io/ktor/server/plugins/methodoverride/XHttpMethodOverride.kt b/ktor-server/ktor-server-plugins/ktor-server-method-override/common/src/io/ktor/server/plugins/methodoverride/XHttpMethodOverride.kt index e0d7727396b..360f9adb408 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-method-override/common/src/io/ktor/server/plugins/methodoverride/XHttpMethodOverride.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-method-override/common/src/io/ktor/server/plugins/methodoverride/XHttpMethodOverride.kt @@ -19,6 +19,8 @@ import io.ktor.utils.io.* * Ktor will process this request using the `delete` route handler. * * To learn more, see [XHttpMethodOverride](https://ktor.io/docs/x-http-method-override.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.methodoverride.XHttpMethodOverride) */ public val XHttpMethodOverride: ApplicationPlugin = createApplicationPlugin( "XHttpMethodOverride", @@ -33,11 +35,15 @@ public val XHttpMethodOverride: ApplicationPlugin = c /** * A configuration for the [XHttpMethodOverride] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.methodoverride.XHttpMethodOverrideConfig) */ @KtorDsl public class XHttpMethodOverrideConfig { /** * Specifies a name of the header used to override an HTTP method. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.methodoverride.XHttpMethodOverrideConfig.headerName) */ public var headerName: String = HttpHeaders.XHttpMethodOverride } diff --git a/ktor-server/ktor-server-plugins/ktor-server-metrics-micrometer/jvm/src/io/ktor/server/metrics/micrometer/MicrometerMetrics.kt b/ktor-server/ktor-server-plugins/ktor-server-metrics-micrometer/jvm/src/io/ktor/server/metrics/micrometer/MicrometerMetrics.kt index fa2ad1fbd5d..9dff6e81819 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-metrics-micrometer/jvm/src/io/ktor/server/metrics/micrometer/MicrometerMetrics.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-metrics-micrometer/jvm/src/io/ktor/server/metrics/micrometer/MicrometerMetrics.kt @@ -24,6 +24,8 @@ import java.util.concurrent.atomic.* /** * A configuration for the [MicrometerMetrics] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.metrics.micrometer.MicrometerMetricsConfig) */ @KtorDsl public class MicrometerMetricsConfig { @@ -36,6 +38,9 @@ public class MicrometerMetricsConfig { * If you change it to "custom.metric.name", the mentioned metrics will look as follows: * - "custom.metric.name.active" * - "custom.metric.name.seconds.max" + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.metrics.micrometer.MicrometerMetricsConfig.metricName) + * * @see [MicrometerMetrics] */ public var metricName: String = "ktor.http.server.requests" @@ -48,6 +53,9 @@ public class MicrometerMetricsConfig { * registry = PrometheusMeterRegistry(PrometheusConfig.DEFAULT) * } * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.metrics.micrometer.MicrometerMetricsConfig.registry) + * * @see [MicrometerMetrics] */ public var registry: MeterRegistry = LoggingMeterRegistry() @@ -59,6 +67,9 @@ public class MicrometerMetricsConfig { /** * Specifies if requests for non-existent routes should * contain a request path or fallback to common `n/a` value. `true` by default. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.metrics.micrometer.MicrometerMetricsConfig.distinctNotRegisteredRoutes) + * * @see [MicrometerMetrics] */ public var distinctNotRegisteredRoutes: Boolean = true @@ -69,6 +80,9 @@ public class MicrometerMetricsConfig { * ```kotlin * meterBinders = emptyList() * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.metrics.micrometer.MicrometerMetricsConfig.meterBinders) + * * @see [MicrometerMetrics] */ public var meterBinders: List = listOf( @@ -86,6 +100,9 @@ public class MicrometerMetricsConfig { * By default, 50%, 90% , 95% and 99% percentiles are configured. * If your backend supports server side histograms, you should enable these instead * with [DistributionStatisticConfig.Builder.percentilesHistogram] as client side percentiles cannot be aggregated. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.metrics.micrometer.MicrometerMetricsConfig.distributionStatisticConfig) + * * @see [MicrometerMetrics] */ public var distributionStatisticConfig: DistributionStatisticConfig = @@ -96,6 +113,8 @@ public class MicrometerMetricsConfig { /** * Configures micrometer timers. * Can be used to customize tags for each timer, configure individual SLAs, and so on. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.metrics.micrometer.MicrometerMetricsConfig.timers) */ public fun timers(block: Timer.Builder.(ApplicationCall, Throwable?) -> Unit) { timerBuilder = block @@ -109,6 +128,8 @@ public class MicrometerMetricsConfig { * You can customize these metrics or create new ones. * * You can learn more from [Micrometer metrics](https://ktor.io/docs/micrometer-metrics.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.metrics.micrometer.MicrometerMetrics) */ public val MicrometerMetrics: ApplicationPlugin = createApplicationPlugin("MicrometerMetrics", ::MicrometerMetricsConfig) { diff --git a/ktor-server/ktor-server-plugins/ktor-server-metrics/jvm/src/io/ktor/server/metrics/dropwizard/DropwizardMetrics.kt b/ktor-server/ktor-server-plugins/ktor-server-metrics/jvm/src/io/ktor/server/metrics/dropwizard/DropwizardMetrics.kt index 598ac4fa9bb..a033408f2e6 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-metrics/jvm/src/io/ktor/server/metrics/dropwizard/DropwizardMetrics.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-metrics/jvm/src/io/ktor/server/metrics/dropwizard/DropwizardMetrics.kt @@ -16,17 +16,25 @@ import java.util.concurrent.* /** * A configuration for the [DropwizardMetrics] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.metrics.dropwizard.DropwizardMetricsConfig) */ @KtorDsl public class DropwizardMetricsConfig { /** * Specifies the base name (prefix) of Ktor metrics used for monitoring HTTP requests. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.metrics.dropwizard.DropwizardMetricsConfig.baseName) + * * @see [DropwizardMetrics] */ public var baseName: String = name("ktor.calls") /** * Specifies the meter registry for your monitoring system. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.metrics.dropwizard.DropwizardMetricsConfig.registry) + * * @see [DropwizardMetrics] */ public var registry: MetricRegistry = MetricRegistry() @@ -34,6 +42,9 @@ public class DropwizardMetricsConfig { /** * Allows you to configure a set of metrics for monitoring the JVM. * You can disable these metrics by setting this property to `false`. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.metrics.dropwizard.DropwizardMetricsConfig.registerJvmMetricSets) + * * @see [DropwizardMetrics] */ public var registerJvmMetricSets: Boolean = true @@ -44,6 +55,8 @@ public class DropwizardMetricsConfig { * useful information about the server and incoming requests. * * You can learn more from [Dropwizard metrics](https://ktor.io/docs/dropwizard-metrics.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.metrics.dropwizard.DropwizardMetrics) */ public val DropwizardMetrics: ApplicationPlugin = createApplicationPlugin("DropwizardMetrics", ::DropwizardMetricsConfig) { diff --git a/ktor-server/ktor-server-plugins/ktor-server-mustache/jvm/src/io/ktor/server/mustache/Mustache.kt b/ktor-server/ktor-server-plugins/ktor-server-mustache/jvm/src/io/ktor/server/mustache/Mustache.kt index bdcbd64c28c..b306ee09df5 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-mustache/jvm/src/io/ktor/server/mustache/Mustache.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-mustache/jvm/src/io/ktor/server/mustache/Mustache.kt @@ -15,6 +15,9 @@ import java.io.* /** * A response content handled by the [Mustache] plugin. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.mustache.MustacheContent) + * * @param template name that is resolved by Mustache * @param model to be passed during template rendering * @param etag value for the `E-Tag` header (optional) @@ -36,6 +39,8 @@ public class MustacheConfig { * A plugin that allows you to use Mustache templates as views within your application. * Provides the ability to respond with [MustacheContent]. * You can learn more from [Mustache](https://ktor.io/docs/mustache.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.mustache.Mustache) */ public val Mustache: ApplicationPlugin = createApplicationPlugin("Mustache", ::MustacheConfig) { val mustacheFactory = pluginConfig.mustacheFactory diff --git a/ktor-server/ktor-server-plugins/ktor-server-mustache/jvm/src/io/ktor/server/mustache/RespondTemplate.kt b/ktor-server/ktor-server-plugins/ktor-server-mustache/jvm/src/io/ktor/server/mustache/RespondTemplate.kt index 18b366aa867..9241aa09fbf 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-mustache/jvm/src/io/ktor/server/mustache/RespondTemplate.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-mustache/jvm/src/io/ktor/server/mustache/RespondTemplate.kt @@ -11,6 +11,9 @@ import io.ktor.server.response.* /** * Responds with the specified [template] passing a data [model]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.mustache.respondTemplate) + * * @see MustacheContent */ public suspend fun ApplicationCall.respondTemplate( diff --git a/ktor-server/ktor-server-plugins/ktor-server-openapi/jvm/src/io/ktor/server/plugins/openapi/OpenAPI.kt b/ktor-server/ktor-server-plugins/ktor-server-openapi/jvm/src/io/ktor/server/plugins/openapi/OpenAPI.kt index a98584cdc7d..e10b7724fd3 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-openapi/jvm/src/io/ktor/server/plugins/openapi/OpenAPI.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-openapi/jvm/src/io/ktor/server/plugins/openapi/OpenAPI.kt @@ -18,6 +18,8 @@ import java.io.* * * The documentation is generated using [StaticHtml2Codegen] by default. It can be customized using config in [block]. * See [OpenAPIConfig] for more details. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.openapi.openAPI) */ public fun Route.openAPI( path: String, diff --git a/ktor-server/ktor-server-plugins/ktor-server-openapi/jvm/src/io/ktor/server/plugins/openapi/OpenAPIConfig.kt b/ktor-server/ktor-server-plugins/ktor-server-openapi/jvm/src/io/ktor/server/plugins/openapi/OpenAPIConfig.kt index 4eb53a4cf48..b2fcda8ce98 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-openapi/jvm/src/io/ktor/server/plugins/openapi/OpenAPIConfig.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-openapi/jvm/src/io/ktor/server/plugins/openapi/OpenAPIConfig.kt @@ -11,20 +11,28 @@ import io.swagger.v3.parser.core.models.* /** * Configuration for OpenAPI endpoint. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.openapi.OpenAPIConfig) */ public class OpenAPIConfig { /** * Specifies a parser used to parse OpenAPI. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.openapi.OpenAPIConfig.parser) */ public var parser: OpenAPIParser = OpenAPIParser() /** * Specifies options of the OpenAPI generator. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.openapi.OpenAPIConfig.opts) */ public var opts: ClientOptInput = ClientOptInput() /** * Specifies a generator used to generate OpenAPI. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.openapi.OpenAPIConfig.generator) */ public var generator: Generator = DefaultGenerator() @@ -32,11 +40,15 @@ public class OpenAPIConfig { * Specifies a code generator for [OpenAPIConfig]. * * See also [StaticHtml2Codegen], [StaticHtmlCodegen] and etc. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.openapi.OpenAPIConfig.codegen) */ public var codegen: CodegenConfig = StaticHtml2Codegen() /** * Provides access to options of the OpenAPI format parser. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.openapi.OpenAPIConfig.options) */ public var options: ParseOptions = ParseOptions() } diff --git a/ktor-server/ktor-server-plugins/ktor-server-partial-content/common/src/io/ktor/server/plugins/partialcontent/PartialContent.kt b/ktor-server/ktor-server-plugins/ktor-server-partial-content/common/src/io/ktor/server/plugins/partialcontent/PartialContent.kt index fe6e50b2109..f00181ea1d1 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-partial-content/common/src/io/ktor/server/plugins/partialcontent/PartialContent.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-partial-content/common/src/io/ktor/server/plugins/partialcontent/PartialContent.kt @@ -18,6 +18,8 @@ internal val LOGGER = KtorSimpleLogger("io.ktor.server.plugins.partialcontent.Pa /** * A configuration for the [PartialContent] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.partialcontent.PartialContentConfig) */ @KtorDsl public class PartialContentConfig { @@ -25,6 +27,8 @@ public class PartialContentConfig { * Specifies a maximum number of ranges that might be accepted from an HTTP request. * * If an HTTP request specifies more ranges, they will all be merged into a single range. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.partialcontent.PartialContentConfig.maxRangeCount) */ public var maxRangeCount: Int by Delegates.vetoable(10) { _, _, new -> new > 0 || throw IllegalArgumentException("Bad maxRangeCount value $new") @@ -36,6 +40,8 @@ public class PartialContentConfig { * This plugin is useful for streaming content or resuming partial downloads. * * To learn more, see [Partial content](https://ktor.io/docs/partial-content.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.partialcontent.PartialContent) */ public val PartialContent: RouteScopedPlugin = createRouteScopedPlugin( "PartialContent", diff --git a/ktor-server/ktor-server-plugins/ktor-server-pebble/jvm/src/io/ktor/server/pebble/Pebble.kt b/ktor-server/ktor-server-plugins/ktor-server-pebble/jvm/src/io/ktor/server/pebble/Pebble.kt index 78495b8f7fe..3fe507bbba2 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-pebble/jvm/src/io/ktor/server/pebble/Pebble.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-pebble/jvm/src/io/ktor/server/pebble/Pebble.kt @@ -16,6 +16,8 @@ import java.util.* /** * Configuration for the [Pebble] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.pebble.PebbleConfiguration) */ @KtorDsl public class PebbleConfiguration : PebbleEngine.Builder() { @@ -23,6 +25,8 @@ public class PebbleConfiguration : PebbleEngine.Builder() { /** * Allows you to define currently available language translations * must follow IETF BCP 47 language tag string specification + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.pebble.PebbleConfiguration.availableLanguages) */ public var availableLanguages: List? = null } @@ -30,6 +34,9 @@ public class PebbleConfiguration : PebbleEngine.Builder() { /** * A response content handled by the [Pebble] plugin. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.pebble.PebbleContent) + * * @param template name of the template to be resolved by Pebble * @param model which is passed into the template * @param locale which is used to resolve templates (optional) @@ -48,6 +55,8 @@ public class PebbleContent( * A plugin that allows you to use Pebble templates as views within your application. * Provides the ability to respond with [PebbleContent]. * You can learn more from [Pebble](https://ktor.io/docs/pebble.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.pebble.Pebble) */ public val Pebble: ApplicationPlugin = createApplicationPlugin("Pebble", ::PebbleConfiguration) { val engine = pluginConfig.build() diff --git a/ktor-server/ktor-server-plugins/ktor-server-pebble/jvm/src/io/ktor/server/pebble/RespondTemplate.kt b/ktor-server/ktor-server-plugins/ktor-server-pebble/jvm/src/io/ktor/server/pebble/RespondTemplate.kt index 9cee25fd98c..fdb655d46a8 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-pebble/jvm/src/io/ktor/server/pebble/RespondTemplate.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-pebble/jvm/src/io/ktor/server/pebble/RespondTemplate.kt @@ -12,6 +12,9 @@ import java.util.* /** * Responds with the specified [template] passing a data [model]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.pebble.respondTemplate) + * * @see PebbleContent */ public suspend fun ApplicationCall.respondTemplate( diff --git a/ktor-server/ktor-server-plugins/ktor-server-rate-limit/common/src/io/ktor/server/plugins/ratelimit/RateLimit.kt b/ktor-server/ktor-server-plugins/ktor-server-rate-limit/common/src/io/ktor/server/plugins/ratelimit/RateLimit.kt index 8894334db51..48299faea22 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-rate-limit/common/src/io/ktor/server/plugins/ratelimit/RateLimit.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-rate-limit/common/src/io/ktor/server/plugins/ratelimit/RateLimit.kt @@ -33,6 +33,8 @@ internal val RateLimitersForCallKey = /** * A plugin that provides rate limiting for incoming requests. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.ratelimit.RateLimit) */ public val RateLimit: ApplicationPlugin = createApplicationPlugin("RateLimit", ::RateLimitConfig) { val global = pluginConfig.global diff --git a/ktor-server/ktor-server-plugins/ktor-server-rate-limit/common/src/io/ktor/server/plugins/ratelimit/RateLimitConfig.kt b/ktor-server/ktor-server-plugins/ktor-server-rate-limit/common/src/io/ktor/server/plugins/ratelimit/RateLimitConfig.kt index 0d51e287348..2bc805b233b 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-rate-limit/common/src/io/ktor/server/plugins/ratelimit/RateLimitConfig.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-rate-limit/common/src/io/ktor/server/plugins/ratelimit/RateLimitConfig.kt @@ -16,6 +16,8 @@ import kotlin.time.* /** * A config for the [RateLimit] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.ratelimit.RateLimitConfig) */ @KtorDsl public class RateLimitConfig { @@ -25,6 +27,8 @@ public class RateLimitConfig { /** * Registers the Rate-Limit provider that can be used in sub-routes via the [Route.rateLimit] function. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.ratelimit.RateLimitConfig.register) */ public fun register(name: RateLimitName = LIMITER_NAME_EMPTY, block: RateLimitProviderConfig.() -> Unit) { if (providers.containsKey(name)) { @@ -39,6 +43,8 @@ public class RateLimitConfig { /** * Registers the Rate-Limit provider that is applied to a whole application. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.ratelimit.RateLimitConfig.global) */ public fun global(block: RateLimitProviderConfig.() -> Unit) { global = RateLimitProvider( @@ -51,12 +57,16 @@ public class RateLimitConfig { /** * A name of registered [RateLimit] provider. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.ratelimit.RateLimitName) */ @JvmInline public value class RateLimitName(internal val name: String) /** * A config for [RateLimit] provider inside [RateLimiterConfig]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.ratelimit.RateLimitProviderConfig) */ @KtorDsl public class RateLimitProviderConfig(internal val name: RateLimitName) { @@ -84,6 +94,8 @@ public class RateLimitProviderConfig(internal val name: RateLimitName) { /** * Sets [RateLimit] for this provider based on [ApplicationCall] and `key` of this request. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.ratelimit.RateLimitProviderConfig.rateLimiter) */ public fun rateLimiter(provider: (call: ApplicationCall, key: Any) -> RateLimiter) { rateLimiterProvider = provider @@ -91,6 +103,8 @@ public class RateLimitProviderConfig(internal val name: RateLimitName) { /** * Sets [RateLimit] for this provider + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.ratelimit.RateLimitProviderConfig.rateLimiter) */ public fun rateLimiter( limit: Int, @@ -107,6 +121,8 @@ public class RateLimitProviderConfig(internal val name: RateLimitName) { * Sets a function that returns a key for a request. Requests with different keys will have independent Rate-Limits. * Keys should have good equals and hashCode implementations. * By default, the key is a [Unit], so all requests share the same Rate-Limit. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.ratelimit.RateLimitProviderConfig.requestKey) */ public fun requestKey(block: suspend (ApplicationCall) -> Any) { requestKey = block @@ -116,6 +132,8 @@ public class RateLimitProviderConfig(internal val name: RateLimitName) { * Sets a function that returns a weight of a request. * Weight is used to calculate how many tokens are consumed by a request. * By default, weight is always 1. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.ratelimit.RateLimitProviderConfig.requestWeight) */ public fun requestWeight(block: suspend (ApplicationCall, key: Any) -> Int) { requestWeight = block @@ -136,6 +154,8 @@ public class RateLimitProviderConfig(internal val name: RateLimitName) { * if request is declined: * * `Retry-After` time to wait for next limit reset time in seconds + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.ratelimit.RateLimitProviderConfig.modifyResponse) */ public fun modifyResponse(block: (ApplicationCall, RateLimiter.State) -> Unit) { modifyResponse = block diff --git a/ktor-server/ktor-server-plugins/ktor-server-rate-limit/common/src/io/ktor/server/plugins/ratelimit/RateLimiter.kt b/ktor-server/ktor-server-plugins/ktor-server-rate-limit/common/src/io/ktor/server/plugins/ratelimit/RateLimiter.kt index c99b9b5ec81..d6cb3b7580b 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-rate-limit/common/src/io/ktor/server/plugins/ratelimit/RateLimiter.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-rate-limit/common/src/io/ktor/server/plugins/ratelimit/RateLimiter.kt @@ -9,20 +9,28 @@ import kotlin.time.* /** * An interface for rate limiters. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.ratelimit.RateLimiter) */ public interface RateLimiter { /** * Tries to consume the [tokens] amount of tokens and returns state of the rate limiter. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.ratelimit.RateLimiter.tryConsume) */ public suspend fun tryConsume(tokens: Int = 1): State /** * State of the rate limiter. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.ratelimit.RateLimiter.State) */ public sealed class State { /** * Rate limiter has enough tokens. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.ratelimit.RateLimiter.State.Available) */ public class Available( public val remainingTokens: Int, @@ -32,6 +40,8 @@ public interface RateLimiter { /** * Rate limiter is exhausted. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.ratelimit.RateLimiter.State.Exhausted) */ public class Exhausted(public val toWait: Duration) : State() } @@ -39,6 +49,8 @@ public interface RateLimiter { public companion object { /** * An implementation of [RateLimiter] that always has enough tokens and will never be refreshed + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.ratelimit.RateLimiter.Companion.Unlimited) */ public val Unlimited: RateLimiter = object : RateLimiter { override suspend fun tryConsume(tokens: Int): State = @@ -50,6 +62,8 @@ public interface RateLimiter { * and will be refilled every [refillPeriod]. * * Note: [initialSize] parameter is ignored and will be removed in the future. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.ratelimit.RateLimiter.Companion.default) */ public fun default( limit: Int, diff --git a/ktor-server/ktor-server-plugins/ktor-server-rate-limit/common/src/io/ktor/server/plugins/ratelimit/Routing.kt b/ktor-server/ktor-server-plugins/ktor-server-rate-limit/common/src/io/ktor/server/plugins/ratelimit/Routing.kt index aabbb995e2b..e56ac2dc2a5 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-rate-limit/common/src/io/ktor/server/plugins/ratelimit/Routing.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-rate-limit/common/src/io/ktor/server/plugins/ratelimit/Routing.kt @@ -10,6 +10,9 @@ import io.ktor.util.* /** * Creates a route with Rate-Limit rules applied to it. * This function accepts name of RateLimit providers defined in the [RateLimit] plugin configuration. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.ratelimit.rateLimit) + * * @see [RateLimit] * * @param configuration names of RateLimit providers defined in the [RateLimit] plugin configuration. @@ -38,6 +41,9 @@ public fun Route.rateLimit( * A rate-limited route node that is used by the [RateLimit] plugin * and usually created by the [Route.rateLimit] DSL function, so generally there is no need to instantiate it directly * unless you are writing an extension. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.ratelimit.RateLimitRouteSelector) + * * @param name of rate-limit provider to be applied to this route. */ public class RateLimitRouteSelector(public val name: RateLimitName) : RouteSelector() { diff --git a/ktor-server/ktor-server-plugins/ktor-server-request-validation/common/src/io/ktor/server/plugins/requestvalidation/RequestValidation.kt b/ktor-server/ktor-server-plugins/ktor-server-request-validation/common/src/io/ktor/server/plugins/requestvalidation/RequestValidation.kt index 08acff7009c..952d8cb5a8d 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-request-validation/common/src/io/ktor/server/plugins/requestvalidation/RequestValidation.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-request-validation/common/src/io/ktor/server/plugins/requestvalidation/RequestValidation.kt @@ -12,15 +12,21 @@ import kotlinx.io.* /** * A result of validation. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.requestvalidation.ValidationResult) */ public sealed class ValidationResult { /** * A successful result of validation. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.requestvalidation.ValidationResult.Valid) */ public data object Valid : ValidationResult() /** * An unsuccessful result of validation. All errors are stored in the [reasons] list. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.requestvalidation.ValidationResult.Invalid) */ public class Invalid( /** @@ -34,15 +40,21 @@ public sealed class ValidationResult { /** * A validator that should be registered with [RequestValidation] plugin + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.requestvalidation.Validator) */ public interface Validator { /** * Validates the [value]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.requestvalidation.Validator.validate) */ public suspend fun validate(value: Any): ValidationResult /** * Checks if the [value] should be checked by this validator. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.requestvalidation.Validator.filter) */ public fun filter(value: Any): Boolean } @@ -63,6 +75,8 @@ public interface Validator { * } * } * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.requestvalidation.RequestValidation) */ public val RequestValidation: RouteScopedPlugin = createRouteScopedPlugin( "RequestValidation", @@ -97,6 +111,9 @@ public val RequestValidation: RouteScopedPlugin = creat /** * Thrown when validation fails. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.requestvalidation.RequestValidationException) + * * @property value - invalid request body * @property reasons - combined reasons of all validation failures for this request */ diff --git a/ktor-server/ktor-server-plugins/ktor-server-request-validation/common/src/io/ktor/server/plugins/requestvalidation/RequestValidationConfig.kt b/ktor-server/ktor-server-plugins/ktor-server-request-validation/common/src/io/ktor/server/plugins/requestvalidation/RequestValidationConfig.kt index 42fc195541f..ec21bb327d7 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-request-validation/common/src/io/ktor/server/plugins/requestvalidation/RequestValidationConfig.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-request-validation/common/src/io/ktor/server/plugins/requestvalidation/RequestValidationConfig.kt @@ -8,6 +8,8 @@ import kotlin.reflect.* /** * A config for [RequestValidation] plugin + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.requestvalidation.RequestValidationConfig) */ public class RequestValidationConfig { @@ -18,6 +20,8 @@ public class RequestValidationConfig { /** * Enables validation of the request body length matches the [Content-Length] header. * If the length doesn't match, body channel will be cancelled with [IOException]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.requestvalidation.RequestValidationConfig.validateContentLength) */ public fun validateContentLength() { validateContentLength = true @@ -25,6 +29,8 @@ public class RequestValidationConfig { /** * Registers [validator] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.requestvalidation.RequestValidationConfig.validate) */ public fun validate(validator: Validator) { validators.add(validator) @@ -32,6 +38,8 @@ public class RequestValidationConfig { /** * Registers [Validator] that should check instances of a [kClass] using [block] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.requestvalidation.RequestValidationConfig.validate) */ public fun validate(kClass: KClass, block: suspend (T) -> ValidationResult) { val validator = object : Validator { @@ -44,6 +52,8 @@ public class RequestValidationConfig { /** * Registers [Validator] that should check instances of a [T] using [block] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.requestvalidation.RequestValidationConfig.validate) */ public inline fun validate(noinline block: suspend (T) -> ValidationResult) { // `KClass.isInstance` doesn't work for JS, but direct `value is T` works @@ -62,6 +72,8 @@ public class RequestValidationConfig { * validation { check(it is Int); ... } * } * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.requestvalidation.RequestValidationConfig.validate) */ public fun validate(block: ValidatorBuilder.() -> Unit) { val builder = ValidatorBuilder().apply(block) diff --git a/ktor-server/ktor-server-plugins/ktor-server-resources/common/src/io/ktor/server/resources/Resources.kt b/ktor-server/ktor-server-plugins/ktor-server-resources/common/src/io/ktor/server/resources/Resources.kt index 66da2b6669d..afcb3f45c45 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-resources/common/src/io/ktor/server/resources/Resources.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-resources/common/src/io/ktor/server/resources/Resources.kt @@ -42,6 +42,9 @@ import io.ktor.resources.Resources as ResourcesCore * * Client: [Type-safe requests](https://ktor.io/docs/type-safe-request.html) * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.resources.Resources) + * * @see Resource */ public object Resources : BaseApplicationPlugin { @@ -58,6 +61,8 @@ public object Resources : BaseApplicationPlugin Application.href(resource: T): String { return href(plugin(Resources).resourcesFormat, resource) @@ -67,6 +72,8 @@ public inline fun Application.href(resource: T): String { * Constructs a URL for [resource]. * * The class of the [resource] instance **must** be annotated with [Resource]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.resources.href) */ public inline fun Application.href(resource: T, urlBuilder: URLBuilder) { href(plugin(Resources).resourcesFormat, resource, urlBuilder) diff --git a/ktor-server/ktor-server-plugins/ktor-server-resources/common/src/io/ktor/server/resources/Routing.kt b/ktor-server/ktor-server-plugins/ktor-server-resources/common/src/io/ktor/server/resources/Routing.kt index 750a1c36e30..fe8d6159036 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-resources/common/src/io/ktor/server/resources/Routing.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-resources/common/src/io/ktor/server/resources/Routing.kt @@ -16,6 +16,8 @@ import kotlinx.serialization.* * Registers a route [body] for a resource defined by the [T] class. * * A class [T] **must** be annotated with [io.ktor.resources.Resource]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.resources.resource) */ public inline fun Route.resource(noinline body: Route.() -> Unit): Route { val serializer = serializer() @@ -27,6 +29,9 @@ public inline fun Route.resource(noinline body: Route.() -> Un * * A class [T] **must** be annotated with [io.ktor.resources.Resource]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.resources.get) + * * @param body receives an instance of the typed resource [T] as the first parameter. */ public inline fun Route.get( @@ -46,6 +51,9 @@ public inline fun Route.get( * * A class [T] **must** be annotated with [io.ktor.resources.Resource]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.resources.options) + * * @param body receives an instance of the typed resource [T] as the first parameter. */ public inline fun Route.options( @@ -65,6 +73,9 @@ public inline fun Route.options( * * A class [T] **must** be annotated with [io.ktor.resources.Resource]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.resources.head) + * * @param body receives an instance of the typed resource [T] as the first parameter. */ public inline fun Route.head( @@ -84,6 +95,9 @@ public inline fun Route.head( * * A class [T] **must** be annotated with [io.ktor.resources.Resource]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.resources.post) + * * @param body receives an instance of the typed resource [T] as the first parameter. */ public inline fun Route.post( @@ -103,6 +117,9 @@ public inline fun Route.post( * * A class [T] **must** be annotated with [io.ktor.resources.Resource]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.resources.post) + * * @param body receives an instance of the typed resource [T] as the first parameter * and typed request body [R] as second parameter. */ @@ -117,6 +134,9 @@ public inline fun Route.post( * * A class [T] **must** be annotated with [io.ktor.resources.Resource]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.resources.put) + * * @param body receives an instance of the typed resource [T] as the first parameter. */ public inline fun Route.put( @@ -136,6 +156,9 @@ public inline fun Route.put( * * A class [T] **must** be annotated with [io.ktor.resources.Resource]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.resources.put) + * * @param body receives an instance of the typed resource [T] as the first parameter * and typed request body [R] as second parameter. */ @@ -150,6 +173,9 @@ public inline fun Route.put( * * A class [T] **must** be annotated with [io.ktor.resources.Resource]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.resources.delete) + * * @param body receives an instance of the typed resource [T] as the first parameter. */ public inline fun Route.delete( @@ -169,6 +195,9 @@ public inline fun Route.delete( * * A class [T] **must** be annotated with [io.ktor.resources.Resource]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.resources.patch) + * * @param body receives an instance of the typed resource [T] as the first parameter. */ public inline fun Route.patch( @@ -188,6 +217,9 @@ public inline fun Route.patch( * * A class [T] **must** be annotated with [io.ktor.resources.Resource]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.resources.patch) + * * @param body receives an instance of the typed resource [T] as the first parameter * and typed request body [R] as second parameter. */ @@ -200,6 +232,9 @@ public inline fun Route.patch( /** * Registers a handler [body] for a resource defined by the [T] class. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.resources.handle) + * * @param body receives an instance of the typed resource [T] as the first parameter. */ public inline fun Route.handle( @@ -215,6 +250,9 @@ internal val ResourceInstanceKey: AttributeKey = AttributeKey("ResourceInst /** * Registers a route [body] for a resource defined by the [T] class. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.resources.resource) + * * @param serializer is used to decode the parameters of the request to an instance of the typed resource [T]. * * A class [T] **must** be annotated with [io.ktor.resources.Resource]. @@ -241,6 +279,9 @@ public fun Route.resource( /** * Registers a handler [body] for a resource defined by the [T] class. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.resources.handle) + * * @param serializer is used to decode the parameters of the request to an instance of the typed resource [T]. * @param body receives an instance of the typed resource [T] as the first parameter. */ diff --git a/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/Cache.kt b/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/Cache.kt index 33bb59dc787..ba96b37455f 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/Cache.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/Cache.kt @@ -10,31 +10,43 @@ import kotlin.coroutines.* /** * A cache for [CookieStorage] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.Cache) */ public interface Cache { /** * Returns value for [key] or computes ans saves it if it's not found in the cache. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.Cache.getOrCompute) */ public suspend fun getOrCompute(key: K): V /** * Returns value for [key] or `null` if it's not found in the cache. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.Cache.peek) */ public fun peek(key: K): V? /** * Invalidates [key] in the cache. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.Cache.invalidate) */ public fun invalidate(key: K): V? /** * Invalidates [key] in this cache if its value equals to [value]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.Cache.invalidate) */ public fun invalidate(key: K, value: V): Boolean /** * Invalidates all keys in the cache. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.Cache.invalidateAll) */ public fun invalidateAll() } diff --git a/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/CacheStorage.kt b/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/CacheStorage.kt index 29628633cbf..e6576cd43eb 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/CacheStorage.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/CacheStorage.kt @@ -6,6 +6,8 @@ package io.ktor.server.sessions /** * A caching storage for sessions. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.CacheStorage) */ public class CacheStorage( public val delegate: SessionStorage, diff --git a/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/KotlinTimeJvm.kt b/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/KotlinTimeJvm.kt index 8466998ef97..0544089af06 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/KotlinTimeJvm.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/KotlinTimeJvm.kt @@ -12,6 +12,8 @@ import kotlin.time.Duration.Companion.seconds * Cookie time to live duration or `null` for session cookies. * Session cookies are client-driven. For example, a web browser usually removes session * cookies at browser or window close unless the session is restored. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.maxAge) */ public var CookieConfiguration.maxAge: Duration? get() = maxAgeInSeconds?.seconds diff --git a/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SameSite.kt b/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SameSite.kt index 98019a0ac09..7e09b9eb496 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SameSite.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SameSite.kt @@ -10,21 +10,29 @@ private const val SameSiteKey: String = "SameSite" /** * String constant options for SameSite cookie attribute. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.SameSite) */ public object SameSite { /** * Only sends cookies from the origin's site. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.SameSite.Strict) */ public const val Strict: String = "Strict" /** * Default behavior. Also sends cookies when navigating to origin site. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.SameSite.Lax) */ public const val Lax: String = "Lax" /** * Also sends cookies from cross-site requests. * Requires Secure attribute to also be set. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.SameSite.None) */ public const val None: String = "None" } @@ -32,6 +40,8 @@ public object SameSite { /** * Cookie configuration extension to supply the "SameSite" attribute for * preventing cross-site request forgery (CSRF) attacks. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.sameSite) */ public var CookieConfiguration.sameSite: String? get() = extensions[SameSiteKey] @@ -41,6 +51,8 @@ public var CookieConfiguration.sameSite: String? /** * Extension for easier access of SameSite attribute. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.sameSite) */ public val Cookie.sameSite: String? get() = extensions[SameSiteKey] diff --git a/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionData.kt b/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionData.kt index 51f819eb81b..559fdc1c247 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionData.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionData.kt @@ -10,6 +10,9 @@ import kotlin.reflect.* /** * Gets a current session or fails if the [Sessions] plugin is not installed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.sessions) + * * @throws MissingApplicationPluginException */ public val ApplicationCall.sessions: CurrentSession @@ -17,28 +20,42 @@ public val ApplicationCall.sessions: CurrentSession /** * A container for all session instances. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.CurrentSession) */ public interface CurrentSession { /** * Sets a new session instance with [name]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.CurrentSession.set) + * * @throws IllegalStateException if no session provider is registered with for [name] */ public fun set(name: String, value: Any?) /** * Gets a session instance for [name] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.CurrentSession.get) + * * @throws IllegalStateException if no session provider is registered with for [name] */ public fun get(name: String): Any? /** * Clears a session instance for [name]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.CurrentSession.clear) + * * @throws IllegalStateException if no session provider is registered with for [name] */ public fun clear(name: String) /** * Finds a session name for the specified [type] or fails if it's not found. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.CurrentSession.findName) + * * @throws IllegalStateException if no session provider registered for [type] */ public fun findName(type: KClass<*>): String @@ -59,24 +76,36 @@ internal interface StatefulSession : CurrentSession { /** * Sets a session instance with the type [T]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.set) + * * @throws IllegalStateException if no session provider is registered for the type [T] */ public inline fun CurrentSession.set(value: T?): Unit = set(value, T::class) /** * Sets a session instance with the type [T]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.set) + * * @throws IllegalStateException if no session provider is registered for the type [T] */ public fun CurrentSession.set(value: T?, klass: KClass): Unit = set(findName(klass), value) /** * Gets a session instance with the type [T]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.get) + * * @throws IllegalStateException if no session provider is registered for the type [T] */ public inline fun CurrentSession.get(): T? = get(T::class) /** * Gets a session instance with the type [T]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.get) + * * @throws IllegalStateException if no session provider is registered for the type [T] */ @Suppress("UNCHECKED_CAST") @@ -84,18 +113,27 @@ public fun CurrentSession.get(klass: KClass): T? = get(findName(kla /** * Clears a session instance with the type [T]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.clear) + * * @throws IllegalStateException if no session provider is registered for the type [T] */ public inline fun CurrentSession.clear(): Unit = clear(T::class) /** * Clears a session instance with the type [T]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.clear) + * * @throws IllegalStateException if no session provider is registered for the type [T] */ public fun CurrentSession.clear(klass: KClass): Unit = clear(findName(klass)) /** * Gets or generates a new session instance using [generator] with the type [T] (or [name] if specified) + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.getOrSet) + * * @throws IllegalStateException if no session provider is registered for the type [T] (or [name] if specified) */ public inline fun CurrentSession.getOrSet(name: String = findName(T::class), generator: () -> T): T { @@ -201,6 +239,8 @@ private fun ApplicationCall.reportMissingSession(): Nothing { /** * Thrown when an HTTP response has already been sent but an attempt to modify the session is made. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.TooLateSessionSetException) */ public class TooLateSessionSetException : IllegalStateException("It's too late to set session: response most likely already has been sent") @@ -209,6 +249,8 @@ public class TooLateSessionSetException : * Thrown when a session is asked too early before the [Sessions] plugin had chance to configure it. * For example, in a phase before [ApplicationCallPipeline.Plugins] or in a plugin installed before [Sessions] into * the same phase. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.SessionNotYetConfiguredException) */ public class SessionNotYetConfiguredException : IllegalStateException("Sessions are not yet ready: you are asking it to early before the Sessions plugin.") diff --git a/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionIdProvider.kt b/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionIdProvider.kt index 50a02d87d47..7ccd66762f3 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionIdProvider.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionIdProvider.kt @@ -8,5 +8,7 @@ import io.ktor.util.* /** * Generates a secure random session ID + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.generateSessionId) */ public fun generateSessionId(): String = generateNonce() + generateNonce() diff --git a/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionProvider.kt b/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionProvider.kt index 32ad8bd2562..3b744e67974 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionProvider.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionProvider.kt @@ -9,6 +9,9 @@ import kotlin.reflect.* /** * Specifies a provider for a session with the specific [name] and [type]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.SessionProvider) + * * @param transport specifies the [SessionTransport] for this provider * @param tracker specifies the [SessionTracker] for this provider * @property name session name diff --git a/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionSerializer.kt b/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionSerializer.kt index cd06c1f61f9..574151c6082 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionSerializer.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionSerializer.kt @@ -12,28 +12,39 @@ import kotlin.reflect.* /** * Serializes a session data from and to [String]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.SessionSerializer) + * * @see [Sessions] */ public interface SessionSerializer { /** * Serializes a complex arbitrary object into a [String]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.SessionSerializer.serialize) */ public fun serialize(session: T): String /** * Deserializes a complex arbitrary object from a [String]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.SessionSerializer.deserialize) */ public fun deserialize(text: String): T } /** * Creates the default [SessionSerializer] for the type [T]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.defaultSessionSerializer) */ public inline fun defaultSessionSerializer(): SessionSerializer = defaultSessionSerializer(typeOf()) /** * Creates the default [SessionSerializer] by [typeInfo]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.defaultSessionSerializer) */ @Suppress("UNCHECKED_CAST") public fun defaultSessionSerializer(typeInfo: KType): SessionSerializer = diff --git a/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionStorage.kt b/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionStorage.kt index 6932ecc56d8..3d6b289d4b0 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionStorage.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionStorage.kt @@ -7,11 +7,16 @@ package io.ktor.server.sessions /** * A storage that provides the ability to [write], [read], and [invalidate] session data. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.SessionStorage) + * * @see [Sessions] */ public interface SessionStorage { /** * Writes a session [value] for [id]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.SessionStorage.write) */ public suspend fun write(id: String, value: String) @@ -19,6 +24,9 @@ public interface SessionStorage { * Invalidates a session with the [id] identifier. * This method prevents a session [id] from being accessible after this call. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.SessionStorage.invalidate) + * * @throws NoSuchElementException when a session [id] is not found. */ public suspend fun invalidate(id: String) @@ -26,6 +34,9 @@ public interface SessionStorage { /** * Reads a session with the [id] identifier. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.SessionStorage.read) + * * @throws NoSuchElementException when a session [id] is not found. */ public suspend fun read(id: String): String diff --git a/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionStorageMemory.kt b/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionStorageMemory.kt index 580e96bba83..666c649c925 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionStorageMemory.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionStorageMemory.kt @@ -11,6 +11,9 @@ import io.ktor.util.collections.* * * Note that [SessionStorageMemory] is intended for development only. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.SessionStorageMemory) + * * @see [Sessions] */ public class SessionStorageMemory : SessionStorage { diff --git a/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionTracker.kt b/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionTracker.kt index e31322c56bc..206c8f65e60 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionTracker.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionTracker.kt @@ -8,12 +8,17 @@ import io.ktor.server.application.* /** * SessionTracker provides the ability to track and extract session from the call context. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.SessionTracker) */ public interface SessionTracker { /** * Load session value from [transport] string for the specified [call] * * It is recommended to perform lookup asynchronously if there is an external session store + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.SessionTracker.load) + * * @return session instance or null if session was not found */ public suspend fun load(call: ApplicationCall, transport: String?): S? @@ -22,16 +27,22 @@ public interface SessionTracker { * Store session [value] and return respective transport string for the specified [call]. * * Override if there is an existing session. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.SessionTracker.store) */ public suspend fun store(call: ApplicationCall, value: S): String /** * Clear session information + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.SessionTracker.clear) */ public suspend fun clear(call: ApplicationCall) /** * Validate session information + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.SessionTracker.validate) */ public fun validate(value: S) } diff --git a/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionTrackerById.kt b/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionTrackerById.kt index e3bbaefc5df..385c7e27396 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionTrackerById.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionTrackerById.kt @@ -12,6 +12,9 @@ import kotlin.reflect.* * Returns the corresponding session ID for the type [SessionType] or `null` if no session provided. * It will crash if no session provider for type [SessionType] installed or no [Sessions] plugin installed. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.sessionId) + * * @param SessionType to search ID for * @return session id or `null` if no session ID sent by the client */ @@ -23,6 +26,9 @@ public inline fun ApplicationCall.sessionId(): Strin * Returns the corresponding session ID for the type [SessionType] or `null` if no session provided. * It will crash if no session provider for type [SessionType] installed or no [Sessions] plugin installed. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.sessionId) + * * @param SessionType to search ID for * @return session id or `null` if no session ID sent by the client */ @@ -37,6 +43,9 @@ public fun ApplicationCall.sessionId(klass: KClass = mutableMapOf() } diff --git a/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionTransportHeader.kt b/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionTransportHeader.kt index 249a0f78c6a..51c57addd75 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionTransportHeader.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionTransportHeader.kt @@ -12,6 +12,9 @@ import io.ktor.server.response.* * A session transport that sets or gets the specific header [name], * applying/un-applying the specified transforms defined by [transformers]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.SessionTransportHeader) + * * @property name is a header name * @property transformers is a list of registered session transformers */ diff --git a/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionTransportTransformer.kt b/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionTransportTransformer.kt index ab9dbe3070c..515cb733702 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionTransportTransformer.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionTransportTransformer.kt @@ -6,11 +6,16 @@ package io.ktor.server.sessions /** * A transformer used to sign and encrypt session data. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.SessionTransportTransformer) */ public interface SessionTransportTransformer { /** * Untransforms a [transportValue] that represents a transformed session. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.SessionTransportTransformer.transformRead) + * * @return Untransformed value or null */ public fun transformRead(transportValue: String): String? @@ -18,6 +23,9 @@ public interface SessionTransportTransformer { /** * Transforms a [transportValue] that represents session data. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.SessionTransportTransformer.transformWrite) + * * @return Transformed value */ public fun transformWrite(transportValue: String): String @@ -27,6 +35,9 @@ public interface SessionTransportTransformer { * Un-applies a list of session transformations to a [cookieValue] representing a transformed session string. * If any of the unapplication of transformations fail returning a null, this function also returns null. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.transformRead) + * * @return A string representing the original session contents. */ public fun List.transformRead(cookieValue: String?): String? { @@ -37,6 +48,9 @@ public fun List.transformRead(cookieValue: String?) /** * Applies a list of session transformations to a [value] representing session data. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.transformWrite) + * * @return A string containing all the transformations applied. */ public fun List.transformWrite(value: String): String { diff --git a/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/Sessions.kt b/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/Sessions.kt index 4acf0a33833..3ba7c0bb5dc 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/Sessions.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/Sessions.kt @@ -22,6 +22,9 @@ internal val LOGGER = KtorSimpleLogger("io.ktor.server.sessions.Sessions") * sign and encrypt session data and more. * * You can learn more from [Sessions](https://ktor.io/docs/sessions.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.Sessions) + * * @property providers list of session providers */ public val Sessions: RouteScopedPlugin = createRouteScopedPlugin("Sessions", ::SessionsConfig) { diff --git a/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionsBuilder.kt b/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionsBuilder.kt index c3a746ec0cd..5c8379ab299 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionsBuilder.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionsBuilder.kt @@ -10,6 +10,8 @@ import kotlin.reflect.* /** * Configures [Sessions] to pass a session identifier in cookies using the [name] `Set-Cookie` attribute and * store the serialized session's data in the server [storage]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.cookie) */ public inline fun SessionsConfig.cookie(name: String, storage: SessionStorage) { cookie(name, typeInfo(), storage) @@ -18,6 +20,8 @@ public inline fun SessionsConfig.cookie(name: String, storage: /** * Configures [Sessions] to pass a session identifier in cookies using the [name] `Set-Cookie` attribute and * store the serialized session's data in the server [storage]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.cookie) */ public fun SessionsConfig.cookie(name: String, typeInfo: TypeInfo, storage: SessionStorage) { @Suppress("UNCHECKED_CAST") @@ -46,6 +50,8 @@ internal fun SessionsConfig.cookie( * The [block] parameter allows you to configure additional cookie settings, for example: * - add other cookie attributes; * - sign and encrypt session data. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.cookie) */ public inline fun SessionsConfig.cookie( name: String, @@ -61,6 +67,8 @@ public inline fun SessionsConfig.cookie( * The [block] parameter allows you to configure additional cookie settings, for example: * - add other cookie attributes; * - sign and encrypt session data. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.cookie) */ public fun SessionsConfig.cookie( name: String, @@ -79,6 +87,8 @@ public fun SessionsConfig.cookie( /** * Configures [Sessions] to pass a session identifier in a [name] HTTP header and * store the serialized session's data in the server [storage]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.header) */ public inline fun SessionsConfig.header(name: String, storage: SessionStorage) { header(name, typeInfo(), storage) @@ -87,6 +97,8 @@ public inline fun SessionsConfig.header(name: String, storage: /** * Configures [Sessions] to pass a session identifier in a [name] HTTP header and * store the serialized session's data in the server [storage]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.header) */ public fun SessionsConfig.header(name: String, typeInfo: TypeInfo, storage: SessionStorage) { header(name, typeInfo, storage) {} @@ -96,6 +108,8 @@ public fun SessionsConfig.header(name: String, typeInfo: TypeInfo, sto * Configures [Sessions] to pass a session identifier in a [name] HTTP header and * store the serialized session's data in the server [storage]. * The [block] parameter allows you to configure additional settings, for example, sign and encrypt session data. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.header) */ public inline fun SessionsConfig.header( name: String, @@ -109,6 +123,8 @@ public inline fun SessionsConfig.header( * Configures [Sessions] to pass a session identifier in a [name] HTTP header and * store the serialized session's data in the server [storage]. * The [block] parameter allows you to configure additional settings, for example, sign and encrypt session data. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.header) */ public fun SessionsConfig.header( name: String, @@ -147,6 +163,8 @@ internal fun SessionsConfig.header( /** * Configures [Sessions] to pass the serialized session's data in cookies using the [name] `Set-Cookie` attribute. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.cookie) */ public inline fun SessionsConfig.cookie(name: String) { cookie(name, typeInfo()) @@ -154,6 +172,8 @@ public inline fun SessionsConfig.cookie(name: String) { /** * Configures [Sessions] to pass the serialized session's data in cookies using the [name] `Set-Cookie` attribute. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.cookie) */ public fun SessionsConfig.cookie(name: String, typeInfo: TypeInfo) { @Suppress("UNCHECKED_CAST") @@ -178,6 +198,8 @@ public fun SessionsConfig.cookie(name: String, typeInfo: TypeInfo) { * } * } * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.cookie) */ public inline fun SessionsConfig.cookie( name: String, @@ -201,6 +223,8 @@ public inline fun SessionsConfig.cookie( * } * } * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.cookie) */ public fun SessionsConfig.cookie( name: String, @@ -237,6 +261,8 @@ internal fun SessionsConfig.cookie( * } * ``` * On the client side, you need to append this header to each request to get session data. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.header) */ public inline fun SessionsConfig.header(name: String) { header(name, typeInfo()) @@ -252,6 +278,8 @@ public inline fun SessionsConfig.header(name: String) { * } * ``` * On the client side, you need to append this header to each request to get session data. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.header) */ public fun SessionsConfig.header(name: String, typeInfo: TypeInfo) { header(name, typeInfo) {} @@ -260,6 +288,8 @@ public fun SessionsConfig.header(name: String, typeInfo: TypeInfo) { /** * Configures [Sessions] to pass the serialized session's data in a [name] HTTP header. * The [block] parameter allows you to configure additional settings, for example, sign and encrypt session data. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.header) */ public inline fun SessionsConfig.header( name: String, @@ -271,6 +301,8 @@ public inline fun SessionsConfig.header( /** * Configures [Sessions] to pass the serialized session's data in a [name] HTTP header. * The [block] parameter allows you to configure additional settings, for example, sign and encrypt session data. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.header) */ public fun SessionsConfig.header( name: String, @@ -288,6 +320,8 @@ public fun SessionsConfig.header( * A configuration that allows you to configure additional cookie settings for [Sessions], for example: * - add cookie attributes; * - sign and encrypt session data. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.CookieIdSessionBuilder) */ public class CookieIdSessionBuilder @PublishedApi internal constructor( type: KClass, @@ -296,6 +330,8 @@ public class CookieIdSessionBuilder @PublishedApi internal constructor( /** * Registers a function used to generate a session ID. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.CookieIdSessionBuilder.identity) */ public fun identity(f: () -> String) { sessionIdProvider = f @@ -303,6 +339,8 @@ public class CookieIdSessionBuilder @PublishedApi internal constructor( /** * A function used to provide a current session ID. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.CookieIdSessionBuilder.sessionIdProvider) */ public var sessionIdProvider: () -> String = { generateSessionId() } private set @@ -310,6 +348,9 @@ public class CookieIdSessionBuilder @PublishedApi internal constructor( /** * A configuration that allows you to configure additional cookie settings for [Sessions]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.CookieSessionBuilder) + * * @property type - session instance type */ public open class CookieSessionBuilder @@ -323,6 +364,8 @@ internal constructor( /** * Specifies a serializer used to serialize session data. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.CookieSessionBuilder.serializer) */ public var serializer: SessionSerializer set(value) { @@ -334,11 +377,15 @@ internal constructor( /** * Gets transformers used to sign and encrypt session data. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.CookieSessionBuilder.transformers) */ public val transformers: List get() = _transformers /** * Registers a [transformer] used to sign and encrypt session data. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.CookieSessionBuilder.transform) */ public fun transform(transformer: SessionTransportTransformer) { _transformers.add(transformer) @@ -346,12 +393,17 @@ internal constructor( /** * Gets a configuration used to specify additional cookie attributes for [Sessions]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.CookieSessionBuilder.cookie) */ public val cookie: CookieConfiguration = CookieConfiguration() } /** * A configuration that allows you to configure header settings for [Sessions]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.HeaderSessionBuilder) + * * @property type session instance type */ public open class HeaderSessionBuilder @@ -363,6 +415,8 @@ internal constructor( /** * Specifies a serializer used to serialize session data. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.HeaderSessionBuilder.serializer) */ public var serializer: SessionSerializer = defaultSessionSerializer(typeInfo) @@ -370,11 +424,15 @@ internal constructor( /** * Gets transformers used to sign and encrypt session data. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.HeaderSessionBuilder.transformers) */ public val transformers: List get() = _transformers /** * Registers a [transformer] used to sign and encrypt session data. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.HeaderSessionBuilder.transform) */ public fun transform(transformer: SessionTransportTransformer) { _transformers.add(transformer) @@ -383,6 +441,8 @@ internal constructor( /** * A configuration that allows you to configure header settings for [Sessions]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.HeaderIdSessionBuilder) */ public class HeaderIdSessionBuilder @PublishedApi @@ -393,6 +453,8 @@ internal constructor( /** * Registers a function used to generate a session ID. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.HeaderIdSessionBuilder.identity) */ public fun identity(f: () -> String) { sessionIdProvider = f @@ -400,6 +462,8 @@ internal constructor( /** * A function used to provide a current session ID. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.HeaderIdSessionBuilder.sessionIdProvider) */ public var sessionIdProvider: () -> String = { generateSessionId() } private set diff --git a/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionsConfig.kt b/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionsConfig.kt index 1dfec428d51..10422445f20 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionsConfig.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionsConfig.kt @@ -8,6 +8,8 @@ import io.ktor.utils.io.* /** * A configuration for the [Sessions] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.SessionsConfig) */ @KtorDsl public class SessionsConfig { @@ -15,11 +17,15 @@ public class SessionsConfig { /** * Gets a list of session providers to be registered. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.SessionsConfig.providers) */ public val providers: List> get() = registered.toList() /** * Registers a session [provider]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.SessionsConfig.register) */ public fun register(provider: SessionProvider<*>) { registered.firstOrNull { it.name == provider.name }?.let { alreadyRegistered -> diff --git a/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/serialization/KotlinxSessionSerializer.kt b/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/serialization/KotlinxSessionSerializer.kt index 51e46f9df35..92fb3fe0480 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/serialization/KotlinxSessionSerializer.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/serialization/KotlinxSessionSerializer.kt @@ -10,6 +10,8 @@ import kotlinx.serialization.modules.* /** * Returns a [SessionSerializer] based on `kotlinx.serialization` library. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.serialization.KotlinxSessionSerializer) */ @Suppress("FunctionName") public inline fun KotlinxSessionSerializer( @@ -20,6 +22,8 @@ public inline fun KotlinxSessionSerializer( /** * Returns a [SessionSerializer] based on `kotlinx.serialization` library. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.serialization.KotlinxSessionSerializer) */ @Suppress("FunctionName") public fun KotlinxSessionSerializer( @@ -34,6 +38,8 @@ public fun KotlinxSessionSerializer( * that is backward compatible with previous default serializer. * In general, it's discouraged to use this format, and it's recommended to migrate your sessions to another format, * such as JSON + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.serialization.KotlinxBackwardCompatibleSessionSerializer) */ @Suppress("FunctionName") public inline fun KotlinxBackwardCompatibleSessionSerializer( @@ -47,6 +53,8 @@ public inline fun KotlinxBackwardCompatibleSessionSerializer( * that is backward compatible with previous default serializer. * In general, it's discouraged to use this format, and it's recommended to migrate your sessions to another format, * such as JSON + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.serialization.KotlinxBackwardCompatibleSessionSerializer) */ @Suppress("FunctionName") public fun KotlinxBackwardCompatibleSessionSerializer( diff --git a/ktor-server/ktor-server-plugins/ktor-server-sessions/jvm/src/io/ktor/server/sessions/DirectoryStorage.kt b/ktor-server/ktor-server-plugins/ktor-server-sessions/jvm/src/io/ktor/server/sessions/DirectoryStorage.kt index aef550a6a0e..573c3418247 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-sessions/jvm/src/io/ktor/server/sessions/DirectoryStorage.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-sessions/jvm/src/io/ktor/server/sessions/DirectoryStorage.kt @@ -9,6 +9,9 @@ import java.io.* /** * Creates a storage that serializes a session's data to a file under the [rootDir] directory. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.directorySessionStorage) + * * @see [Sessions] */ public fun directorySessionStorage(rootDir: File, cached: Boolean = true): SessionStorage = when (cached) { diff --git a/ktor-server/ktor-server-plugins/ktor-server-sessions/jvm/src/io/ktor/server/sessions/SessionSerializerReflection.kt b/ktor-server/ktor-server-plugins/ktor-server-sessions/jvm/src/io/ktor/server/sessions/SessionSerializerReflection.kt index b098981dbeb..3a967d93bd8 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-sessions/jvm/src/io/ktor/server/sessions/SessionSerializerReflection.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-sessions/jvm/src/io/ktor/server/sessions/SessionSerializerReflection.kt @@ -24,6 +24,9 @@ private const val TYPE_TOKEN_PARAMETER_NAME: String = "\$type" * A reflection-based session serializer. Can be used for backward compatibility with previous versions. * A serialized format is textual and optimized for size as it could be transferred via HTTP headers or cookies. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.reflectionSessionSerializer) + * * @property T is a session instance class handled by this serializer */ public inline fun reflectionSessionSerializer(): SessionSerializer = @@ -33,6 +36,9 @@ public inline fun reflectionSessionSerializer(): SessionSerial * A reflection-based session serializer. Can be used for backward compatibility with previous versions. * A serialized format is textual and optimized for size as it could be transferred via HTTP headers or cookies. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.reflectionSessionSerializer) + * * @property typeInfo is a session instance class handled by this serializer */ public fun reflectionSessionSerializer(typeInfo: KType): SessionSerializer = diff --git a/ktor-server/ktor-server-plugins/ktor-server-sessions/jvm/src/io/ktor/server/sessions/SessionTransportTransformerEncrypt.kt b/ktor-server/ktor-server-plugins/ktor-server-sessions/jvm/src/io/ktor/server/sessions/SessionTransportTransformerEncrypt.kt index 8a9a5a35229..a4d02e64405 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-sessions/jvm/src/io/ktor/server/sessions/SessionTransportTransformerEncrypt.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-sessions/jvm/src/io/ktor/server/sessions/SessionTransportTransformerEncrypt.kt @@ -22,6 +22,9 @@ import javax.crypto.spec.* * You have to provide keys of compatible sizes: 16, 24 and 32 for AES encryption. * For HmacSHA256 it is recommended a key of 32 bytes. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.SessionTransportTransformerEncrypt) + * * @see [Sessions] * * @property encryptionKeySpec is a secret key that is used for encryption @@ -49,6 +52,8 @@ public class SessionTransportTransformerEncrypt( /** * A size of the key used to encrypt session data. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.SessionTransportTransformerEncrypt.encryptionKeySize) */ public val encryptionKeySize: Int get() = encryptionKeySpec.encoded.size diff --git a/ktor-server/ktor-server-plugins/ktor-server-sessions/jvm/src/io/ktor/server/sessions/SessionTransportTransformerMessageAuthentication.kt b/ktor-server/ktor-server-plugins/ktor-server-sessions/jvm/src/io/ktor/server/sessions/SessionTransportTransformerMessageAuthentication.kt index 200d1efc618..add5901796d 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-sessions/jvm/src/io/ktor/server/sessions/SessionTransportTransformerMessageAuthentication.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-sessions/jvm/src/io/ktor/server/sessions/SessionTransportTransformerMessageAuthentication.kt @@ -14,6 +14,9 @@ import javax.crypto.spec.* * This transformer appends an [algorithm] MAC (Message Authentication Code) hash of the session data. * It uses a specified [keySpec] when generating the MAC hash. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sessions.SessionTransportTransformerMessageAuthentication) + * * @see [Sessions] * * @property keySpec is a secret key spec for message authentication diff --git a/ktor-server/ktor-server-plugins/ktor-server-sse/common/src/io/ktor/server/sse/Routing.kt b/ktor-server/ktor-server-plugins/ktor-server-sse/common/src/io/ktor/server/sse/Routing.kt index 8665c97bb2e..20627ebf10c 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-sse/common/src/io/ktor/server/sse/Routing.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-sse/common/src/io/ktor/server/sse/Routing.kt @@ -13,6 +13,9 @@ import io.ktor.util.reflect.* * Adds a route to handle Server-Sent Events (SSE) at the specified [path] using the provided [handler]. * Requires [SSE] plugin to be installed. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sse.sse) + * * @param path A URL path at which to handle Server-Sent Events (SSE) requests. * @param handler A function that defines the behavior of the SSE session. It is invoked when a client connects to the SSE * endpoint. Inside the handler, you can use the functions provided by [ServerSSESessionWithSerialization] @@ -45,6 +48,9 @@ public fun Route.sse(path: String, handler: suspend ServerSSESession.() -> Unit) * Adds a route to handle Server-Sent Events (SSE) using the provided [handler]. * Requires [SSE] plugin to be installed. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sse.sse) + * * @param handler A function that defines the behavior of the SSE session. It is invoked when a client connects to the SSE * endpoint. Inside the handler, you can use the functions provided by [ServerSSESessionWithSerialization] * to send events to the connected clients. @@ -72,6 +78,9 @@ public fun Route.sse(handler: suspend ServerSSESession.() -> Unit): Unit = proce * Adds a route to handle Server-Sent Events (SSE) at the specified [path] using the provided [handler]. * Requires [SSE] plugin to be installed. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sse.sse) + * * @param path A URL path at which to handle Server-Sent Events (SSE) requests. * @param serialize A function to serialize data objects into the `data` field of a `ServerSentEvent`. * @param handler A function that defines the behavior of the SSE session. It is invoked when a client connects to the SSE @@ -111,6 +120,9 @@ public fun Route.sse( * Adds a route to handle Server-Sent Events (SSE) using the provided [handler]. * Requires [SSE] plugin to be installed. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sse.sse) + * * @param serialize A function to serialize data objects into the `data` field of a `ServerSentEvent`. * @param handler A function that defines the behavior of the SSE session. It is invoked when a client connects to the SSE * endpoint. Inside the handler, you can use the functions provided by [ServerSSESessionWithSerialization] diff --git a/ktor-server/ktor-server-plugins/ktor-server-sse/common/src/io/ktor/server/sse/SSE.kt b/ktor-server/ktor-server-plugins/ktor-server-sse/common/src/io/ktor/server/sse/SSE.kt index bf8b558f8fd..52399df61d3 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-sse/common/src/io/ktor/server/sse/SSE.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-sse/common/src/io/ktor/server/sse/SSE.kt @@ -34,5 +34,7 @@ internal val LOGGER = KtorSimpleLogger("io.ktor.server.plugins.sse.SSE") * * To learn more, see [the SSE](https://en.wikipedia.org/wiki/Server-sent_events) * and [the SSE specification](https://html.spec.whatwg.org/multipage/server-sent-events.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sse.SSE) */ public val SSE: ApplicationPlugin = createApplicationPlugin("SSE") {} diff --git a/ktor-server/ktor-server-plugins/ktor-server-sse/common/src/io/ktor/server/sse/SSEServerContent.kt b/ktor-server/ktor-server-plugins/ktor-server-sse/common/src/io/ktor/server/sse/SSEServerContent.kt index 928c78cd28e..81e8a5871a9 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-sse/common/src/io/ktor/server/sse/SSEServerContent.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-sse/common/src/io/ktor/server/sse/SSEServerContent.kt @@ -21,6 +21,9 @@ import kotlinx.coroutines.* * * [handle] function is applied to a session. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sse.SSEServerContent) + * * @param call that is starting SSE session. * @param handle function that is started once SSE session created. */ diff --git a/ktor-server/ktor-server-plugins/ktor-server-sse/common/src/io/ktor/server/sse/ServerSSESession.kt b/ktor-server/ktor-server-plugins/ktor-server-sse/common/src/io/ktor/server/sse/ServerSSESession.kt index 57ca84f8355..c260209ecd5 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-sse/common/src/io/ktor/server/sse/ServerSSESession.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-sse/common/src/io/ktor/server/sse/ServerSSESession.kt @@ -32,22 +32,32 @@ import kotlin.time.Duration.Companion.seconds * To learn more, see [the SSE](https://en.wikipedia.org/wiki/Server-sent_events) * and [the SSE specification](https://html.spec.whatwg.org/multipage/server-sent-events.html). * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sse.ServerSSESession) + * * @see SSE */ public interface ServerSSESession : CoroutineScope { /** * The received [call] that originated this session. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sse.ServerSSESession.call) */ public val call: ApplicationCall /** * Sends a [ServerSentEvent] to the client. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sse.ServerSSESession.send) */ public suspend fun send(event: ServerSentEvent) /** * Creates and sends a [ServerSentEvent] to the client. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sse.ServerSSESession.send) + * * @param data data field of the event. * @param event string identifying the type of event. * @param id event ID. @@ -72,6 +82,8 @@ public interface ServerSSESession : CoroutineScope { * It's important to note that closing the session using this method does not send a termination event * to the client. If you wish to send a specific event to signify the end of the SSE stream * before closing the session, you can use the [send] function for it. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sse.ServerSSESession.close) */ public suspend fun close() } @@ -97,11 +109,16 @@ public interface ServerSSESession : CoroutineScope { * To learn more, see [the SSE](https://en.wikipedia.org/wiki/Server-sent_events) * and [the SSE specification](https://html.spec.whatwg.org/multipage/server-sent-events.html). * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sse.ServerSSESessionWithSerialization) + * * @see SSE */ public interface ServerSSESessionWithSerialization : ServerSSESession { /** * Serializer for transforming data object into field `data` of `ServerSentEvent`. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sse.ServerSSESessionWithSerialization.serializer) */ public val serializer: (TypeInfo, Any) -> String } @@ -140,6 +157,9 @@ public suspend inline fun ServerSSESessionWithSerialization.se * The heartbeat will send the specified [Heartbeat.event] at the specified [Heartbeat.duration] interval * as long as the session is active. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sse.heartbeat) + * * @param heartbeatConfig a lambda that configures the [Heartbeat] object used for the heartbeat. */ public fun ServerSSESession.heartbeat(heartbeatConfig: Heartbeat.() -> Unit) { @@ -159,6 +179,9 @@ internal val heartbeatJobKey = AttributeKey("HeartbeatJobAttributeKey") /** * Represents a heartbeat configuration for a [ServerSSESession]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.sse.Heartbeat) + * * @property duration the duration between heartbeat events, default is 30 seconds. * @property event the [ServerSentEvent] to be sent as the heartbeat, default is a [ServerSentEvent] with the comment "heartbeat". */ diff --git a/ktor-server/ktor-server-plugins/ktor-server-status-pages/common/src/io/ktor/server/plugins/statuspages/StatusPages.kt b/ktor-server/ktor-server-plugins/ktor-server-status-pages/common/src/io/ktor/server/plugins/statuspages/StatusPages.kt index d1c163d7522..802914ee2af 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-status-pages/common/src/io/ktor/server/plugins/statuspages/StatusPages.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-status-pages/common/src/io/ktor/server/plugins/statuspages/StatusPages.kt @@ -21,11 +21,15 @@ private val LOGGER = KtorSimpleLogger("io.ktor.server.plugins.statuspages.Status /** * Specifies how the exception should be handled. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.statuspages.HandlerFunction) */ public typealias HandlerFunction = suspend (call: ApplicationCall, cause: Throwable) -> Unit /** * A plugin that handles exceptions and status codes. Useful to configure default error pages. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.statuspages.StatusPages) */ public val StatusPages: ApplicationPlugin = createApplicationPlugin( "StatusPages", @@ -103,16 +107,22 @@ public val StatusPages: ApplicationPlugin = createApplication /** * A [StatusPages] plugin configuration. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.statuspages.StatusPagesConfig) */ @KtorDsl public class StatusPagesConfig { /** * Provides access to exception handlers of the exception class. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.statuspages.StatusPagesConfig.exceptions) */ public val exceptions: MutableMap, HandlerFunction> = mutableMapOf() /** * Provides access to status handlers based on a status code. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.statuspages.StatusPagesConfig.statuses) */ public val statuses: MutableMap< HttpStatusCode, @@ -124,6 +134,8 @@ public class StatusPagesConfig { /** * Register an exception [handler] for the exception type [T] and its children. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.statuspages.StatusPagesConfig.exception) */ public inline fun exception( noinline handler: suspend (call: ApplicationCall, cause: T) -> Unit @@ -131,6 +143,8 @@ public class StatusPagesConfig { /** * Register an exception [handler] for the exception class [klass] and its children. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.statuspages.StatusPagesConfig.exception) */ public fun exception( klass: KClass, @@ -144,6 +158,8 @@ public class StatusPagesConfig { /** * Register a status [handler] for the [status] code. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.statuspages.StatusPagesConfig.status) */ public fun status( vararg status: HttpStatusCode, @@ -156,6 +172,8 @@ public class StatusPagesConfig { /** * Register a [handler] for the unhandled calls. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.statuspages.StatusPagesConfig.unhandled) */ public fun unhandled(handler: suspend (ApplicationCall) -> Unit) { unhandled = handler @@ -163,6 +181,8 @@ public class StatusPagesConfig { /** * Register a status [handler] for the [status] code. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.statuspages.StatusPagesConfig.status) */ @JvmName("statusWithContext") public fun status( @@ -176,6 +196,8 @@ public class StatusPagesConfig { /** * A context for [status] config method. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.statuspages.StatusPagesConfig.StatusContext) */ public class StatusContext( public val call: ApplicationCall, diff --git a/ktor-server/ktor-server-plugins/ktor-server-status-pages/jvm/src/io/ktor/server/plugins/statuspages/StatusPagesJvm.kt b/ktor-server/ktor-server-plugins/ktor-server-status-pages/jvm/src/io/ktor/server/plugins/statuspages/StatusPagesJvm.kt index 1b082631469..34d2b2351ae 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-status-pages/jvm/src/io/ktor/server/plugins/statuspages/StatusPagesJvm.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-status-pages/jvm/src/io/ktor/server/plugins/statuspages/StatusPagesJvm.kt @@ -12,6 +12,9 @@ import io.ktor.util.pipeline.* /** * Register a status page file(s) using [filePattern] for multiple status [code] list + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.statuspages.statusFile) + * * @param code vararg list of status codes handled by this configuration * @param filePattern path to status file with optional `#` character(s) that will be replaced with numeric status code */ @@ -30,6 +33,8 @@ public fun StatusPagesConfig.statusFile(vararg code: HttpStatusCode, filePattern /** * Register an exception [handler] for the exception class [klass] and its children + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.statuspages.exception) */ public fun StatusPagesConfig.exception( klass: Class, diff --git a/ktor-server/ktor-server-plugins/ktor-server-swagger/jvm/src/io/ktor/server/plugins/swagger/Swagger.kt b/ktor-server/ktor-server-plugins/ktor-server-swagger/jvm/src/io/ktor/server/plugins/swagger/Swagger.kt index 902b11b19cb..6371df9cfb3 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-swagger/jvm/src/io/ktor/server/plugins/swagger/Swagger.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-swagger/jvm/src/io/ktor/server/plugins/swagger/Swagger.kt @@ -20,6 +20,8 @@ import java.io.* * This method tries to lookup [swaggerFile] in the resources first, and if it's not found, it will try to read it from * the file system using [java.io.File]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.swagger.swaggerUI) */ public fun Route.swaggerUI( path: String, @@ -39,6 +41,8 @@ public fun Route.swaggerUI( /** * Creates a `get` endpoint with [SwaggerUI] at [path] rendered from the [apiFile]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.swagger.swaggerUI) */ public fun Route.swaggerUI(path: String, apiFile: File, block: SwaggerConfig.() -> Unit = {}) { if (!apiFile.exists()) { @@ -54,6 +58,9 @@ public fun Route.swaggerUI(path: String, apiFile: File, block: SwaggerConfig.() * * This function sets up a given path to serve a Swagger UI interface based on the provided API specification. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.swagger.swaggerUI) + * * @param path The base path where the Swagger UI will be accessible. * @param apiUrl The relative URL for the Swagger API JSON file. * @param api The content of the Swagger API specification. diff --git a/ktor-server/ktor-server-plugins/ktor-server-swagger/jvm/src/io/ktor/server/plugins/swagger/SwaggerConfig.kt b/ktor-server/ktor-server-plugins/ktor-server-swagger/jvm/src/io/ktor/server/plugins/swagger/SwaggerConfig.kt index d95ddd056ef..7b716535e41 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-swagger/jvm/src/io/ktor/server/plugins/swagger/SwaggerConfig.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-swagger/jvm/src/io/ktor/server/plugins/swagger/SwaggerConfig.kt @@ -6,12 +6,16 @@ package io.ktor.server.plugins.swagger /** * A configuration for the Swagger UI endpoint. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.swagger.SwaggerConfig) */ public class SwaggerConfig { internal var customStyle: String? = null /** * Specifies a Swagger UI version to use. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.swagger.SwaggerConfig.version) */ public var version: String = "5.17.12" @@ -19,6 +23,8 @@ public class SwaggerConfig { * Specifies a URL for a custom CSS applied to a Swagger UI. * * Example: https://unpkg.com/swagger-ui-themes@3.0.1/themes/3.x/theme-monokai.css + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.swagger.SwaggerConfig.customStyle) */ public fun customStyle(path: String?) { customStyle = path @@ -26,6 +32,8 @@ public class SwaggerConfig { /** * Swagger package location + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.swagger.SwaggerConfig.packageLocation) */ public var packageLocation: String = "https://unpkg.com/swagger-ui-dist" @@ -33,6 +41,8 @@ public class SwaggerConfig { * Whether to allow [deep linking in Swagger UI](https://swagger.io/docs/open-source-tools/swagger-ui/usage/deep-linking/). * * Defaults to `false`. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.plugins.swagger.SwaggerConfig.deepLinking) */ public var deepLinking: Boolean = false diff --git a/ktor-server/ktor-server-plugins/ktor-server-thymeleaf/jvm/src/io/ktor/server/thymeleaf/RespondTemplate.kt b/ktor-server/ktor-server-plugins/ktor-server-thymeleaf/jvm/src/io/ktor/server/thymeleaf/RespondTemplate.kt index 58ac260edd0..f24f1f99fd4 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-thymeleaf/jvm/src/io/ktor/server/thymeleaf/RespondTemplate.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-thymeleaf/jvm/src/io/ktor/server/thymeleaf/RespondTemplate.kt @@ -11,6 +11,8 @@ import java.util.* /** * Respond with a [template] applying a data [model]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.thymeleaf.respondTemplate) */ public suspend fun ApplicationCall.respondTemplate( template: String, diff --git a/ktor-server/ktor-server-plugins/ktor-server-thymeleaf/jvm/src/io/ktor/server/thymeleaf/Thymeleaf.kt b/ktor-server/ktor-server-plugins/ktor-server-thymeleaf/jvm/src/io/ktor/server/thymeleaf/Thymeleaf.kt index 3dc22d9ffed..29d469be95a 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-thymeleaf/jvm/src/io/ktor/server/thymeleaf/Thymeleaf.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-thymeleaf/jvm/src/io/ktor/server/thymeleaf/Thymeleaf.kt @@ -16,6 +16,9 @@ import java.util.* /** * A response content handled by the [io.ktor.server.thymeleaf.Thymeleaf] plugin. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.thymeleaf.ThymeleafContent) + * * @param template name that is resolved by Thymeleaf * @param model to be passed during template rendering * @param etag value for the `E-Tag` header (optional) @@ -36,6 +39,8 @@ public class ThymeleafContent( * A plugin that allows you to use Thymeleaf templates as views within your application. * Provides the ability to respond with [ThymeleafContent]. * You can learn more from [Thymeleaf](https://ktor.io/docs/thymeleaf.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.thymeleaf.Thymeleaf) */ public val Thymeleaf: ApplicationPlugin = createApplicationPlugin( "Thymeleaf", diff --git a/ktor-server/ktor-server-plugins/ktor-server-velocity/jvm/src/io/ktor/server/velocity/RespondTemplate.kt b/ktor-server/ktor-server-plugins/ktor-server-velocity/jvm/src/io/ktor/server/velocity/RespondTemplate.kt index a1aa3a1a815..06597a8cf63 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-velocity/jvm/src/io/ktor/server/velocity/RespondTemplate.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-velocity/jvm/src/io/ktor/server/velocity/RespondTemplate.kt @@ -11,6 +11,9 @@ import io.ktor.server.response.* /** * Responds with the specified [template] and data [model]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.velocity.respondTemplate) + * * @see VelocityContent */ public suspend fun ApplicationCall.respondTemplate( diff --git a/ktor-server/ktor-server-plugins/ktor-server-velocity/jvm/src/io/ktor/server/velocity/Velocity.kt b/ktor-server/ktor-server-plugins/ktor-server-velocity/jvm/src/io/ktor/server/velocity/Velocity.kt index 331dc6ce230..49e05d89eb6 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-velocity/jvm/src/io/ktor/server/velocity/Velocity.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-velocity/jvm/src/io/ktor/server/velocity/Velocity.kt @@ -17,6 +17,9 @@ import java.io.* /** * A response content handled by the [io.ktor.server.velocity.Velocity] plugin. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.velocity.VelocityContent) + * * @param template name to be resolved by Velocity * @param model to be passed during template rendering * @param etag value for the `E-Tag` header (optional) @@ -49,6 +52,8 @@ internal fun velocityOutgoingContent( * A plugin that allows you to use Velocity templates as views within your application. * Provides the ability to respond with [VelocityContent]. * You can learn more from [Velocity](https://ktor.io/docs/velocity.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.velocity.Velocity) */ public val Velocity: ApplicationPlugin = createApplicationPlugin("Velocity", ::VelocityEngine) { diff --git a/ktor-server/ktor-server-plugins/ktor-server-velocity/jvm/src/io/ktor/server/velocity/VelocityTools.kt b/ktor-server/ktor-server-plugins/ktor-server-velocity/jvm/src/io/ktor/server/velocity/VelocityTools.kt index c385e0d0683..d429ceaef2e 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-velocity/jvm/src/io/ktor/server/velocity/VelocityTools.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-velocity/jvm/src/io/ktor/server/velocity/VelocityTools.kt @@ -19,6 +19,8 @@ public fun EasyFactoryConfiguration.engine(configure: VelocityEngine.() -> Unit) /** * A plugin that allows you to add standard and custom Velocity tools. * You can learn more from [Velocity](https://ktor.io/docs/velocity.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.velocity.VelocityTools) */ @Suppress("UNCHECKED_CAST") public val VelocityTools: ApplicationPlugin = createApplicationPlugin( diff --git a/ktor-server/ktor-server-plugins/ktor-server-webjars/jvm/src/io/ktor/server/webjars/Webjars.kt b/ktor-server/ktor-server-plugins/ktor-server-webjars/jvm/src/io/ktor/server/webjars/Webjars.kt index 15ba18eec1b..74aa2462c41 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-webjars/jvm/src/io/ktor/server/webjars/Webjars.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-webjars/jvm/src/io/ktor/server/webjars/Webjars.kt @@ -20,6 +20,8 @@ import kotlin.time.Duration.Companion.days /** * A configuration for the [Webjars] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.webjars.WebjarsConfig) */ @KtorDsl public class WebjarsConfig { @@ -30,6 +32,8 @@ public class WebjarsConfig { /** * Specifies a prefix for the path used to serve WebJars assets. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.webjars.WebjarsConfig.path) */ public var path: String = "/webjars/" set(value) { @@ -50,6 +54,8 @@ public class WebjarsConfig { * Return `null` from this block to omit the header. * * Note: for this property to work, you need to install the [ConditionalHeaders] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.webjars.WebjarsConfig.lastModified) */ public fun lastModified(block: (WebJarInfo) -> GMTDate?) { lastModifiedExtractor = block @@ -61,6 +67,8 @@ public class WebjarsConfig { * Return `null` from this block to omit the header. * * Note: for this property to work, you need to install the [ConditionalHeaders] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.webjars.WebjarsConfig.etag) */ public fun etag(block: (WebJarInfo) -> String?) { etagExtractor = block @@ -72,6 +80,8 @@ public class WebjarsConfig { * Return `null` from this block to omit the header. * * Note: for this property to work, you need to install the [CachingHeaders] plugin. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.webjars.WebjarsConfig.maxAge) */ public fun maxAge(block: (WebJarInfo) -> Duration?) { maxAgeExtractor = block @@ -83,6 +93,8 @@ public class WebjarsConfig { * It allows you to package your assets such as JavaScript and CSS libraries as part of your fat JAR. * * To learn more, see [Webjars](https://ktor.io/docs/webjars.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.webjars.Webjars) */ public val Webjars: ApplicationPlugin = createApplicationPlugin("Webjars", ::WebjarsConfig) { val webjarsPrefix = pluginConfig.path diff --git a/ktor-server/ktor-server-plugins/ktor-server-websockets/common/src/io/ktor/server/websocket/Durations.kt b/ktor-server/ktor-server-plugins/ktor-server-websockets/common/src/io/ktor/server/websocket/Durations.kt index b60d449bb0b..d85529d614b 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-websockets/common/src/io/ktor/server/websocket/Durations.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-websockets/common/src/io/ktor/server/websocket/Durations.kt @@ -23,6 +23,9 @@ import kotlin.time.Duration.Companion.milliseconds * } * ``` * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.websocket.WebSockets) + * * @param pingInterval duration between pings or `null` to disable pings. * @param timeout write/ping timeout after that a connection will be closed. * @param maxFrameSize maximum frame that could be received or sent. diff --git a/ktor-server/ktor-server-plugins/ktor-server-websockets/common/src/io/ktor/server/websocket/Routing.kt b/ktor-server/ktor-server-plugins/ktor-server-websockets/common/src/io/ktor/server/websocket/Routing.kt index 171d5a6e94e..b088f9f5c8a 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-websockets/common/src/io/ktor/server/websocket/Routing.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-websockets/common/src/io/ktor/server/websocket/Routing.kt @@ -26,6 +26,8 @@ import kotlinx.coroutines.CancellationException * When a WebSocket session is created, a [handler] lambda will be called with WebSocket session instance on receiver. * Once [handler] function returns, the WebSocket connection will be terminated immediately. For RAW WebSockets * it is important to perform close sequence properly. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.websocket.webSocketRaw) */ public fun Route.webSocketRaw( path: String, @@ -47,6 +49,9 @@ public fun Route.webSocketRaw( * Once [handler] function returns, the WebSocket connection will be terminated immediately. For RAW WebSockets * it is important to perform close sequence properly. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.websocket.webSocketRaw) + * * @param negotiateExtensions indicates if the server should negotiate installed WebSocket extensions. */ public fun Route.webSocketRaw( @@ -73,6 +78,8 @@ public fun Route.webSocketRaw( * When a WebSocket session is created, a [handler] lambda will be called with WebSocket session instance on receiver. * Once [handler] function returns, the WebSocket connection will be terminated immediately. For RAW WebSocket * it is important to perform close sequence properly. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.websocket.webSocketRaw) */ public fun Route.webSocketRaw(protocol: String? = null, handler: suspend WebSocketServerSession.() -> Unit) { webSocketRaw(protocol, negotiateExtensions = false, handler) @@ -90,6 +97,9 @@ public fun Route.webSocketRaw(protocol: String? = null, handler: suspend WebSock * Once [handler] function returns, the WebSocket connection will be terminated immediately. For RAW WebSocket * it is important to perform close sequence properly. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.websocket.webSocketRaw) + * * @param negotiateExtensions indicates if the server should negotiate installed WebSocket extensions. */ public fun Route.webSocketRaw( @@ -123,6 +133,8 @@ public fun Route.webSocketRaw( * Once [handler] function returns, the websocket termination sequence will be scheduled, so you shouldn't use * [DefaultWebSocketSession] anymore. However, WebSocket could live for a while until close sequence completed or * a timeout exceeds. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.websocket.webSocket) */ public fun Route.webSocket( protocol: String? = null, @@ -144,6 +156,8 @@ public fun Route.webSocket( * Once [handler] function returns, the WebSocket termination sequence will be scheduled so you shouldn't use * [DefaultWebSocketSession] anymore. However, WebSocket could live for a while until close sequence completed or * a timeout exceeds. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.websocket.webSocket) */ public fun Route.webSocket( path: String, diff --git a/ktor-server/ktor-server-plugins/ktor-server-websockets/common/src/io/ktor/server/websocket/WebSocketServerSession.kt b/ktor-server/ktor-server-plugins/ktor-server-websockets/common/src/io/ktor/server/websocket/WebSocketServerSession.kt index 505047f83f6..1db2c41ef0a 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-websockets/common/src/io/ktor/server/websocket/WebSocketServerSession.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-websockets/common/src/io/ktor/server/websocket/WebSocketServerSession.kt @@ -15,10 +15,14 @@ import io.ktor.websocket.serialization.* /** * Represents a server-side web socket session + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.websocket.WebSocketServerSession) */ public interface WebSocketServerSession : WebSocketSession { /** * Associated received [call] that originating this session + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.websocket.WebSocketServerSession.call) */ public val call: ApplicationCall } @@ -26,17 +30,24 @@ public interface WebSocketServerSession : WebSocketSession { /** * Represents a server-side web socket session with all default implementations * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.websocket.DefaultWebSocketServerSession) + * * @see DefaultWebSocketSession */ public interface DefaultWebSocketServerSession : DefaultWebSocketSession, WebSocketServerSession /** * An application that started this web socket session + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.websocket.application) */ public val WebSocketServerSession.application: Application get() = call.application /** * Converter for web socket session + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.websocket.converter) */ public val WebSocketServerSession.converter: WebsocketContentConverter? get() = application.plugin(WebSockets).contentConverter @@ -48,6 +59,9 @@ public val WebSocketServerSession.converter: WebsocketContentConverter? * Frames sent after a Close frame are silently ignored. * Note that a Close frame could be sent automatically in reply to a peer's Close frame unless it is a raw WebSocket session. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.websocket.sendSerialized) + * * @param typeInfo Type info of [T]. Can be retrieved with [typeInfo] function. * * @throws WebsocketConverterNotFoundException if no [contentConverter] is found for the [WebSockets] plugin @@ -67,6 +81,9 @@ public suspend fun WebSocketServerSession.sendSerialized(data: Any?, typeInfo: T * Frames sent after a Close frame are silently ignored. * Note that a Close frame could be sent automatically in reply to a peer's Close frame unless it is a raw WebSocket session. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.websocket.sendSerialized) + * * @throws WebsocketConverterNotFoundException if no [contentConverter] is found for the [WebSockets] plugin */ public suspend inline fun WebSocketServerSession.sendSerialized(data: T) { @@ -80,6 +97,9 @@ public suspend inline fun WebSocketServerSession.sendSerialized(data * In this case, [WebsocketDeserializeException.frame] contains the received frame. * May throw [ClosedReceiveChannelException] if a channel was closed * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.websocket.receiveDeserialized) + * * @param typeInfo Type info of [T]. Can be retrieved with [typeInfo] function. * @throws WebsocketConverterNotFoundException if no [contentConverter] is found for the [WebSockets] plugin diff --git a/ktor-server/ktor-server-plugins/ktor-server-websockets/common/src/io/ktor/server/websocket/WebSocketUpgrade.kt b/ktor-server/ktor-server-plugins/ktor-server-websockets/common/src/io/ktor/server/websocket/WebSocketUpgrade.kt index 594721cea63..a36aab08ccc 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-websockets/common/src/io/ktor/server/websocket/WebSocketUpgrade.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-websockets/common/src/io/ktor/server/websocket/WebSocketUpgrade.kt @@ -24,6 +24,9 @@ import kotlin.coroutines.* * [handle] function is applied to a session and as far as it is a RAW session, you should handle all low-level * frames yourself and deal with ping/pongs, timeouts, close frames, frame fragmentation and so on. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.websocket.WebSocketUpgrade) + * * @param call that is starting web socket session * @param protocol web socket negotiated protocol name (optional) * @param installExtensions specifies if WebSocket extensions should be installed in current session. @@ -46,6 +49,9 @@ public class WebSocketUpgrade( * [handle] function is applied to a session and as far as it is a RAW session, you should handle all low-level * frames yourself and deal with ping/pongs, timeouts, close frames, frame fragmentation and so on. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.websocket.WebSocketUpgrade.WebSocketUpgrade) + * * @param call that is starting web socket session * @param protocol web socket negotiated protocol name (optional) * @param handle function that is started once HTTP upgrade complete and the session will end once this function exit diff --git a/ktor-server/ktor-server-plugins/ktor-server-websockets/common/src/io/ktor/server/websocket/WebSockets.kt b/ktor-server/ktor-server-plugins/ktor-server-websockets/common/src/io/ktor/server/websocket/WebSockets.kt index 347917f4c89..1d3386c7a71 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-websockets/common/src/io/ktor/server/websocket/WebSockets.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-websockets/common/src/io/ktor/server/websocket/WebSockets.kt @@ -29,6 +29,9 @@ internal val LOGGER = KtorSimpleLogger("io.ktor.server.websocket.WebSockets") * } * ``` * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.websocket.WebSockets) + * * @param pingIntervalMillis duration between pings or [PINGER_DISABLED] to disable pings. * @param timeoutMillis write/ping timeout after that a connection will be closed. * @param maxFrameSize maximum frame that could be received or sent. @@ -67,6 +70,8 @@ public class WebSockets private constructor( /** * Websockets configuration options + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.websocket.WebSockets.WebSocketOptions) */ @KtorDsl public class WebSocketOptions { @@ -74,31 +79,43 @@ public class WebSockets private constructor( /** * Duration between pings or [PINGER_DISABLED] to disable pings + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.websocket.WebSockets.WebSocketOptions.pingPeriodMillis) */ public var pingPeriodMillis: Long = PINGER_DISABLED /** * write/ping timeout after that a connection will be closed + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.websocket.WebSockets.WebSocketOptions.timeoutMillis) */ public var timeoutMillis: Long = 15_000L /** * Maximum frame that could be received or sent + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.websocket.WebSockets.WebSocketOptions.maxFrameSize) */ public var maxFrameSize: Long = Long.MAX_VALUE /** * Whether masking need to be enabled (useful for security) + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.websocket.WebSockets.WebSocketOptions.masking) */ public var masking: Boolean = false /** * A converter for serialization/deserialization + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.websocket.WebSockets.WebSocketOptions.contentConverter) */ public var contentConverter: WebsocketContentConverter? = null /** * Configure WebSocket extensions. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.websocket.WebSockets.WebSocketOptions.extensions) */ public fun extensions(block: WebSocketExtensionsConfig.() -> Unit) { extensionsConfig.apply(block) @@ -107,12 +124,16 @@ public class WebSockets private constructor( /** * Plugin installation object. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.websocket.WebSockets.Plugin) */ public companion object Plugin : BaseApplicationPlugin { override val key: AttributeKey = AttributeKey("WebSockets") /** * Key for saving configured WebSocket extensions for the specific call. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.websocket.WebSockets.Plugin.EXTENSIONS_KEY) */ public val EXTENSIONS_KEY: AttributeKey>> = AttributeKey("WebSocket extensions") diff --git a/ktor-server/ktor-server-servlet-jakarta/jvm/src/io/ktor/server/servlet/jakarta/Attributes.kt b/ktor-server/ktor-server-servlet-jakarta/jvm/src/io/ktor/server/servlet/jakarta/Attributes.kt index bac26a9a33a..76bcaa0f52e 100644 --- a/ktor-server/ktor-server-servlet-jakarta/jvm/src/io/ktor/server/servlet/jakarta/Attributes.kt +++ b/ktor-server/ktor-server-servlet-jakarta/jvm/src/io/ktor/server/servlet/jakarta/Attributes.kt @@ -12,6 +12,8 @@ import jakarta.servlet.* /** * Provides jakarta.servlet request attributes or fail it the underlying engine is not * servlet-backed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.jakarta.servletRequestAttributes) */ public val ApplicationRequest.servletRequestAttributes: Map get() = call.attributes[servletRequestAttributesKey] diff --git a/ktor-server/ktor-server-servlet-jakarta/jvm/src/io/ktor/server/servlet/jakarta/JAASBridge.kt b/ktor-server/ktor-server-servlet-jakarta/jvm/src/io/ktor/server/servlet/jakarta/JAASBridge.kt index c8a62411436..80cd9918827 100644 --- a/ktor-server/ktor-server-servlet-jakarta/jvm/src/io/ktor/server/servlet/jakarta/JAASBridge.kt +++ b/ktor-server/ktor-server-servlet-jakarta/jvm/src/io/ktor/server/servlet/jakarta/JAASBridge.kt @@ -10,6 +10,8 @@ import java.security.* /** * Returns Java's JAAS Principal + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.jakarta.javaSecurityPrincipal) */ public val ApplicationRequest.javaSecurityPrincipal: Principal? get() = when (this) { diff --git a/ktor-server/ktor-server-servlet-jakarta/jvm/src/io/ktor/server/servlet/jakarta/KtorServlet.kt b/ktor-server/ktor-server-servlet-jakarta/jvm/src/io/ktor/server/servlet/jakarta/KtorServlet.kt index ff558c53cbc..adca0cf37c7 100644 --- a/ktor-server/ktor-server-servlet-jakarta/jvm/src/io/ktor/server/servlet/jakarta/KtorServlet.kt +++ b/ktor-server/ktor-server-servlet-jakarta/jvm/src/io/ktor/server/servlet/jakarta/KtorServlet.kt @@ -18,6 +18,8 @@ import kotlin.coroutines.* /** * A base class for servlet engine implementations + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.jakarta.KtorServlet) */ public abstract class KtorServlet : HttpServlet(), CoroutineScope { /** @@ -52,6 +54,8 @@ public abstract class KtorServlet : HttpServlet(), CoroutineScope { /** * Called by the servlet container when loading the servlet (on load) + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.jakarta.KtorServlet.init) */ override fun init() { super.init() @@ -60,6 +64,8 @@ public abstract class KtorServlet : HttpServlet(), CoroutineScope { /** * Called by servlet container when the application is going to be undeployed or stopped. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.jakarta.KtorServlet.destroy) */ override fun destroy() { coroutineContext.cancel() @@ -67,6 +73,8 @@ public abstract class KtorServlet : HttpServlet(), CoroutineScope { /** * Called by the servlet container when an HTTP request received. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.jakarta.KtorServlet.service) */ override fun service(request: HttpServletRequest, response: HttpServletResponse) { if (response.isCommitted) return @@ -149,5 +157,7 @@ public abstract class KtorServlet : HttpServlet(), CoroutineScope { /** * Attribute that is added by ktor servlet to application attributes to hold [ServletContext] instance. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.jakarta.ServletContextAttribute) */ public val ServletContextAttribute: AttributeKey = AttributeKey("servlet-context") diff --git a/ktor-server/ktor-server-servlet-jakarta/jvm/src/io/ktor/server/servlet/jakarta/ServletApplicationEngine.kt b/ktor-server/ktor-server-servlet-jakarta/jvm/src/io/ktor/server/servlet/jakarta/ServletApplicationEngine.kt index 01ebad7c0e5..6aee67391d5 100644 --- a/ktor-server/ktor-server-servlet-jakarta/jvm/src/io/ktor/server/servlet/jakarta/ServletApplicationEngine.kt +++ b/ktor-server/ktor-server-servlet-jakarta/jvm/src/io/ktor/server/servlet/jakarta/ServletApplicationEngine.kt @@ -19,6 +19,8 @@ import kotlin.coroutines.* /** * This servlet need to be installed into a servlet container + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.jakarta.ServletApplicationEngine) */ @MultipartConfig public open class ServletApplicationEngine : KtorServlet() { @@ -107,6 +109,8 @@ public open class ServletApplicationEngine : KtorServlet() { /** * Called by the servlet container when loading the servlet (on load) + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.jakarta.ServletApplicationEngine.init) */ override fun init() { embeddedServer?.start() @@ -123,6 +127,8 @@ public open class ServletApplicationEngine : KtorServlet() { /** * An embedded server instance key. It is not recommended to use unless you are writing * your own servlet application engine implementation + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.jakarta.ServletApplicationEngine.Companion.EnvironmentAttributeKey) */ public const val EnvironmentAttributeKey: String = "_ktor_environment_instance" public const val ApplicationAttributeKey: String = "_ktor_application_instance" @@ -130,6 +136,8 @@ public open class ServletApplicationEngine : KtorServlet() { /** * An application engine pipeline instance key. It is not recommended to use unless you are writing * your own servlet application engine implementation + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.jakarta.ServletApplicationEngine.Companion.ApplicationEnginePipelineAttributeKey) */ public const val ApplicationEnginePipelineAttributeKey: String = "_ktor_application_engine_pipeline_instance" diff --git a/ktor-server/ktor-server-servlet-jakarta/jvm/src/io/ktor/server/servlet/jakarta/ServletUpgrade.kt b/ktor-server/ktor-server-servlet-jakarta/jvm/src/io/ktor/server/servlet/jakarta/ServletUpgrade.kt index 204e902df16..2ab54fd852f 100644 --- a/ktor-server/ktor-server-servlet-jakarta/jvm/src/io/ktor/server/servlet/jakarta/ServletUpgrade.kt +++ b/ktor-server/ktor-server-servlet-jakarta/jvm/src/io/ktor/server/servlet/jakarta/ServletUpgrade.kt @@ -15,10 +15,14 @@ import kotlin.coroutines.* /** * Servlet upgrade processing + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.jakarta.ServletUpgrade) */ public interface ServletUpgrade { /** * Perform HTTP upgrade using engine's native API + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.jakarta.ServletUpgrade.performUpgrade) */ public suspend fun performUpgrade( upgrade: OutgoingContent.ProtocolUpgrade, @@ -32,6 +36,8 @@ public interface ServletUpgrade { /** * The default servlet upgrade implementation using Servlet API. * Please note that some servlet containers may not support it or it may be broken. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.jakarta.DefaultServletUpgrade) */ public object DefaultServletUpgrade : ServletUpgrade { @OptIn(InternalAPI::class) diff --git a/ktor-server/ktor-server-servlet-jakarta/jvm/src/io/ktor/server/servlet/jakarta/WebResources.kt b/ktor-server/ktor-server-servlet-jakarta/jvm/src/io/ktor/server/servlet/jakarta/WebResources.kt index 75f5d22651e..7ed9cef3bb6 100644 --- a/ktor-server/ktor-server-servlet-jakarta/jvm/src/io/ktor/server/servlet/jakarta/WebResources.kt +++ b/ktor-server/ktor-server-servlet-jakarta/jvm/src/io/ktor/server/servlet/jakarta/WebResources.kt @@ -15,27 +15,38 @@ import kotlin.random.* /** * Web resources serve configuration + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.jakarta.WebResourcesConfig) */ public class WebResourcesConfig internal constructor() { /** * Path predicates to be included. All files will be served if no include rules specified. * A path provided to a predicate is always slash-separated (`/`). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.jakarta.WebResourcesConfig.includes) */ public val includes: MutableList<(String) -> Boolean> = mutableListOf() /** * Path predicates to be excluded. By default WEB-INF directory is excluded. * A path provided to a predicate is always slash-separated (`/`). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.jakarta.WebResourcesConfig.excludes) */ public val excludes: MutableList<(String) -> Boolean> = mutableListOf() /** * Content-type resolution, uses [defaultForFileExtension] by default + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.jakarta.WebResourcesConfig.mimeResolve) */ public var mimeResolve: (URL) -> ContentType = { ContentType.defaultForFilePath(it.path) } /** * Add [predicate] to [includes] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.jakarta.WebResourcesConfig.include) + * * @see includes */ public fun include(predicate: (path: String) -> Boolean) { @@ -44,6 +55,9 @@ public class WebResourcesConfig internal constructor() { /** * Add [predicate] exclusion rule to [excludes] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.jakarta.WebResourcesConfig.exclude) + * * @see excludes */ public fun exclude(predicate: (path: String) -> Boolean) { @@ -58,6 +72,9 @@ public class WebResourcesConfig internal constructor() { /** * Serve web resources (usually a directory named webapp containing WEB-INF/web.xml). Note that WEB-INF directory * itself is not served by default. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.jakarta.webResources) + * * @param subPath slash-delimited web resources root path (relative to webapp directory) */ @OptIn(InternalAPI::class) diff --git a/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/Attributes.kt b/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/Attributes.kt index f9bb8f9815a..c6fdd565330 100644 --- a/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/Attributes.kt +++ b/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/Attributes.kt @@ -12,6 +12,8 @@ import javax.servlet.* /** * Provides javax.servlet request attributes or fail it the underlying engine is not * servlet-backed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.servletRequestAttributes) */ public val ApplicationRequest.servletRequestAttributes: Map get() = call.attributes[servletRequestAttributesKey] diff --git a/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/JAASBridge.kt b/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/JAASBridge.kt index 1f24c5d5f24..d01cbd2fae0 100644 --- a/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/JAASBridge.kt +++ b/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/JAASBridge.kt @@ -10,6 +10,8 @@ import java.security.* /** * Returns Java's JAAS Principal + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.javaSecurityPrincipal) */ public val ApplicationRequest.javaSecurityPrincipal: Principal? get() = when (this) { diff --git a/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/KtorServlet.kt b/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/KtorServlet.kt index dddcabcbffa..be76895c885 100644 --- a/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/KtorServlet.kt +++ b/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/KtorServlet.kt @@ -18,6 +18,8 @@ import kotlin.coroutines.* /** * A base class for servlet engine implementations + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.KtorServlet) */ public abstract class KtorServlet : HttpServlet(), CoroutineScope { /** @@ -52,6 +54,8 @@ public abstract class KtorServlet : HttpServlet(), CoroutineScope { /** * Called by the servlet container when loading the servlet (on load) + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.KtorServlet.init) */ override fun init() { super.init() @@ -60,6 +64,8 @@ public abstract class KtorServlet : HttpServlet(), CoroutineScope { /** * Called by servlet container when the application is going to be undeployed or stopped. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.KtorServlet.destroy) */ override fun destroy() { coroutineContext.cancel() @@ -67,6 +73,8 @@ public abstract class KtorServlet : HttpServlet(), CoroutineScope { /** * Called by the servlet container when an HTTP request received. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.KtorServlet.service) */ override fun service(request: HttpServletRequest, response: HttpServletResponse) { if (response.isCommitted) return @@ -149,5 +157,7 @@ public abstract class KtorServlet : HttpServlet(), CoroutineScope { /** * Attribute that is added by ktor servlet to application attributes to hold [ServletContext] instance. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.ServletContextAttribute) */ public val ServletContextAttribute: AttributeKey = AttributeKey("servlet-context") diff --git a/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/ServletApplicationEngine.kt b/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/ServletApplicationEngine.kt index be2881030e8..3050a78c41f 100644 --- a/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/ServletApplicationEngine.kt +++ b/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/ServletApplicationEngine.kt @@ -19,6 +19,8 @@ import kotlin.coroutines.* /** * This servlet need to be installed into a servlet container + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.ServletApplicationEngine) */ @MultipartConfig public open class ServletApplicationEngine : KtorServlet() { @@ -107,6 +109,8 @@ public open class ServletApplicationEngine : KtorServlet() { /** * Called by the servlet container when loading the servlet (on load) + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.ServletApplicationEngine.init) */ override fun init() { embeddedServer?.start() @@ -123,6 +127,8 @@ public open class ServletApplicationEngine : KtorServlet() { /** * An embedded server instance key. It is not recommended to use unless you are writing * your own servlet application engine implementation + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.ServletApplicationEngine.Companion.EnvironmentAttributeKey) */ public const val EnvironmentAttributeKey: String = "_ktor_environment_instance" public const val ApplicationAttributeKey: String = "_ktor_application_instance" @@ -130,6 +136,8 @@ public open class ServletApplicationEngine : KtorServlet() { /** * An application engine pipeline instance key. It is not recommended to use unless you are writing * your own servlet application engine implementation + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.ServletApplicationEngine.Companion.ApplicationEnginePipelineAttributeKey) */ public const val ApplicationEnginePipelineAttributeKey: String = "_ktor_application_engine_pipeline_instance" diff --git a/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/ServletUpgrade.kt b/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/ServletUpgrade.kt index 72c8b3215dc..28fcaabd6b7 100644 --- a/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/ServletUpgrade.kt +++ b/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/ServletUpgrade.kt @@ -15,10 +15,14 @@ import kotlin.coroutines.* /** * Servlet upgrade processing + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.ServletUpgrade) */ public interface ServletUpgrade { /** * Perform HTTP upgrade using engine's native API + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.ServletUpgrade.performUpgrade) */ public suspend fun performUpgrade( upgrade: OutgoingContent.ProtocolUpgrade, @@ -32,6 +36,8 @@ public interface ServletUpgrade { /** * The default servlet upgrade implementation using Servlet API. * Please note that some servlet containers may not support it or it may be broken. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.DefaultServletUpgrade) */ public object DefaultServletUpgrade : ServletUpgrade { @OptIn(InternalAPI::class) diff --git a/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/WebResources.kt b/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/WebResources.kt index babed69df3a..95ce3d1af8d 100644 --- a/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/WebResources.kt +++ b/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/WebResources.kt @@ -14,27 +14,38 @@ import kotlin.random.* /** * Web resources serve configuration + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.WebResourcesConfig) */ public class WebResourcesConfig internal constructor() { /** * Path predicates to be included. All files will be served if no include rules specified. * A path provided to a predicate is always slash-separated (`/`). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.WebResourcesConfig.includes) */ public val includes: MutableList<(String) -> Boolean> = mutableListOf() /** * Path predicates to be excluded. By default WEB-INF directory is excluded. * A path provided to a predicate is always slash-separated (`/`). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.WebResourcesConfig.excludes) */ public val excludes: MutableList<(String) -> Boolean> = mutableListOf() /** * Content-type resolution, uses [defaultForFileExtension] by default + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.WebResourcesConfig.mimeResolve) */ public var mimeResolve: (String) -> ContentType = { ContentType.defaultForFileExtension(it) } /** * Add [predicate] to [includes] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.WebResourcesConfig.include) + * * @see includes */ public fun include(predicate: (path: String) -> Boolean) { @@ -43,6 +54,9 @@ public class WebResourcesConfig internal constructor() { /** * Add [predicate] exclusion rule to [excludes] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.WebResourcesConfig.exclude) + * * @see excludes */ public fun exclude(predicate: (path: String) -> Boolean) { @@ -57,6 +71,9 @@ public class WebResourcesConfig internal constructor() { /** * Serve web resources (usually a directory named webapp containing WEB-INF/web.xml). Note that WEB-INF directory * itself is not served by default. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.servlet.webResources) + * * @param subPath slash-delimited web resources root path (relative to webapp directory) */ @OptIn(InternalAPI::class) diff --git a/ktor-server/ktor-server-test-base/jvm/src/io/ktor/server/test/base/HighLoadHttpGenerator.kt b/ktor-server/ktor-server-test-base/jvm/src/io/ktor/server/test/base/HighLoadHttpGenerator.kt index 0635643cf26..69ffe87f1ae 100644 --- a/ktor-server/ktor-server-test-base/jvm/src/io/ktor/server/test/base/HighLoadHttpGenerator.kt +++ b/ktor-server/ktor-server-test-base/jvm/src/io/ktor/server/test/base/HighLoadHttpGenerator.kt @@ -30,6 +30,8 @@ import kotlin.text.toByteArray * due to long long tasks queue. If server could manage so much requests then * RPS is much higher (up to 10x higher) in this mode * but load generator provides absolutely no diagnostics. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.test.base.HighLoadHttpGenerator) */ class HighLoadHttpGenerator( val host: String, diff --git a/ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/ExpectedTestException.kt b/ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/ExpectedTestException.kt index ce5d67cf18d..930d7abf911 100644 --- a/ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/ExpectedTestException.kt +++ b/ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/ExpectedTestException.kt @@ -6,5 +6,7 @@ package io.ktor.server.testing /** * Exception that is expected to be thrown during test execution. It will not be logged and will not fail the test. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.ExpectedTestException) */ public open class ExpectedTestException(message: String) : Throwable(message) diff --git a/ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/TestApplication.kt b/ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/TestApplication.kt index 8dceb97158f..f905ad1c1a9 100644 --- a/ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/TestApplication.kt +++ b/ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/TestApplication.kt @@ -24,11 +24,16 @@ import kotlin.coroutines.EmptyCoroutineContext /** * A client attached to [TestApplication]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.ClientProvider) */ @KtorDsl public interface ClientProvider { /** * Returns a client with the default configuration. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.ClientProvider.client) + * * @see [testApplication] */ public val client: HttpClient @@ -45,6 +50,9 @@ public interface ClientProvider { * } * } * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.ClientProvider.createClient) + * * @see [testApplication] */ @KtorDsl @@ -53,6 +61,9 @@ public interface ClientProvider { /** * A configured instance of a test application running locally. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.TestApplication) + * * @see [testApplication] */ public class TestApplication internal constructor( @@ -76,6 +87,8 @@ public class TestApplication internal constructor( /** * Starts this [TestApplication] instance. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.TestApplication.start) */ public suspend fun start() { if (state.compareAndSet(State.Created, State.Starting)) { @@ -94,6 +107,8 @@ public class TestApplication internal constructor( /** * Stops this [TestApplication] instance. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.TestApplication.stop) */ public fun stop() { state.value = State.Stopped @@ -106,6 +121,9 @@ public class TestApplication internal constructor( /** * Creates an instance of [TestApplication] configured with the builder [block]. * Make sure to call [TestApplication.stop] after your tests. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.TestApplication) + * * @see [testApplication] */ @KtorDsl @@ -117,6 +135,8 @@ public fun TestApplication( /** * Registers mocks for external services. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.ExternalServicesBuilder) */ @KtorDsl public class ExternalServicesBuilder internal constructor(private val testApplicationBuilder: TestApplicationBuilder) { @@ -128,6 +148,9 @@ public class ExternalServicesBuilder internal constructor(private val testApplic /** * Registers a mock for an external service specified by [hosts] and configured with [block]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.ExternalServicesBuilder.hosts) + * * @see [testApplication] */ @KtorDsl @@ -148,6 +171,8 @@ public class ExternalServicesBuilder internal constructor(private val testApplic /** * A builder for [TestApplication]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.TestApplicationBuilder) */ @KtorDsl public open class TestApplicationBuilder { @@ -189,6 +214,9 @@ public open class TestApplicationBuilder { /** * Builds mocks for external services using [ExternalServicesBuilder]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.TestApplicationBuilder.externalServices) + * * @see [testApplication] */ @KtorDsl @@ -199,6 +227,9 @@ public open class TestApplicationBuilder { /** * Adds a configuration block for the [TestApplicationEngine]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.TestApplicationBuilder.engine) + * * @see [testApplication] */ @KtorDsl @@ -213,6 +244,9 @@ public open class TestApplicationBuilder { /** * Adds a configuration block for the [ServerConfig]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.TestApplicationBuilder.serverConfig) + * * @see [testApplication] */ @KtorDsl @@ -227,6 +261,9 @@ public open class TestApplicationBuilder { /** * Builds an environment using [block]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.TestApplicationBuilder.environment) + * * @see [testApplication] */ @KtorDsl @@ -241,6 +278,9 @@ public open class TestApplicationBuilder { /** * Adds a module to [TestApplication]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.TestApplicationBuilder.application) + * * @see [testApplication] */ @KtorDsl @@ -251,6 +291,8 @@ public open class TestApplicationBuilder { /** * Installs a [plugin] into [TestApplication] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.TestApplicationBuilder.install) */ @Suppress("UNCHECKED_CAST") @KtorDsl @@ -264,6 +306,8 @@ public open class TestApplicationBuilder { /** * Installs routing into [TestApplication] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.TestApplicationBuilder.routing) */ @KtorDsl public fun routing(configuration: Route.() -> Unit) { @@ -281,6 +325,8 @@ public open class TestApplicationBuilder { /** * A builder for a test that uses [TestApplication]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.ApplicationTestBuilder) */ @KtorDsl public class ApplicationTestBuilder : TestApplicationBuilder(), ClientProvider { @@ -301,6 +347,8 @@ public class ApplicationTestBuilder : TestApplicationBuilder(), ClientProvider { * But it's still useful when you need to test your application lifecycle events. * * After calling this method, no modification of the application is allowed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.ApplicationTestBuilder.startApplication) */ public suspend fun startApplication() { application.start() @@ -349,6 +397,8 @@ public class ApplicationTestBuilder : TestApplicationBuilder(), ClientProvider { * [testApplication] loads all modules and properties specified in the configuration file automatically._ * * You can learn more from [Testing](https://ktor.io/docs/testing.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.testApplication) */ @KtorDsl public fun testApplication(block: suspend ApplicationTestBuilder.() -> Unit): TestResult { @@ -386,6 +436,8 @@ public fun testApplication(block: suspend ApplicationTestBuilder.() -> Unit): Te * [testApplication] loads all modules and properties specified in the configuration file automatically. * * You can learn more from [Testing](https://ktor.io/docs/testing.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.testApplication) */ @KtorDsl public fun testApplication( diff --git a/ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/TestApplicationCall.kt b/ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/TestApplicationCall.kt index eb097d98178..a72719ed233 100644 --- a/ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/TestApplicationCall.kt +++ b/ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/TestApplicationCall.kt @@ -11,6 +11,8 @@ import kotlin.coroutines.* /** * A test application call that is used in [TestApplicationEngine]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.TestApplicationCall) */ public class TestApplicationCall( application: Application, diff --git a/ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/TestApplicationEngine.kt b/ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/TestApplicationEngine.kt index 469323c712c..d6345875349 100644 --- a/ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/TestApplicationEngine.kt +++ b/ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/TestApplicationEngine.kt @@ -30,6 +30,8 @@ internal const val CONFIG_KEY_THROW_ON_EXCEPTION = "ktor.test.throwOnException" /** * A test engine that provides a way to simulate application calls to the existing application module(s) * without actual HTTP connection. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.TestApplicationEngine) */ public class TestApplicationEngine( environment: ApplicationEnvironment = createTestEnvironment(), @@ -50,6 +52,9 @@ public class TestApplicationEngine( /** * An engine configuration for a test application. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.TestApplicationEngine.Configuration) + * * @property dispatcher to run handlers and interceptors on */ public class Configuration : BaseApplicationEngine.Configuration() { @@ -76,6 +81,8 @@ public class TestApplicationEngine( /** * An instance of a client engine to be used in [client]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.TestApplicationEngine.engine) */ public val engine: HttpClientEngine = TestHttpClientEngine.create { app = this@TestApplicationEngine } diff --git a/ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/TestApplicationRequest.kt b/ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/TestApplicationRequest.kt index c2fb2abf12d..b659f83d31d 100644 --- a/ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/TestApplicationRequest.kt +++ b/ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/TestApplicationRequest.kt @@ -13,6 +13,9 @@ import kotlinx.coroutines.* /** * A test application request * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.TestApplicationRequest) + * * @property method HTTP method to be sent or executed * @property uri HTTP url to sent request to or was sent to * @property version HTTP version to sent or executed @@ -85,6 +88,8 @@ public class TestApplicationRequest( /** * Request body channel. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.TestApplicationRequest.bodyChannel) */ public var bodyChannel: ByteReadChannel = if (closeRequest) ByteReadChannel.Empty else ByteChannel() @@ -100,6 +105,8 @@ public class TestApplicationRequest( /** * Adds an HTTP request header. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.TestApplicationRequest.addHeader) */ public fun addHeader(name: String, value: String) { val map = headersMap ?: throw Exception("Headers were already acquired for this request") diff --git a/ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/TestApplicationResponse.kt b/ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/TestApplicationResponse.kt index b15b5d3aa4a..936060a83ed 100644 --- a/ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/TestApplicationResponse.kt +++ b/ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/TestApplicationResponse.kt @@ -17,6 +17,9 @@ import kotlin.coroutines.* /** * A test call response received from a server. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.TestApplicationResponse) + * * @property readResponse if response channel need to be consumed into byteContent */ public class TestApplicationResponse( @@ -31,6 +34,8 @@ public class TestApplicationResponse( /** * Response body byte content. Could be blocking. Remains `null` until response appears. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.TestApplicationResponse.byteContent) */ public var byteContent: ByteArray? get() = when { @@ -105,6 +110,8 @@ public class TestApplicationResponse( /** * Gets a response body content channel. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.TestApplicationResponse.contentChannel) */ public fun contentChannel(): ByteReadChannel? = byteContent?.let { ByteReadChannel(it) } @@ -127,6 +134,8 @@ public class TestApplicationResponse( /** * A websocket session's channel. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.TestApplicationResponse.websocketChannel) */ public fun websocketChannel(): ByteReadChannel? = responseChannel } diff --git a/ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/TestEngine.kt b/ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/TestEngine.kt index 457dfed18b8..9bdc3aaabcd 100644 --- a/ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/TestEngine.kt +++ b/ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/TestEngine.kt @@ -12,6 +12,8 @@ import io.ktor.util.logging.* /** * Creates an engine environment for a test application. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.createTestEnvironment) */ public fun createTestEnvironment( configure: ApplicationEnvironmentBuilder.() -> Unit = {} @@ -24,6 +26,8 @@ public fun createTestEnvironment( /** * Starts a test application engine, passes it to the [test] function, and stops it. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.withApplication) */ @Deprecated( "Use new `testApplication` API: https://ktor.io/docs/migration-to-20x.html#testing-api", @@ -48,6 +52,8 @@ public fun withApplication( /** * Starts a test application engine, passes it to the [test] function, and stops it. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.withTestApplication) */ @Deprecated( "Use new `testApplication` API: https://ktor.io/docs/migration-to-20x.html#testing-api", @@ -60,6 +66,8 @@ public fun withTestApplication(test: TestApplicationEngine.() -> R): R { /** * Starts a test application engine, passes it to the [test] function, and stops it. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.withTestApplication) */ @Deprecated( "Use new `testApplication` API: https://ktor.io/docs/migration-to-20x.html#testing-api", @@ -75,6 +83,8 @@ public fun withTestApplication(moduleFunction: Application.() -> Unit, test: /** * Starts a test application engine, passes it to the [test] function, and stops it. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.withTestApplication) */ @Deprecated( "Use new `testApplication` API: https://ktor.io/docs/migration-to-20x.html#testing-api", @@ -94,6 +104,8 @@ public fun withTestApplication( /** * An [ApplicationEngineFactory] providing a CIO-based [ApplicationEngine]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.TestEngine) */ public object TestEngine : ApplicationEngineFactory { diff --git a/ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/Utils.kt b/ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/Utils.kt index d96814f3302..f731e47e1e6 100644 --- a/ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/Utils.kt +++ b/ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/Utils.kt @@ -13,22 +13,30 @@ import io.ktor.network.sockets.SocketTimeoutException as NetworkSocketTimeoutExc /** * [on] function receiver object + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.On) */ public object On /** * [it] function receiver object + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.It) */ public object It /** * DSL for creating a test case + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.on) */ @Suppress("UNUSED_PARAMETER") public inline fun on(comment: String, body: On.() -> Unit): Unit = On.body() /** * DSL function for test case assertions + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.it) */ @Suppress("UNUSED_PARAMETER", "UnusedReceiverParameter") public inline fun On.it(description: String, body: It.() -> Unit): Unit = It.body() diff --git a/ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/client/DelegatingTestClientEngine.kt b/ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/client/DelegatingTestClientEngine.kt index 343ed42aa20..9b957f87e64 100644 --- a/ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/client/DelegatingTestClientEngine.kt +++ b/ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/client/DelegatingTestClientEngine.kt @@ -80,6 +80,8 @@ internal class DelegatingTestClientEngine( /** * Thrown when a request is made to an unknown resource + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.client.InvalidTestRequestException) */ public class InvalidTestRequestException( authority: String, diff --git a/ktor-server/ktor-server-test-suites/jvm/src/io/ktor/server/testing/suites/ClientCertTestSuite.kt b/ktor-server/ktor-server-test-suites/jvm/src/io/ktor/server/testing/suites/ClientCertTestSuite.kt index 5fbaa1c93a9..7086dd6ffb4 100644 --- a/ktor-server/ktor-server-test-suites/jvm/src/io/ktor/server/testing/suites/ClientCertTestSuite.kt +++ b/ktor-server/ktor-server-test-suites/jvm/src/io/ktor/server/testing/suites/ClientCertTestSuite.kt @@ -21,6 +21,8 @@ import kotlin.test.assertEquals /** * This tests uses a CA, which creates server and client certificates. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.testing.suites.ClientCertTestSuite) */ abstract class ClientCertTestSuite( val engine: ApplicationEngineFactory diff --git a/ktor-server/ktor-server-tomcat-jakarta/jvm/src/io/ktor/server/tomcat/jakarta/Embedded.kt b/ktor-server/ktor-server-tomcat-jakarta/jvm/src/io/ktor/server/tomcat/jakarta/Embedded.kt index 0f418a11c38..24a7d96b449 100644 --- a/ktor-server/ktor-server-tomcat-jakarta/jvm/src/io/ktor/server/tomcat/jakarta/Embedded.kt +++ b/ktor-server/ktor-server-tomcat-jakarta/jvm/src/io/ktor/server/tomcat/jakarta/Embedded.kt @@ -10,6 +10,8 @@ import io.ktor.server.engine.* /** * An [ApplicationEngineFactory] providing a Tomcat-based [ApplicationEngine] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.tomcat.jakarta.Tomcat) */ public object Tomcat : ApplicationEngineFactory { diff --git a/ktor-server/ktor-server-tomcat-jakarta/jvm/src/io/ktor/server/tomcat/jakarta/EngineMain.kt b/ktor-server/ktor-server-tomcat-jakarta/jvm/src/io/ktor/server/tomcat/jakarta/EngineMain.kt index 8821fff3db3..b1e1f4d546e 100644 --- a/ktor-server/ktor-server-tomcat-jakarta/jvm/src/io/ktor/server/tomcat/jakarta/EngineMain.kt +++ b/ktor-server/ktor-server-tomcat-jakarta/jvm/src/io/ktor/server/tomcat/jakarta/EngineMain.kt @@ -9,11 +9,15 @@ import io.ktor.server.engine.* /** * Tomcat engine + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.tomcat.jakarta.EngineMain) */ public object EngineMain { /** * Main function for starting EngineMain with Tomcat * Creates an embedded Tomcat application with an environment built from command line arguments. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.tomcat.jakarta.EngineMain.main) */ @JvmStatic public fun main(args: Array) { diff --git a/ktor-server/ktor-server-tomcat-jakarta/jvm/src/io/ktor/server/tomcat/jakarta/TomcatApplicationEngine.kt b/ktor-server/ktor-server-tomcat-jakarta/jvm/src/io/ktor/server/tomcat/jakarta/TomcatApplicationEngine.kt index 96d98127b8f..72e108cbf12 100644 --- a/ktor-server/ktor-server-tomcat-jakarta/jvm/src/io/ktor/server/tomcat/jakarta/TomcatApplicationEngine.kt +++ b/ktor-server/ktor-server-tomcat-jakarta/jvm/src/io/ktor/server/tomcat/jakarta/TomcatApplicationEngine.kt @@ -28,6 +28,8 @@ import kotlin.coroutines.CoroutineContext /** * Tomcat application engine that runs it in embedded mode + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.tomcat.jakarta.TomcatApplicationEngine) */ public class TomcatApplicationEngine( environment: ApplicationEnvironment, @@ -38,11 +40,15 @@ public class TomcatApplicationEngine( ) : BaseApplicationEngine(environment, monitor, developmentMode) { /** * Tomcat engine specific configuration builder + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.tomcat.jakarta.TomcatApplicationEngine.Configuration) */ public class Configuration : BaseApplicationEngine.Configuration() { /** * Property to provide a lambda that will be called * during Tomcat server initialization with the server instance as argument. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.tomcat.jakarta.TomcatApplicationEngine.Configuration.configureTomcat) */ public var configureTomcat: Tomcat.() -> Unit = {} } diff --git a/ktor-server/ktor-server-tomcat-jakarta/jvm/test/io/ktor/tests/server/tomcat/jakarta/TomcatEngineTest.kt b/ktor-server/ktor-server-tomcat-jakarta/jvm/test/io/ktor/tests/server/tomcat/jakarta/TomcatEngineTest.kt index 3589b676ad1..3651305c5e2 100644 --- a/ktor-server/ktor-server-tomcat-jakarta/jvm/test/io/ktor/tests/server/tomcat/jakarta/TomcatEngineTest.kt +++ b/ktor-server/ktor-server-tomcat-jakarta/jvm/test/io/ktor/tests/server/tomcat/jakarta/TomcatEngineTest.kt @@ -48,6 +48,8 @@ class TomcatContentTest : ContentTestSuite) { diff --git a/ktor-server/ktor-server-tomcat/jvm/src/io/ktor/server/tomcat/TomcatApplicationEngine.kt b/ktor-server/ktor-server-tomcat/jvm/src/io/ktor/server/tomcat/TomcatApplicationEngine.kt index 44610ab4bf4..f00d767ff25 100644 --- a/ktor-server/ktor-server-tomcat/jvm/src/io/ktor/server/tomcat/TomcatApplicationEngine.kt +++ b/ktor-server/ktor-server-tomcat/jvm/src/io/ktor/server/tomcat/TomcatApplicationEngine.kt @@ -26,6 +26,8 @@ import kotlin.coroutines.CoroutineContext /** * Tomcat application engine that runs it in embedded mode + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.tomcat.TomcatApplicationEngine) */ public class TomcatApplicationEngine( environment: ApplicationEnvironment, @@ -36,11 +38,15 @@ public class TomcatApplicationEngine( ) : BaseApplicationEngine(environment, monitor, developmentMode) { /** * Tomcat engine specific configuration builder + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.tomcat.TomcatApplicationEngine.Configuration) */ public class Configuration : BaseApplicationEngine.Configuration() { /** * Property to provide a lambda that will be called * during Tomcat server initialization with the server instance as argument. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.tomcat.TomcatApplicationEngine.Configuration.configureTomcat) */ public var configureTomcat: Tomcat.() -> Unit = {} } diff --git a/ktor-server/ktor-server-tomcat/jvm/test/io/ktor/tests/server/tomcat/TomcatEngineTest.kt b/ktor-server/ktor-server-tomcat/jvm/test/io/ktor/tests/server/tomcat/TomcatEngineTest.kt index fad0e990a91..bbeef8cb2b7 100644 --- a/ktor-server/ktor-server-tomcat/jvm/test/io/ktor/tests/server/tomcat/TomcatEngineTest.kt +++ b/ktor-server/ktor-server-tomcat/jvm/test/io/ktor/tests/server/tomcat/TomcatEngineTest.kt @@ -42,6 +42,8 @@ class TomcatContentTest : ContentTestSuite Unit): Unit = diff --git a/ktor-shared/ktor-events/common/src/io/ktor/events/Events.kt b/ktor-shared/ktor-events/common/src/io/ktor/events/Events.kt index 30db37a37e5..414d8cad94c 100644 --- a/ktor-shared/ktor-events/common/src/io/ktor/events/Events.kt +++ b/ktor-shared/ktor-events/common/src/io/ktor/events/Events.kt @@ -16,6 +16,8 @@ public class Events { /** * Subscribe [handler] to an event specified by [definition] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.events.Events.subscribe) */ public fun subscribe(definition: EventDefinition, handler: EventHandler): DisposableHandle { val registration = HandlerRegistration(handler) @@ -25,6 +27,8 @@ public class Events { /** * Unsubscribe [handler] from an event specified by [definition] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.events.Events.unsubscribe) */ public fun unsubscribe(definition: EventDefinition, handler: EventHandler) { handlers[definition]?.forEach { @@ -37,6 +41,8 @@ public class Events { * * Handlers are called in order of subscriptions. * If some handler throws an exception, all remaining handlers will still run. The exception will eventually be re-thrown. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.events.Events.raise) */ public fun raise(definition: EventDefinition, value: T) { var exception: Throwable? = null @@ -60,6 +66,8 @@ public class Events { /** * Raises an event the same way as [Events.raise] but catches an exception and logs it if the [logger] is provided + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.events.raiseCatching) */ public fun Events.raiseCatching(definition: EventDefinition, value: T, logger: Logger? = null) { try { @@ -71,6 +79,8 @@ public fun Events.raiseCatching(definition: EventDefinition, value: T, lo /** * Specifies signature for the event handler + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.events.EventHandler) */ public typealias EventHandler = (T) -> Unit @@ -83,6 +93,9 @@ public typealias EventHandler = (T) -> Unit * Inheriting of this class is an experimental feature. * Instantiate directly if inheritance not necessary. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.events.EventDefinition) + * * @param T specifies what is a type of value passed to the event */ public open class EventDefinition diff --git a/ktor-shared/ktor-resources/common/src/io/ktor/resources/Resource.kt b/ktor-shared/ktor-resources/common/src/io/ktor/resources/Resource.kt index bbbbc28788f..03045d58ed7 100644 --- a/ktor-shared/ktor-resources/common/src/io/ktor/resources/Resource.kt +++ b/ktor-shared/ktor-resources/common/src/io/ktor/resources/Resource.kt @@ -38,6 +38,9 @@ import kotlinx.serialization.* * val addUser = Users.add("new_name") * ``` * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.resources.Resource) + * * @property path the route path, including the class property names wrapped with curly braces. */ @OptIn(ExperimentalSerializationApi::class) diff --git a/ktor-shared/ktor-resources/common/src/io/ktor/resources/ResourceSerializationException.kt b/ktor-shared/ktor-resources/common/src/io/ktor/resources/ResourceSerializationException.kt index 1c4fbef0d2e..733889aa810 100644 --- a/ktor-shared/ktor-resources/common/src/io/ktor/resources/ResourceSerializationException.kt +++ b/ktor-shared/ktor-resources/common/src/io/ktor/resources/ResourceSerializationException.kt @@ -6,5 +6,7 @@ package io.ktor.resources /** * Thrown when [de]serialization of the resource failed + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.resources.ResourceSerializationException) */ public class ResourceSerializationException(message: String) : Exception(message) diff --git a/ktor-shared/ktor-resources/common/src/io/ktor/resources/Resources.kt b/ktor-shared/ktor-resources/common/src/io/ktor/resources/Resources.kt index 92d29bd5fbb..cf5b9969d09 100644 --- a/ktor-shared/ktor-resources/common/src/io/ktor/resources/Resources.kt +++ b/ktor-shared/ktor-resources/common/src/io/ktor/resources/Resources.kt @@ -10,22 +10,30 @@ import kotlinx.serialization.modules.* /** * Resources plugin instance. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.resources.Resources) */ public class Resources(configuration: Configuration) { /** * The format instance used to (de)serialize resources instances + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.resources.Resources.resourcesFormat) */ public val resourcesFormat: ResourcesFormat = ResourcesFormat(configuration.serializersModule) /** * Configuration for the Resources plugin instance. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.resources.Resources.Configuration) */ @KtorDsl public class Configuration { /** * [SerializersModule] used to (de)serialize the Resource instances. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.resources.Resources.Configuration.serializersModule) */ public var serializersModule: SerializersModule = EmptySerializersModule() } diff --git a/ktor-shared/ktor-resources/common/src/io/ktor/resources/UrlBuilder.kt b/ktor-shared/ktor-resources/common/src/io/ktor/resources/UrlBuilder.kt index 66558bc28c1..a81191e16f7 100644 --- a/ktor-shared/ktor-resources/common/src/io/ktor/resources/UrlBuilder.kt +++ b/ktor-shared/ktor-resources/common/src/io/ktor/resources/UrlBuilder.kt @@ -13,6 +13,8 @@ import kotlinx.serialization.* * Constructs a URL for the [resource]. * * The class of the [resource] instance **must** be annotated with [Resource]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.resources.href) */ public inline fun href( resourcesFormat: ResourcesFormat, @@ -27,6 +29,8 @@ public inline fun href( * Constructs a URL for the [resource]. * * The class of the [resource] instance **must** be annotated with [Resource]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.resources.href) */ public inline fun href( resourcesFormat: ResourcesFormat, diff --git a/ktor-shared/ktor-resources/common/src/io/ktor/resources/serialization/ResourcesFormat.kt b/ktor-shared/ktor-resources/common/src/io/ktor/resources/serialization/ResourcesFormat.kt index 235268d2b31..af3c16eb82e 100644 --- a/ktor-shared/ktor-resources/common/src/io/ktor/resources/serialization/ResourcesFormat.kt +++ b/ktor-shared/ktor-resources/common/src/io/ktor/resources/serialization/ResourcesFormat.kt @@ -12,6 +12,8 @@ import kotlinx.serialization.modules.* /** * A format to (de)serialize resources instances + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.resources.serialization.ResourcesFormat) */ @OptIn(ExperimentalSerializationApi::class) public class ResourcesFormat( @@ -20,6 +22,8 @@ public class ResourcesFormat( /** * A query parameter description + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.resources.serialization.ResourcesFormat.Parameter) */ public data class Parameter( val name: String, @@ -28,6 +32,8 @@ public class ResourcesFormat( /** * Builds a path pattern for a given [serializer] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.resources.serialization.ResourcesFormat.encodeToPathPattern) */ public fun encodeToPathPattern(serializer: KSerializer): String { val pathBuilder = StringBuilder() @@ -56,6 +62,8 @@ public class ResourcesFormat( /** * Builds a description of query parameters for a given [serializer] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.resources.serialization.ResourcesFormat.encodeToQueryParameters) */ public fun encodeToQueryParameters(serializer: KSerializer): Set { val path = encodeToPathPattern(serializer) @@ -84,6 +92,8 @@ public class ResourcesFormat( /** * Builds [Parameters] for a resource [T] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.resources.serialization.ResourcesFormat.encodeToParameters) */ public fun encodeToParameters(serializer: KSerializer, value: T): Parameters { val encoder = ParametersEncoder(serializersModule) @@ -93,6 +103,8 @@ public class ResourcesFormat( /** * Builds a [T] resource instance from [parameters] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.resources.serialization.ResourcesFormat.decodeFromParameters) */ public fun decodeFromParameters(deserializer: KSerializer, parameters: Parameters): T { val input = ParametersDecoder(serializersModule, parameters, emptyList()) diff --git a/ktor-shared/ktor-serialization/common/src/ContentConverter.kt b/ktor-shared/ktor-serialization/common/src/ContentConverter.kt index ee28a7eb330..14b1120c057 100644 --- a/ktor-shared/ktor-serialization/common/src/ContentConverter.kt +++ b/ktor-shared/ktor-serialization/common/src/ContentConverter.kt @@ -21,6 +21,8 @@ import kotlinx.coroutines.flow.* * serialization and deserialization * * Implementations must override at least one of [serialize] or [serialize] methods. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.serialization.ContentConverter) */ public interface ContentConverter { @@ -30,6 +32,9 @@ public interface ContentConverter { * other registered converters could be tried or this function could be invoked with other content types * it the converted has been registered multiple times with different content types. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.serialization.ContentConverter.serialize) + * * @param charset response charset * @param typeInfo response body typeInfo * @param contentType to which this data converter has been registered and that matches the client's [Accept] header @@ -47,6 +52,9 @@ public interface ContentConverter { /** * Deserializes [content] to the value of type [typeInfo] * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.serialization.ContentConverter.deserialize) + * * @return a converted value (deserialized) or `null` if the context's subject is not suitable for this converter */ public suspend fun deserialize(charset: Charset, typeInfo: TypeInfo, content: ByteReadChannel): Any? @@ -54,12 +62,16 @@ public interface ContentConverter { /** * Detect suitable charset for an application call by `Accept` header or fallback to [defaultCharset] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.serialization.suitableCharset) */ public fun Headers.suitableCharset(defaultCharset: Charset = Charsets.UTF_8): Charset = suitableCharsetOrNull(defaultCharset) ?: defaultCharset /** * Detect suitable charset for an application call by `Accept` header or fallback to null + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.serialization.suitableCharsetOrNull) */ public fun Headers.suitableCharsetOrNull(defaultCharset: Charset = Charsets.UTF_8): Charset? { for ((charset, _) in parseAndSortHeader(get(HttpHeaders.AcceptCharset))) { @@ -73,6 +85,8 @@ public fun Headers.suitableCharsetOrNull(defaultCharset: Charset = Charsets.UTF_ /** * Configuration for client and server `ContentNegotiation` plugin + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.serialization.Configuration) */ public interface Configuration { diff --git a/ktor-shared/ktor-serialization/common/src/WebsocketContentConverter.kt b/ktor-shared/ktor-serialization/common/src/WebsocketContentConverter.kt index 2cf354658d8..aca1f5795d6 100644 --- a/ktor-shared/ktor-serialization/common/src/WebsocketContentConverter.kt +++ b/ktor-shared/ktor-serialization/common/src/WebsocketContentConverter.kt @@ -16,12 +16,17 @@ import io.ktor.websocket.* * Could provide bi-directional conversion implementation. * One of the most typical examples of the content converter is a JSON converter that provides * both serialization and deserialization + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.serialization.WebsocketContentConverter) */ public interface WebsocketContentConverter { /** * Serializes a [value] to a WebSocket [Frame]. * This function could throw `WebsocketConverterNotFoundException` if the value is not suitable for conversion * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.serialization.WebsocketContentConverter.serialize) + * * @param charset response charset * @param typeInfo response body typeInfo * @param value to be converted @@ -37,6 +42,9 @@ public interface WebsocketContentConverter { /** * Deserializes [content] to the value of type [typeInfo] * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.serialization.WebsocketContentConverter.deserialize) + * * @return a converted value (deserialized) or throws `WebsocketConverterNotFoundException` if the context's * subject is not suitable for this converter */ @@ -45,6 +53,9 @@ public interface WebsocketContentConverter { /** * Checks if the content converter can deserialize a [frame] * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.serialization.WebsocketContentConverter.isApplicable) + * * @param frame a WebSocket frame * * @return true if the content converter can deserialize a [frame] type or false if a type of [frame] @@ -57,6 +68,9 @@ public interface WebsocketContentConverter { * Serializes a [value] to a WebSocket [Frame]. * This function could throw `WebsocketConverterNotFoundException` if the value is not suitable for conversion * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.serialization.serialize) + * * @param charset response charset * @param value to be converted * @@ -70,6 +84,9 @@ public suspend inline fun WebsocketContentConverter.serialize( /** * Deserializes [content] to the value of type [T] * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.serialization.deserialize) + * * @return a converted value (deserialized) or throws `WebsocketConverterNotFoundException` if the context's * subject is not suitable for this converter */ diff --git a/ktor-shared/ktor-serialization/ktor-serialization-gson/jvm/src/GsonConverter.kt b/ktor-shared/ktor-serialization/ktor-serialization-gson/jvm/src/GsonConverter.kt index d5e6abf6259..ab580787a78 100644 --- a/ktor-shared/ktor-serialization/ktor-serialization-gson/jvm/src/GsonConverter.kt +++ b/ktor-shared/ktor-serialization/ktor-serialization-gson/jvm/src/GsonConverter.kt @@ -21,6 +21,9 @@ import kotlin.reflect.* /** * A content converter that uses [Gson] * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.serialization.gson.GsonConverter) + * * @param gson a configured instance of [Gson] */ public class GsonConverter(private val gson: Gson = Gson()) : ContentConverter { @@ -102,6 +105,8 @@ internal class ExcludedTypeGsonException( * Registers the `application/json` content type to the [ContentNegotiation] plugin using GSON. * * You can learn more from [Content negotiation and serialization](https://ktor.io/docs/serialization.html). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.serialization.gson.gson) */ public fun Configuration.gson( contentType: ContentType = ContentType.Application.Json, diff --git a/ktor-shared/ktor-serialization/ktor-serialization-gson/jvm/src/GsonWebsocketContentConverter.kt b/ktor-shared/ktor-serialization/ktor-serialization-gson/jvm/src/GsonWebsocketContentConverter.kt index 00d56dd2aa1..ce1490f461b 100644 --- a/ktor-shared/ktor-serialization/ktor-serialization-gson/jvm/src/GsonWebsocketContentConverter.kt +++ b/ktor-shared/ktor-serialization/ktor-serialization-gson/jvm/src/GsonWebsocketContentConverter.kt @@ -14,6 +14,8 @@ import kotlinx.coroutines.* /** * GSON converter for the [WebSockets] plugin + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.serialization.gson.GsonWebsocketContentConverter) */ public class GsonWebsocketContentConverter(private val gson: Gson = Gson()) : WebsocketContentConverter { override suspend fun serialize(charset: Charset, typeInfo: TypeInfo, value: Any?): Frame { diff --git a/ktor-shared/ktor-serialization/ktor-serialization-jackson/jvm/src/JacksonConverter.kt b/ktor-shared/ktor-serialization/ktor-serialization-jackson/jvm/src/JacksonConverter.kt index b7e5373db50..775609aea1d 100644 --- a/ktor-shared/ktor-serialization/ktor-serialization-jackson/jvm/src/JacksonConverter.kt +++ b/ktor-shared/ktor-serialization/ktor-serialization-jackson/jvm/src/JacksonConverter.kt @@ -23,6 +23,9 @@ import kotlin.text.* /** * A content converter that uses [Jackson] * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.serialization.jackson.JacksonConverter) + * * @param objectMapper a configured instance of [ObjectMapper] * @param streamRequestBody if set to true, will stream request body, without keeping it whole in memory. * This will set `Transfer-Encoding: chunked` header. @@ -147,6 +150,9 @@ public class JacksonConverter( * * You can learn more from [Content negotiation and serialization](https://ktor.io/docs/serialization.html). * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.serialization.jackson.jackson) + * * @param contentType the content type to send with request * @param streamRequestBody if set to true, will stream request body, without keeping it whole in memory. * This will set `Transfer-Encoding: chunked` header. diff --git a/ktor-shared/ktor-serialization/ktor-serialization-jackson/jvm/src/JacksonWebsocketContentConverter.kt b/ktor-shared/ktor-serialization/ktor-serialization-jackson/jvm/src/JacksonWebsocketContentConverter.kt index 8d7c1118ace..8c93cc996c6 100644 --- a/ktor-shared/ktor-serialization/ktor-serialization-jackson/jvm/src/JacksonWebsocketContentConverter.kt +++ b/ktor-shared/ktor-serialization/ktor-serialization-jackson/jvm/src/JacksonWebsocketContentConverter.kt @@ -18,6 +18,8 @@ import java.io.* /** * A jackson converter for the [WebSockets] plugin + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.serialization.jackson.JacksonWebsocketContentConverter) */ public class JacksonWebsocketContentConverter( private val objectmapper: ObjectMapper = jacksonObjectMapper() diff --git a/ktor-shared/ktor-serialization/ktor-serialization-kotlinx/common/src/io/ktor/serialization/kotlinx/Extensions.kt b/ktor-shared/ktor-serialization/ktor-serialization-kotlinx/common/src/io/ktor/serialization/kotlinx/Extensions.kt index 52abd0ad648..3b94ef0d594 100644 --- a/ktor-shared/ktor-serialization/ktor-serialization-kotlinx/common/src/io/ktor/serialization/kotlinx/Extensions.kt +++ b/ktor-shared/ktor-serialization/ktor-serialization-kotlinx/common/src/io/ktor/serialization/kotlinx/Extensions.kt @@ -18,6 +18,8 @@ internal fun extensions(format: SerialFormat): List { val module = this diff --git a/ktor-shared/ktor-serialization/ktor-serialization-kotlinx/ktor-serialization-kotlinx-cbor/common/src/io/ktor/serialization/kotlinx/cbor/CborSupport.kt b/ktor-shared/ktor-serialization/ktor-serialization-kotlinx/ktor-serialization-kotlinx-cbor/common/src/io/ktor/serialization/kotlinx/cbor/CborSupport.kt index 571f4bb4d58..91aca27105f 100644 --- a/ktor-shared/ktor-serialization/ktor-serialization-kotlinx/ktor-serialization-kotlinx-cbor/common/src/io/ktor/serialization/kotlinx/cbor/CborSupport.kt +++ b/ktor-shared/ktor-serialization/ktor-serialization-kotlinx/ktor-serialization-kotlinx-cbor/common/src/io/ktor/serialization/kotlinx/cbor/CborSupport.kt @@ -17,6 +17,8 @@ import kotlin.native.concurrent.* * - defaults are serialized * * See [Cbor] for more details. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.serialization.kotlinx.cbor.DefaultCbor) */ @OptIn(ExperimentalSerializationApi::class) public val DefaultCbor: Cbor = Cbor { @@ -29,6 +31,9 @@ public val DefaultCbor: Cbor = Cbor { * * You can learn more from [Content negotiation and serialization](https://ktor.io/docs/serialization.html). * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.serialization.kotlinx.cbor.cbor) + * * @param cbor format instance (optional) * @param contentType to register with, `application/cbor` by default */ diff --git a/ktor-shared/ktor-serialization/ktor-serialization-kotlinx/ktor-serialization-kotlinx-json/common/src/io/ktor/serialization/kotlinx/json/JsonSupport.kt b/ktor-shared/ktor-serialization/ktor-serialization-kotlinx/ktor-serialization-kotlinx-json/common/src/io/ktor/serialization/kotlinx/json/JsonSupport.kt index cc092401875..8e5cf0fb4e1 100644 --- a/ktor-shared/ktor-serialization/ktor-serialization-kotlinx/ktor-serialization-kotlinx-json/common/src/io/ktor/serialization/kotlinx/json/JsonSupport.kt +++ b/ktor-shared/ktor-serialization/ktor-serialization-kotlinx/ktor-serialization-kotlinx-json/common/src/io/ktor/serialization/kotlinx/json/JsonSupport.kt @@ -20,6 +20,8 @@ import kotlin.native.concurrent.* * - keys and values are quoted, non-quoted are not allowed * * See [Json] for more details. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.serialization.kotlinx.json.DefaultJson) */ public val DefaultJson: Json = @@ -48,6 +50,9 @@ public val DefaultJson: Json = * ``` * You can learn more from [Content negotiation and serialization](https://ktor.io/docs/serialization.html). * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.serialization.kotlinx.json.json) + * * @param json a format instance (optional) * @param contentType to register with, `application/json` by default */ @@ -64,6 +69,9 @@ public fun Configuration.json( * * This uses the experimental JSON support for kotlinx-io to stream content more efficiently. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.serialization.kotlinx.json.jsonIo) + * * @param json A JSON instance used for serialization and deserialization. Defaults to an instance of DefaultJson. * @param contentType The content type to be associated with the JSON converter. Defaults to ContentType.Application.Json. */ diff --git a/ktor-shared/ktor-serialization/ktor-serialization-kotlinx/ktor-serialization-kotlinx-json/common/src/io/ktor/serialization/kotlinx/json/KotlinxSerializationJsonExtensions.kt b/ktor-shared/ktor-serialization/ktor-serialization-kotlinx/ktor-serialization-kotlinx-json/common/src/io/ktor/serialization/kotlinx/json/KotlinxSerializationJsonExtensions.kt index e5da5b1bbd1..9ae2d595a3a 100644 --- a/ktor-shared/ktor-serialization/ktor-serialization-kotlinx/ktor-serialization-kotlinx-json/common/src/io/ktor/serialization/kotlinx/json/KotlinxSerializationJsonExtensions.kt +++ b/ktor-shared/ktor-serialization/ktor-serialization-kotlinx/ktor-serialization-kotlinx-json/common/src/io/ktor/serialization/kotlinx/json/KotlinxSerializationJsonExtensions.kt @@ -19,6 +19,8 @@ import kotlin.reflect.* /** * Adds special handling for receiving [Sequence] and sending [Flow] bodies for the Json format. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.serialization.kotlinx.json.KotlinxSerializationJsonExtensionProvider) */ public class KotlinxSerializationJsonExtensionProvider : KotlinxSerializationExtensionProvider { override fun extension(format: SerialFormat): KotlinxSerializationExtension? { diff --git a/ktor-shared/ktor-serialization/ktor-serialization-kotlinx/ktor-serialization-kotlinx-protobuf/common/src/io/ktor/serialization/kotlinx/protobuf/ProtoBufSupport.kt b/ktor-shared/ktor-serialization/ktor-serialization-kotlinx/ktor-serialization-kotlinx-protobuf/common/src/io/ktor/serialization/kotlinx/protobuf/ProtoBufSupport.kt index fc4ec323d6f..8f32610ddf2 100644 --- a/ktor-shared/ktor-serialization/ktor-serialization-kotlinx/ktor-serialization-kotlinx-protobuf/common/src/io/ktor/serialization/kotlinx/protobuf/ProtoBufSupport.kt +++ b/ktor-shared/ktor-serialization/ktor-serialization-kotlinx/ktor-serialization-kotlinx-protobuf/common/src/io/ktor/serialization/kotlinx/protobuf/ProtoBufSupport.kt @@ -15,6 +15,8 @@ import kotlinx.serialization.protobuf.* * - defaults are serialized * * See [ProtoBuf] for more details. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.serialization.kotlinx.protobuf.DefaultProtoBuf) */ @OptIn(ExperimentalSerializationApi::class) public val DefaultProtoBuf: ProtoBuf = ProtoBuf { @@ -27,6 +29,9 @@ public val DefaultProtoBuf: ProtoBuf = ProtoBuf { * * You can learn more from [Content negotiation and serialization](https://ktor.io/docs/serialization.html). * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.serialization.kotlinx.protobuf.protobuf) + * * @param protobuf format instance (optional) * @param contentType to register with, `application/protobuf` by default */ diff --git a/ktor-shared/ktor-serialization/ktor-serialization-kotlinx/ktor-serialization-kotlinx-xml/common/src/io/ktor/serialization/kotlinx/xml/XmlSupport.kt b/ktor-shared/ktor-serialization/ktor-serialization-kotlinx/ktor-serialization-kotlinx-xml/common/src/io/ktor/serialization/kotlinx/xml/XmlSupport.kt index 598963a10af..88281ac9486 100644 --- a/ktor-shared/ktor-serialization/ktor-serialization-kotlinx/ktor-serialization-kotlinx-xml/common/src/io/ktor/serialization/kotlinx/xml/XmlSupport.kt +++ b/ktor-shared/ktor-serialization/ktor-serialization-kotlinx/ktor-serialization-kotlinx-xml/common/src/io/ktor/serialization/kotlinx/xml/XmlSupport.kt @@ -20,6 +20,8 @@ import nl.adaptivity.xmlutil.serialization.* * - Polymorphic serialization is disabled. * * See [XML] for more details. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.serialization.kotlinx.xml.DefaultXml) */ public val DefaultXml: XML = XML { repairNamespaces = true @@ -34,6 +36,9 @@ public val DefaultXml: XML = XML { * * You can learn more from [Content negotiation and serialization](https://ktor.io/docs/serialization.html). * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.serialization.kotlinx.xml.xml) + * * @param format instance. [DefaultXml] is used by default * @param contentType to register with, `application/xml` by default */ diff --git a/ktor-shared/ktor-sse/common/src/io/ktor/sse/ServerSentEvent.kt b/ktor-shared/ktor-sse/common/src/io/ktor/sse/ServerSentEvent.kt index fe064d38ced..70c6ab2c264 100644 --- a/ktor-shared/ktor-sse/common/src/io/ktor/sse/ServerSentEvent.kt +++ b/ktor-shared/ktor-sse/common/src/io/ktor/sse/ServerSentEvent.kt @@ -9,6 +9,9 @@ import io.ktor.utils.io.* /** * Server-sent event interface. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.sse.ServerSentEventMetadata) + * * @property data data field of the event. * @property event string identifying the type of event. * @property id event ID. @@ -29,6 +32,9 @@ public sealed interface ServerSentEventMetadata { /** * Server-sent event. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.sse.ServerSentEvent) + * * @property data data field of the event. * @property event string identifying the type of event. * @property id event ID. @@ -50,6 +56,9 @@ public data class ServerSentEvent( /** * Server-sent event with generic parameter [data]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.sse.TypedServerSentEvent) + * * @property data data field of the event. * @property event string identifying the type of event. * @property id event ID. diff --git a/ktor-shared/ktor-test-base/common/src/io/ktor/test/TestResult.kt b/ktor-shared/ktor-test-base/common/src/io/ktor/test/TestResult.kt index 2436a14132a..99818134946 100644 --- a/ktor-shared/ktor-test-base/common/src/io/ktor/test/TestResult.kt +++ b/ktor-shared/ktor-test-base/common/src/io/ktor/test/TestResult.kt @@ -12,6 +12,9 @@ internal expect val DummyTestResult: TestResult /** * Executes the provided [block] after the test. * It is the only way to execute something **after** test on JS/WasmJS targets. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.test.andThen) + * * @see TestResult */ expect inline fun TestResult.andThen(crossinline block: () -> Any): TestResult @@ -32,6 +35,9 @@ internal expect inline fun runTestForEach(items: Iterable, crossinline te * } * ``` * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.test.retryTest) + * * @param retries The number of retries to attempt after an initial failure. Must be a non-negative integer. * @param test A test to execute, which accepts the current retry attempt (starting at 0) as an argument. * @return A [TestResult] representing the outcome of the test after all attempts. @@ -41,5 +47,7 @@ expect inline fun retryTest(retries: Int, crossinline test: (Int) -> TestResult) /** * Defaults to `1` on all platforms except for JVM. * On JVM retries are disabled as we use test-retry Gradle plugin instead. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.test.DEFAULT_RETRIES) */ val DEFAULT_RETRIES: Int = if (PlatformUtils.IS_JVM) 0 else 1 diff --git a/ktor-shared/ktor-test-base/common/src/io/ktor/test/runTestWithData.kt b/ktor-shared/ktor-test-base/common/src/io/ktor/test/runTestWithData.kt index e1c090a3372..2298cd4c0fd 100644 --- a/ktor-shared/ktor-test-base/common/src/io/ktor/test/runTestWithData.kt +++ b/ktor-shared/ktor-test-base/common/src/io/ktor/test/runTestWithData.kt @@ -17,19 +17,30 @@ import kotlin.time.TimeSource /** * Represents a test case with associated data and retry attempt information. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.test.TestCase) + * * @property data The input data for the test case. * @property retry The current retry attempt number for this test case. `0` means the initial test run before retries. */ data class TestCase(val data: T, val retry: Int) -/** Represents a failed test execution with the [cause] of failure. */ +/** + * Represents a failed test execution with the [cause] of failure. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.test.TestFailure) + */ data class TestFailure( override val testCase: TestCase, val cause: Throwable, override val duration: Duration, ) : TestExecutionResult -/** Represents a successful test execution. */ +/** + * Represents a successful test execution. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.test.TestSuccess) + */ data class TestSuccess( override val testCase: TestCase, override val duration: Duration, @@ -37,6 +48,9 @@ data class TestSuccess( /** * The result of a test execution. Can be [TestFailure] or [TestSuccess]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.test.TestExecutionResult) + * * @property testCase The test case associated with this execution. * @property duration The duration of the test execution. */ @@ -68,6 +82,9 @@ sealed interface TestExecutionResult { * } * ``` * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.test.runTestWithData) + * * @param testCases Data to be used in tests. Each element represents a separate test case. * @param context Optional coroutine context for test execution. Defaults to [EmptyCoroutineContext]. * @param timeout Maximum duration allowed for each test attempt. Defaults to 1 minute. diff --git a/ktor-shared/ktor-test-base/jvm/src/io/ktor/test/junit/Assertions.kt b/ktor-shared/ktor-test-base/jvm/src/io/ktor/test/junit/Assertions.kt index bd43df0fc14..c3de5a6f258 100644 --- a/ktor-shared/ktor-test-base/jvm/src/io/ktor/test/junit/Assertions.kt +++ b/ktor-shared/ktor-test-base/jvm/src/io/ktor/test/junit/Assertions.kt @@ -9,6 +9,8 @@ import kotlin.test.* /** * Convenience function for asserting on all elements of a collection. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.test.junit.assertAll) */ fun assertAll(collection: Iterable, message: String? = null, predicate: (T) -> Boolean) { org.junit.jupiter.api.assertAll( @@ -22,6 +24,8 @@ fun assertAll(collection: Iterable, message: String? = null, predicate: ( /** * Convenience function for asserting on all elements of a collection. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.test.junit.assertAll) */ fun assertAll(collection: Iterable, assertion: (T) -> Unit) { org.junit.jupiter.api.assertAll( diff --git a/ktor-shared/ktor-websocket-serialization/common/src/io/ktor/websocket/serialization/WebsocketChannelSerialization.kt b/ktor-shared/ktor-websocket-serialization/common/src/io/ktor/websocket/serialization/WebsocketChannelSerialization.kt index e999026d1a0..ba6d598398d 100644 --- a/ktor-shared/ktor-websocket-serialization/common/src/io/ktor/websocket/serialization/WebsocketChannelSerialization.kt +++ b/ktor-shared/ktor-websocket-serialization/common/src/io/ktor/websocket/serialization/WebsocketChannelSerialization.kt @@ -18,6 +18,9 @@ import io.ktor.websocket.* * Frames sent after a Close frame are silently ignored. * Note that a Close frame could be sent automatically in reply to a peer's Close frame unless it is a raw WebSocket session. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.serialization.sendSerializedBase) + * * @param data The data to serialize * @param converter The WebSocket converter * @param charset Response charset @@ -36,6 +39,9 @@ public suspend inline fun WebSocketSession.sendSerializedBase( * Frames sent after a Close frame are silently ignored. * Note that a Close frame could be sent automatically in reply to a peer's Close frame unless it is a raw WebSocket session. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.serialization.sendSerializedBase) + * * @param data The data to serialize * @param typeInfo Type info of [T]. Can be retrieved with [typeInfo] function. * @param converter The WebSocket converter @@ -62,6 +68,9 @@ public suspend fun WebSocketSession.sendSerializedBase( * In this case, [WebsocketDeserializeException.frame] contains the received frame. * May throw [ClosedReceiveChannelException] if a channel was closed * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.serialization.receiveDeserializedBase) + * * @param converter The WebSocket converter * @param charset Response charset * @@ -80,6 +89,9 @@ public suspend inline fun WebSocketSession.receiveDeserializedBase( * In this case, [WebsocketDeserializeException.frame] contains the received frame. * May throw [ClosedReceiveChannelException] if a channel was closed * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.serialization.receiveDeserializedBase) + * * @param typeInfo Type info of [T]. Can be retrieved with [typeInfo] function. * @param converter The WebSocket converter * @param charset Response charset diff --git a/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/CloseReason.kt b/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/CloseReason.kt index da43f986e86..f4c383b265b 100644 --- a/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/CloseReason.kt +++ b/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/CloseReason.kt @@ -9,6 +9,9 @@ import kotlin.jvm.* /** * A WebSocket close reason. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.CloseReason) + * * @property code - close reason code as per RFC 6455, recommended to be one of [CloseReason.Codes] * @property message - a close reason message, could be empty */ @@ -17,6 +20,8 @@ public data class CloseReason(val code: Short, val message: String) { /** * An enum value for this [code] or `null` if the [code] is not listed in [Codes] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.CloseReason.knownReason) */ val knownReason: Codes? get() = Codes.byCode(code) @@ -29,6 +34,8 @@ public data class CloseReason(val code: Short, val message: String) { * Standard close reason codes * * see https://tools.ietf.org/html/rfc6455#section-7.4 for list of codes + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.CloseReason.Codes) */ public enum class Codes(public val code: Short) { NORMAL(1000), @@ -64,6 +71,9 @@ public data class CloseReason(val code: Short, val message: String) { /** * Get enum value by close reason code + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.CloseReason.Codes.Companion.byCode) + * * @return enum instance or null if [code] is not in standard */ public fun byCode(code: Short): Codes? = byCodeMap[code] diff --git a/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/DefaultWebSocketSession.kt b/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/DefaultWebSocketSession.kt index 7872a2b4f83..516cc05b1ed 100644 --- a/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/DefaultWebSocketSession.kt +++ b/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/DefaultWebSocketSession.kt @@ -21,36 +21,50 @@ internal val LOGGER = KtorSimpleLogger("io.ktor.websocket.WebSocket") /** * Ping interval meaning pinger is disabled. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.PINGER_DISABLED) + * * @see DefaultWebSocketSession.pingIntervalMillis */ public const val PINGER_DISABLED: Long = 0 /** * A default WebSocket session with ping-pong and timeout processing and built-in [closeReason] population. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.DefaultWebSocketSession) */ public interface DefaultWebSocketSession : WebSocketSession { /** * Specifies the ping interval or disables ping if [PINGER_DISABLED] is specified. * Note that pongs will be handled despite this setting. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.DefaultWebSocketSession.pingIntervalMillis) */ public var pingIntervalMillis: Long /** * Specifies a timeout to wait for pong reply to ping; otherwise, the session will be terminated immediately. * It doesn't have any effect if [pingIntervalMillis] is [PINGER_DISABLED]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.DefaultWebSocketSession.timeoutMillis) */ public var timeoutMillis: Long /** * A close reason for this session. It could be `null` if a session is terminated with no close reason * (for example due to connection failure). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.DefaultWebSocketSession.closeReason) */ public val closeReason: Deferred /** * Starts a WebSocket conversation. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.DefaultWebSocketSession.start) + * * @param negotiatedExtensions specify negotiated extensions list to use in current session. */ @InternalAPI @@ -59,6 +73,8 @@ public interface DefaultWebSocketSession : WebSocketSession { /** * Creates [DefaultWebSocketSession] from a session. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.DefaultWebSocketSession) */ public fun DefaultWebSocketSession( session: WebSocketSession, @@ -351,6 +367,8 @@ internal class DefaultWebSocketSessionImpl( /** * Ping interval or `null` to disable pinger. Note that pongs will be handled despite this setting. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.pingInterval) */ public inline var DefaultWebSocketSession.pingInterval: Duration? get() = pingIntervalMillis.takeIf { it > PINGER_DISABLED }?.milliseconds @@ -361,6 +379,8 @@ public inline var DefaultWebSocketSession.pingInterval: Duration? /** * A timeout to wait for pong reply to ping, otherwise the session will be terminated immediately. * It doesn't have any effect if [pingInterval] is `null` (pinger is disabled). + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.timeout) */ public inline var DefaultWebSocketSession.timeout: Duration get() = timeoutMillis.milliseconds diff --git a/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/FrameCommon.kt b/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/FrameCommon.kt index db8893940dc..2672ca3dbf3 100644 --- a/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/FrameCommon.kt +++ b/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/FrameCommon.kt @@ -11,6 +11,9 @@ import kotlinx.io.* /** * A frame received or ready to be sent. It is not reusable and not thread-safe. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.Frame) + * * @property fin is it final fragment, should be always `true` for control frames and if no fragmentation is used * @property frameType enum value * @property data - a frame content or fragment content @@ -30,16 +33,22 @@ public expect sealed class Frame private constructor( /** * First extension bit. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.Frame.rsv1) */ public val rsv1: Boolean /** * Second extension bit. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.Frame.rsv2) */ public val rsv2: Boolean /** * Third extension bit. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.Frame.rsv3) */ public val rsv3: Boolean @@ -54,6 +63,8 @@ public expect sealed class Frame private constructor( * In a RAW WebSocket session a big text frame could be fragmented * (separated into several text frames, so they have [fin] = false except the last one). * Note that usually there is no need to handle fragments unless you have a RAW web socket session. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.Frame.Binary) */ public class Binary public constructor( fin: Boolean, @@ -73,6 +84,8 @@ public expect sealed class Frame private constructor( * Please note that a boundary between fragments could be in the middle of multi-byte (unicode) character * so don't apply String constructor to every fragment but use decoder loop instead of concatenate fragments first. * Note that usually there is no need to handle fragments unless you have a RAW web socket session. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.Frame.Text) */ public class Text public constructor( fin: Boolean, @@ -89,6 +102,8 @@ public expect sealed class Frame private constructor( /** * Represents a low-level level close frame. It could be sent to indicate WebSocket session end. * Usually there is no need to send/handle it unless you have a RAW WebSocket session. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.Frame.Close) */ public class Close(data: ByteArray) : Frame { public constructor(reason: CloseReason) @@ -99,6 +114,8 @@ public expect sealed class Frame private constructor( /** * Represents a low-level ping frame. Could be sent to test connection (peer should reply with [Pong]). * Usually there is no need to send/handle it unless you have a RAW WebSocket session. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.Frame.Ping) */ public class Ping(data: ByteArray) : Frame { public constructor(packet: Source) @@ -107,6 +124,8 @@ public expect sealed class Frame private constructor( /** * Represents a low-level pong frame. Should be sent in reply to a [Ping] frame. * Usually there is no need to send/handle it unless you have a RAW WebSocket session. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.Frame.Pong) */ public class Pong( data: ByteArray, @@ -117,12 +136,16 @@ public expect sealed class Frame private constructor( /** * Creates a frame copy. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.Frame.copy) */ public fun copy(): Frame public companion object { /** * Create a particular [Frame] instance by the frame type. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.Frame.Companion.byType) */ public fun byType( fin: Boolean, @@ -138,6 +161,8 @@ public expect sealed class Frame private constructor( /** * Reads text content from the text frame. * Shouldn't be used for fragmented frames: such frames need to be reassembled first. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.readText) */ public fun Frame.Text.readText(): String { require(fin) { "Text could be only extracted from non-fragmented frame" } @@ -146,6 +171,8 @@ public fun Frame.Text.readText(): String { /** * Reads binary content from the frame. For fragmented frames only returns this fragment. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.readBytes) */ public fun Frame.readBytes(): ByteArray { return data.copyOf() @@ -153,6 +180,8 @@ public fun Frame.readBytes(): ByteArray { /** * Reads the close reason from the close frame or null if no close reason is provided. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.readReason) */ public fun Frame.Close.readReason(): CloseReason? { if (data.size < 2) { diff --git a/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/FrameTooBigException.kt b/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/FrameTooBigException.kt index ad0e4f1fd90..8bf95eb1c0b 100644 --- a/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/FrameTooBigException.kt +++ b/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/FrameTooBigException.kt @@ -9,6 +9,9 @@ import kotlinx.coroutines.* /** * Raised when the frame is bigger than allowed in a current WebSocket session. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.FrameTooBigException) + * * @param frameSize size of received or posted frame that is too big */ @OptIn(ExperimentalCoroutinesApi::class) diff --git a/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/FrameType.kt b/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/FrameType.kt index 4ac0614c364..b2023056639 100644 --- a/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/FrameType.kt +++ b/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/FrameType.kt @@ -6,32 +6,45 @@ package io.ktor.websocket /** * A WebSocket frame type. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.FrameType) + * * @property controlFrame if this is control frame type * @property opcode - frame type id that is used to transport it */ public enum class FrameType(public val controlFrame: Boolean, public val opcode: Int) { /** * A regular application level text frame. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.FrameType.TEXT) */ TEXT(false, 1), /** * A regular application level binary frame. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.FrameType.BINARY) */ BINARY(false, 2), /** * A low level close frame. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.FrameType.CLOSE) */ CLOSE(true, 8), /** * A low level ping frame. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.FrameType.PING) */ PING(true, 9), /** * A low level pong frame. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.FrameType.PONG) */ PONG(true, 0xa); @@ -42,6 +55,9 @@ public enum class FrameType(public val controlFrame: Boolean, public val opcode: /** * Finds [FrameType] instance by numeric [opcode]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.FrameType.Companion.get) + * * @return a [FrameType] instance or `null` of the [opcode] value is not valid */ public operator fun get(opcode: Int): FrameType? = if (opcode in 0..maxOpcode) byOpcodeArray[opcode] else null diff --git a/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/ProtocolViolationException.kt b/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/ProtocolViolationException.kt index 98197bc726f..d8b8f632fe8 100644 --- a/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/ProtocolViolationException.kt +++ b/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/ProtocolViolationException.kt @@ -9,6 +9,8 @@ import kotlinx.coroutines.* /** * Raised when peers send frames which violate the Websocket RFC + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.ProtocolViolationException) */ @OptIn(ExperimentalCoroutinesApi::class) public class ProtocolViolationException( diff --git a/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/RawWebSocketCommon.kt b/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/RawWebSocketCommon.kt index 24d8d214d28..af48f6394c9 100644 --- a/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/RawWebSocketCommon.kt +++ b/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/RawWebSocketCommon.kt @@ -18,6 +18,9 @@ import kotlin.random.* /** * Creates a RAW web socket session from connection. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.RawWebSocket) + * * @param input is a [ByteReadChannel] of connection * @param output is a [ByteWriteChannel] of connection * @param maxFrameSize is an initial [maxFrameSize] value for [WebSocketSession] @@ -164,6 +167,8 @@ private fun Source.mask(maskKey: Int): Source = withMemory(4) { maskMemory -> /** * Serializes WebSocket [Frame] and writes the bits into the [ByteWriteChannel]. * If [masking] is true, then data will be masked with random mask + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.writeFrame) */ @InternalAPI // used in tests public suspend fun ByteWriteChannel.writeFrame(frame: Frame, masking: Boolean) { @@ -209,6 +214,9 @@ public suspend fun ByteWriteChannel.writeFrame(frame: Frame, masking: Boolean) { /** * Reads bits from [ByteReadChannel] and converts into a WebSocket [Frame]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.readFrame) + * * @param maxFrameSize maximum frame size that could be read * @param lastOpcode last read opcode */ diff --git a/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/WebSocketExtension.kt b/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/WebSocketExtension.kt index 076be42576d..1638345e1a3 100644 --- a/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/WebSocketExtension.kt +++ b/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/WebSocketExtension.kt @@ -13,10 +13,14 @@ private typealias ExtensionInstaller = () -> WebSocketExtension<*> * [WebSocketExtensionsConfig.install] method to install the WebSocket extension in client or server. * * Usually this interface is implemented in `companion object` of the origin [WebSocketExtension]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.WebSocketExtensionFactory) */ public interface WebSocketExtensionFactory> { /** * A key used to locate an extension. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.WebSocketExtensionFactory.key) */ public val key: AttributeKey @@ -25,6 +29,8 @@ public interface WebSocketExtensionFactory Unit): ExtensionType } @@ -53,23 +65,32 @@ public interface WebSocketExtensionFactory { /** * Reference to the [WebSocketExtensionFactory], which produced this extension. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.WebSocketExtension.factory) */ public val factory: WebSocketExtensionFactory> /** * List of WebSocket extension protocols which will be sent by client in headers. * They are required to inform server that client wants to negotiate the current extension. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.WebSocketExtension.protocols) */ public val protocols: List /** * This method is called only for the client, when it receives the WebSocket upgrade response. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.WebSocketExtension.clientNegotiation) + * * @param negotiatedProtocols contains list of negotiated extensions from the server (can be empty). * * It's up to extension to decide if it should be used or not. @@ -80,6 +101,9 @@ public interface WebSocketExtension { /** * This method is called only for the server, when it receives WebSocket session. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.WebSocketExtension.serverNegotiation) + * * @param requestedProtocols contains list of requested extensions from the client (can be empty). * * @return list of protocols (with parameters), which server prefers to use for the current client request. @@ -90,17 +114,23 @@ public interface WebSocketExtension { /** * This method is called on each outgoing frame and handle it before sending. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.WebSocketExtension.processOutgoingFrame) */ public fun processOutgoingFrame(frame: Frame): Frame /** * This method is called on each incoming frame before handling it in WebSocket session. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.WebSocketExtension.processIncomingFrame) */ public fun processIncomingFrame(frame: Frame): Frame } /** * Extensions configuration for the WebSocket client and server plugins. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.WebSocketExtensionsConfig) */ public class WebSocketExtensionsConfig { private val installers: MutableList = mutableListOf() @@ -108,6 +138,8 @@ public class WebSocketExtensionsConfig { /** * Installs the provided [extension] using [config]. Every extension is processed in order of installation. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.WebSocketExtensionsConfig.install) */ public fun install( extension: WebSocketExtensionFactory, @@ -119,6 +151,8 @@ public class WebSocketExtensionsConfig { /** * Instantiates all installed extensions. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.WebSocketExtensionsConfig.build) */ public fun build(): List> = installers.map { it() } diff --git a/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/WebSocketExtensionHeader.kt b/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/WebSocketExtensionHeader.kt index 0c6a16d5acb..fee07f6bcc0 100644 --- a/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/WebSocketExtensionHeader.kt +++ b/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/WebSocketExtensionHeader.kt @@ -7,6 +7,9 @@ package io.ktor.websocket /** * A parsed `Sec-WebSocket-Accept` header item representation. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.WebSocketExtensionHeader) + * * @param name is extension name. * @param parameters is list of extension parameters. */ @@ -14,6 +17,8 @@ public class WebSocketExtensionHeader(public val name: String, public val parame /** * Parses parameters keys and values. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.WebSocketExtensionHeader.parseParameters) */ public fun parseParameters(): Sequence> = parameters.asSequence().map { val equalsIndex = it.indexOf('=') @@ -33,6 +38,8 @@ public class WebSocketExtensionHeader(public val name: String, public val parame /** * Parses the `Sec-WebSocket-Accept` header. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.parseWebSocketExtensions) */ public fun parseWebSocketExtensions(value: String): List = value .split(",") diff --git a/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/WebSocketSession.kt b/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/WebSocketSession.kt index fee08b70336..6417c79effe 100644 --- a/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/WebSocketSession.kt +++ b/ktor-shared/ktor-websockets/common/src/io/ktor/websocket/WebSocketSession.kt @@ -13,17 +13,23 @@ import kotlinx.coroutines.channels.* * - [Server WebSockets](https://ktor.io/docs/websocket.html) * - [Client WebSockets](https://ktor.io/docs/websocket-client.html) * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.WebSocketSession) */ public interface WebSocketSession : CoroutineScope { /** * Enables or disables masking output messages by a random XOR mask. * Note that changing this flag on the fly could be applied to the messages already sent (enqueued earlier) * as the sending pipeline works asynchronously. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.WebSocketSession.masking) */ public var masking: Boolean /** * Specifies the frame size limit. A connection will be closed if violated. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.WebSocketSession.maxFrameSize) */ public var maxFrameSize: Long @@ -32,17 +38,23 @@ public interface WebSocketSession : CoroutineScope { * Note that if you use `webSocket` to handle a WebSockets session, * the incoming channel doesn't contain control frames such as the ping/pong or close frames. * If you need control over control frames, use the `webSocketRaw` function. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.WebSocketSession.incoming) */ public val incoming: ReceiveChannel /** * An outgoing frames channel. It could have limited capacity so sending too many frames may lead to suspension at * corresponding send invocations. It also may suspend if a peer doesn't read frames for some reason. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.WebSocketSession.outgoing) */ public val outgoing: SendChannel /** * Negotiated WebSocket extensions. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.WebSocketSession.extensions) */ public val extensions: List> @@ -52,6 +64,8 @@ public interface WebSocketSession : CoroutineScope { * Frames that were sent after close frame could be silently ignored. * Note that a close frame could be sent automatically in reply to a peer's close frame unless it is * raw WebSocket session. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.WebSocketSession.send) */ public suspend fun send(frame: Frame) { outgoing.send(frame) @@ -62,11 +76,15 @@ public interface WebSocketSession : CoroutineScope { * Could be called at any time even after close. May return immediately if the connection is already terminated. * However, it may also fail with an exception (or cancellation) at any point due to a session failure. * Note that [flush] doesn't guarantee that frames were actually delivered. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.WebSocketSession.flush) */ public suspend fun flush() /** * Initiates a connection termination immediately. Termination may complete asynchronously. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.WebSocketSession.terminate) */ @Deprecated( "Use cancel() instead.", @@ -79,6 +97,9 @@ public interface WebSocketSession : CoroutineScope { /** * Finds the extensions using [WebSocketExtensionFactory]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.extension) + * * @return extension instance. * @throws [IllegalStateException] if the extension is not found. */ @@ -88,6 +109,9 @@ public fun > WebSocketSession.extension(extension: Web /** * Searches the extensions using [WebSocketExtensionFactory]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.extensionOrNull) + * * @return extension instance or `null` if the extension is not installed. */ @Suppress("UNCHECKED_CAST") @@ -99,6 +123,8 @@ public fun > WebSocketSession.extensionOrNull( * Enqueues a text frame for sending with the specified [content]. * * May suspend if the outgoing queue is full, and throw an exception if the channel is already closed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.send) */ public suspend fun WebSocketSession.send(content: String): Unit = send(Frame.Text(content)) @@ -106,6 +132,8 @@ public suspend fun WebSocketSession.send(content: String): Unit = send(Frame.Tex * Enqueues a final binary frame for sending with the specified [content]. * * May suspend if the outgoing queue is full, and throws an exception if the channel is already closed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.send) */ public suspend fun WebSocketSession.send(content: ByteArray): Unit = send(Frame.Binary(true, content)) @@ -114,6 +142,8 @@ public suspend fun WebSocketSession.send(content: ByteArray): Unit = send(Frame. * The specified [reason] could be ignored if there was already * close frame sent (for example in reply to a peer close frame). It also may do nothing when a session or an outgoing * channel is already closed due to any reason. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.close) */ public suspend fun WebSocketSession.close(reason: CloseReason = CloseReason(CloseReason.Codes.NORMAL, "")) { try { @@ -125,6 +155,8 @@ public suspend fun WebSocketSession.close(reason: CloseReason = CloseReason(Clos /** * Closes with the reason depending on [cause] or normally if the [cause] is `null`. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.close) */ @Deprecated( "Close with reason or terminate instead.", @@ -140,6 +172,8 @@ public suspend fun WebSocketSession.close(cause: Throwable?) { /** * Closes a session with normal or error close reason, depending on whether [cause] is cancellation or not. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.closeExceptionally) */ public suspend fun WebSocketSession.closeExceptionally(cause: Throwable) { val reason = when (cause) { diff --git a/ktor-shared/ktor-websockets/jsAndWasmShared/src/io/ktor/websocket/FrameJs.kt b/ktor-shared/ktor-websockets/jsAndWasmShared/src/io/ktor/websocket/FrameJs.kt index dd40a1e5ec7..ec23085e591 100644 --- a/ktor-shared/ktor-websockets/jsAndWasmShared/src/io/ktor/websocket/FrameJs.kt +++ b/ktor-shared/ktor-websockets/jsAndWasmShared/src/io/ktor/websocket/FrameJs.kt @@ -10,6 +10,9 @@ import kotlinx.io.* /** * A frame received or ready to be sent. It is not reusable and not thread-safe + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.Frame) + * * @property fin is it final fragment, should be always `true` for control frames and if no fragmentation is used * @property frameType enum value * @property data - a frame content or fragment content @@ -30,6 +33,8 @@ public actual sealed class Frame actual constructor( * In a RAW web socket session a big text frame could be fragmented * (separated into several text frames so they have [fin] = false except the last one). * Note that usually there is no need to handle fragments unless you have a RAW web socket session. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.Frame.Binary) */ public actual class Binary actual constructor( fin: Boolean, @@ -49,6 +54,8 @@ public actual sealed class Frame actual constructor( * Please note that a boundary between fragments could be in the middle of multi-byte (unicode) character * so don't apply String constructor to every fragment but use decoder loop instead of concatenate fragments first. * Note that usually there is no need to handle fragments unless you have a RAW web socket session. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.Frame.Text) */ public actual class Text actual constructor( fin: Boolean, @@ -65,6 +72,8 @@ public actual sealed class Frame actual constructor( /** * Represents a low-level level close frame. It could be sent to indicate web socket session end. * Usually there is no need to send/handle it unless you have a RAW web socket session. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.Frame.Close) */ public actual class Close actual constructor( data: ByteArray @@ -83,6 +92,8 @@ public actual sealed class Frame actual constructor( /** * Represents a low-level ping frame. Could be sent to test connection (peer should reply with [Pong]). * Usually there is no need to send/handle it unless you have a RAW web socket session. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.Frame.Ping) */ public actual class Ping actual constructor( data: ByteArray @@ -93,6 +104,8 @@ public actual sealed class Frame actual constructor( /** * Represents a low-level pong frame. Should be sent in reply to a [Ping] frame. * Usually there is no need to send/handle it unless you have a RAW web socket session. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.Frame.Pong) */ public actual class Pong actual constructor( data: ByteArray, @@ -105,6 +118,8 @@ public actual sealed class Frame actual constructor( /** * Creates a frame copy. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.Frame.copy) */ public actual fun copy(): Frame = byType(fin, frameType, data.copyOf(), rsv1, rsv2, rsv3) @@ -113,6 +128,8 @@ public actual sealed class Frame actual constructor( /** * Create a particular [Frame] instance by frame type. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.Frame.Companion.byType) */ public actual fun byType( fin: Boolean, diff --git a/ktor-shared/ktor-websockets/jsAndWasmShared/src/io/ktor/websocket/RawWebSocket.kt b/ktor-shared/ktor-websockets/jsAndWasmShared/src/io/ktor/websocket/RawWebSocket.kt index 55f1b8c65c1..df5efc049de 100644 --- a/ktor-shared/ktor-websockets/jsAndWasmShared/src/io/ktor/websocket/RawWebSocket.kt +++ b/ktor-shared/ktor-websockets/jsAndWasmShared/src/io/ktor/websocket/RawWebSocket.kt @@ -10,6 +10,9 @@ import kotlin.coroutines.* /** * Creates a RAW web socket session from connection * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.RawWebSocket) + * * @param input is a [ByteReadChannel] of connection * @param output is a [ByteWriteChannel] of connection * @param maxFrameSize is an initial [maxFrameSize] value for [WebSocketSession] diff --git a/ktor-shared/ktor-websockets/jvm/src/io/ktor/websocket/Frame.kt b/ktor-shared/ktor-websockets/jvm/src/io/ktor/websocket/Frame.kt index f3167dee11e..2afc1419f81 100644 --- a/ktor-shared/ktor-websockets/jvm/src/io/ktor/websocket/Frame.kt +++ b/ktor-shared/ktor-websockets/jvm/src/io/ktor/websocket/Frame.kt @@ -12,6 +12,9 @@ import java.nio.* /** * A frame received or ready to be sent. It is not reusable and not thread-safe + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.Frame) + * * @property fin is it final fragment, should be always `true` for control frames and if no fragmentation is used * @property frameType enum value * @property data - a frame content or fragment content @@ -29,6 +32,8 @@ public actual sealed class Frame actual constructor( ) { /** * Frame content + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.Frame.buffer) */ public val buffer: ByteBuffer = ByteBuffer.wrap(data) @@ -37,6 +42,8 @@ public actual sealed class Frame actual constructor( * In a RAW web socket session a big text frame could be fragmented * (separated into several text frames so they have [fin] = false except the last one). * Note that usually there is no need to handle fragments unless you have a RAW web socket session. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.Frame.Binary) */ public actual class Binary actual constructor( fin: Boolean, @@ -59,6 +66,8 @@ public actual sealed class Frame actual constructor( * Please note that a boundary between fragments could be in the middle of multi-byte (unicode) character * so don't apply String constructor to every fragment but use decoder loop instead of concatenate fragments first. * Note that usually there is no need to handle fragments unless you have a RAW web socket session. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.Frame.Text) */ public actual class Text actual constructor( fin: Boolean, @@ -80,6 +89,8 @@ public actual sealed class Frame actual constructor( /** * Represents a low-level level close frame. It could be sent to indicate web socket session end. * Usually there is no need to send/handle it unless you have a RAW web socket session. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.Frame.Close) */ public actual class Close actual constructor( data: ByteArray @@ -101,6 +112,8 @@ public actual sealed class Frame actual constructor( /** * Represents a low-level ping frame. Could be sent to test connection (peer should reply with [Pong]). * Usually there is no need to send/handle it unless you have a RAW web socket session. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.Frame.Ping) */ public actual class Ping actual constructor( data: ByteArray @@ -112,6 +125,8 @@ public actual sealed class Frame actual constructor( /** * Represents a low-level pong frame. Should be sent in reply to a [Ping] frame. * Usually there is no need to send/handle it unless you have a RAW web socket session. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.Frame.Pong) */ public actual class Pong actual constructor( data: ByteArray, @@ -130,6 +145,8 @@ public actual sealed class Frame actual constructor( /** * Creates a frame copy. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.Frame.copy) */ public actual fun copy(): Frame = byType(fin, frameType, data.copyOf(), rsv1, rsv2, rsv3) @@ -138,6 +155,8 @@ public actual sealed class Frame actual constructor( /** * Create a particular [Frame] instance by frame type. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.Frame.Companion.byType) */ public actual fun byType( fin: Boolean, diff --git a/ktor-shared/ktor-websockets/jvm/src/io/ktor/websocket/RawWebSocketJvm.kt b/ktor-shared/ktor-websockets/jvm/src/io/ktor/websocket/RawWebSocketJvm.kt index 930fba5d040..71ebb63b556 100644 --- a/ktor-shared/ktor-websockets/jvm/src/io/ktor/websocket/RawWebSocketJvm.kt +++ b/ktor-shared/ktor-websockets/jvm/src/io/ktor/websocket/RawWebSocketJvm.kt @@ -17,6 +17,9 @@ import kotlin.properties.* /** * Creates a RAW web socket session from connection * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.RawWebSocket) + * * @param input is a [ByteReadChannel] of connection * @param output is a [ByteWriteChannel] of connection * @param maxFrameSize is an initial [maxFrameSize] value for [WebSocketSession] diff --git a/ktor-shared/ktor-websockets/jvm/src/io/ktor/websocket/WebSocketDeflateExtension.kt b/ktor-shared/ktor-websockets/jvm/src/io/ktor/websocket/WebSocketDeflateExtension.kt index 926212fba5a..c1bc96b2a72 100644 --- a/ktor-shared/ktor-websockets/jvm/src/io/ktor/websocket/WebSocketDeflateExtension.kt +++ b/ktor-shared/ktor-websockets/jvm/src/io/ktor/websocket/WebSocketDeflateExtension.kt @@ -32,6 +32,8 @@ private const val MIN_WINDOW_BITS: Int = 8 * * Implements WebSocket deflate extension from [RFC-7692](https://tools.ietf.org/html/rfc7692). * This implementation is using window size = 15 due to limitations of [Deflater] implementation. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.WebSocketDeflateExtension) */ public class WebSocketDeflateExtension internal constructor( private val config: Config @@ -157,20 +159,28 @@ public class WebSocketDeflateExtension internal constructor( /** * WebSocket deflate extension configuration. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.WebSocketDeflateExtension.Config) */ public class Config { /** * Specify if the client drops the deflater state (reset the window) after each frame. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.WebSocketDeflateExtension.Config.clientNoContextTakeOver) */ public var clientNoContextTakeOver: Boolean = false /** * Specify if the server drops the deflater state (reset the window) after each frame. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.WebSocketDeflateExtension.Config.serverNoContextTakeOver) */ public var serverNoContextTakeOver: Boolean = false /** * Compression level that is used for outgoing frames in the [Deflate] instance. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.WebSocketDeflateExtension.Config.compressionLevel) */ public var compressionLevel: Int = Deflater.DEFAULT_COMPRESSION @@ -180,6 +190,8 @@ public class WebSocketDeflateExtension internal constructor( /** * Configure which protocols should send the client. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.WebSocketDeflateExtension.Config.configureProtocols) */ public fun configureProtocols(block: (protocols: MutableList) -> Unit) { val old = manualConfig @@ -193,6 +205,8 @@ public class WebSocketDeflateExtension internal constructor( * Indicates if the outgoing frame should be compressed. * * Compress the frame only if all conditions passed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.WebSocketDeflateExtension.Config.compressIf) */ public fun compressIf(block: (frame: Frame) -> Boolean) { val old = compressCondition @@ -201,6 +215,8 @@ public class WebSocketDeflateExtension internal constructor( /** * Specify the minimum size of frame for compression. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.WebSocketDeflateExtension.Config.compressIfBiggerThan) */ public fun compressIfBiggerThan(bytes: Int) { compressIf { frame -> frame.data.size > bytes } diff --git a/ktor-shared/ktor-websockets/jvm/src/io/ktor/websocket/WebSocketReader.kt b/ktor-shared/ktor-websockets/jvm/src/io/ktor/websocket/WebSocketReader.kt index 2e7d11b75d8..81b961d026a 100644 --- a/ktor-shared/ktor-websockets/jvm/src/io/ktor/websocket/WebSocketReader.kt +++ b/ktor-shared/ktor-websockets/jvm/src/io/ktor/websocket/WebSocketReader.kt @@ -20,6 +20,9 @@ import kotlin.coroutines.* * Class that continuously reads a [byteChannel] and * converts into Websocket [Frame] exposing them in [incoming]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.WebSocketReader) + * * @param maxFrameSize maximum frame size that could be read */ public class WebSocketReader( @@ -58,6 +61,8 @@ public class WebSocketReader( /** * Channel receiving Websocket's [Frame] objects read from [byteChannel]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.WebSocketReader.incoming) */ public val incoming: ReceiveChannel get() = queue diff --git a/ktor-shared/ktor-websockets/jvm/src/io/ktor/websocket/WebSocketWriter.kt b/ktor-shared/ktor-websockets/jvm/src/io/ktor/websocket/WebSocketWriter.kt index 4671eec6931..1388e8f18ae 100644 --- a/ktor-shared/ktor-websockets/jvm/src/io/ktor/websocket/WebSocketWriter.kt +++ b/ktor-shared/ktor-websockets/jvm/src/io/ktor/websocket/WebSocketWriter.kt @@ -16,6 +16,9 @@ import kotlin.coroutines.* /** * Class that processes written [outgoing] Websocket [Frame], * serializes them and writes the bits into the [writeChannel]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.WebSocketWriter) + * * @property masking: whether it will mask serialized frames. * @property pool: [ByteBuffer] pool to be used by this writer */ @@ -32,6 +35,8 @@ public class WebSocketWriter( /** * Channel for sending Websocket's [Frame] that will be serialized and written to [writeChannel]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.WebSocketWriter.outgoing) */ public val outgoing: SendChannel get() = queue @@ -143,11 +148,15 @@ public class WebSocketWriter( /** * Send a frame and write it and all outstanding frames in the queue + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.WebSocketWriter.send) */ public suspend fun send(frame: Frame): Unit = queue.send(frame) /** * Ensures all enqueued messages has been written + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.WebSocketWriter.flush) */ public suspend fun flush(): Unit = FlushRequest(coroutineContext[Job]).also { try { diff --git a/ktor-shared/ktor-websockets/posix/src/io/ktor/websocket/FrameNative.kt b/ktor-shared/ktor-websockets/posix/src/io/ktor/websocket/FrameNative.kt index fbbe55569ac..957c1533aaf 100644 --- a/ktor-shared/ktor-websockets/posix/src/io/ktor/websocket/FrameNative.kt +++ b/ktor-shared/ktor-websockets/posix/src/io/ktor/websocket/FrameNative.kt @@ -10,6 +10,9 @@ import kotlinx.io.* /** * A frame received or ready to be sent. It is not reusable and not thread-safe + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.Frame) + * * @property fin is it final fragment, should be always `true` for control frames and if no fragmentation is used * @property frameType enum value * @property data - a frame content or fragment content @@ -30,6 +33,8 @@ public actual sealed class Frame actual constructor( * In a RAW web socket session a big text frame could be fragmented * (separated into several text frames so they have [fin] = false except the last one). * Note that usually there is no need to handle fragments unless you have a RAW web socket session. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.Frame.Binary) */ public actual class Binary actual constructor( fin: Boolean, @@ -50,6 +55,8 @@ public actual sealed class Frame actual constructor( * Please note that a boundary between fragments could be in the middle of multi-byte (unicode) character * so don't apply String constructor to every fragment but use decoder loop instead of concatenate fragments first. * Note that usually there is no need to handle fragments unless you have a RAW web socket session. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.Frame.Text) */ public actual class Text actual constructor( fin: Boolean, @@ -66,6 +73,8 @@ public actual sealed class Frame actual constructor( /** * Represents a low-level level close frame. It could be sent to indicate web socket session end. * Usually there is no need to send/handle it unless you have a RAW web socket session. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.Frame.Close) */ public actual class Close actual constructor( data: ByteArray @@ -84,6 +93,8 @@ public actual sealed class Frame actual constructor( /** * Represents a low-level ping frame. Could be sent to test connection (peer should reply with [Pong]). * Usually there is no need to send/handle it unless you have a RAW web socket session. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.Frame.Ping) */ public actual class Ping actual constructor( data: ByteArray @@ -94,6 +105,8 @@ public actual sealed class Frame actual constructor( /** * Represents a low-level pong frame. Should be sent in reply to a [Ping] frame. * Usually there is no need to send/handle it unless you have a RAW web socket session. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.Frame.Pong) */ public actual class Pong actual constructor( data: ByteArray, @@ -106,6 +119,8 @@ public actual sealed class Frame actual constructor( /** * Creates a frame copy. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.Frame.copy) */ public actual fun copy(): Frame = byType(fin, frameType, data.copyOf(), rsv1, rsv2, rsv3) @@ -114,6 +129,8 @@ public actual sealed class Frame actual constructor( /** * Create a particular [Frame] instance by frame type. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.Frame.Companion.byType) */ public actual fun byType( fin: Boolean, diff --git a/ktor-shared/ktor-websockets/posix/src/io/ktor/websocket/RawWebSocket.kt b/ktor-shared/ktor-websockets/posix/src/io/ktor/websocket/RawWebSocket.kt index 55f1b8c65c1..df5efc049de 100644 --- a/ktor-shared/ktor-websockets/posix/src/io/ktor/websocket/RawWebSocket.kt +++ b/ktor-shared/ktor-websockets/posix/src/io/ktor/websocket/RawWebSocket.kt @@ -10,6 +10,9 @@ import kotlin.coroutines.* /** * Creates a RAW web socket session from connection * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.websocket.RawWebSocket) + * * @param input is a [ByteReadChannel] of connection * @param output is a [ByteWriteChannel] of connection * @param maxFrameSize is an initial [maxFrameSize] value for [WebSocketSession] diff --git a/ktor-test-dispatcher/common/src/TestCommon.kt b/ktor-test-dispatcher/common/src/TestCommon.kt index f7d63b7c8fd..a3095af0696 100644 --- a/ktor-test-dispatcher/common/src/TestCommon.kt +++ b/ktor-test-dispatcher/common/src/TestCommon.kt @@ -12,6 +12,8 @@ import kotlin.time.Duration.Companion.seconds /** * Test runner for common suspend tests. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.test.dispatcher.testSuspend) */ @Deprecated( "testSuspend is deprecated, use runTest function instead", diff --git a/ktor-test-dispatcher/js/src/TestJs.kt b/ktor-test-dispatcher/js/src/TestJs.kt index f5d9470c119..2eff269f3d7 100644 --- a/ktor-test-dispatcher/js/src/TestJs.kt +++ b/ktor-test-dispatcher/js/src/TestJs.kt @@ -12,6 +12,8 @@ import kotlin.time.Duration.Companion.milliseconds /** * Test runner for js suspend tests. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.test.dispatcher.testSuspend) */ public actual fun testSuspend( context: CoroutineContext, diff --git a/ktor-test-dispatcher/jvm/src/TestJvm.kt b/ktor-test-dispatcher/jvm/src/TestJvm.kt index 07a1c86f067..46e9d044508 100644 --- a/ktor-test-dispatcher/jvm/src/TestJvm.kt +++ b/ktor-test-dispatcher/jvm/src/TestJvm.kt @@ -10,6 +10,8 @@ import kotlin.coroutines.* /** * Test runner for jvm suspend tests. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.test.dispatcher.testSuspend) */ public actual fun testSuspend( context: CoroutineContext, diff --git a/ktor-test-dispatcher/posix/src/TestPosix.kt b/ktor-test-dispatcher/posix/src/TestPosix.kt index 79393b3e532..273adf042b3 100644 --- a/ktor-test-dispatcher/posix/src/TestPosix.kt +++ b/ktor-test-dispatcher/posix/src/TestPosix.kt @@ -10,6 +10,8 @@ import kotlin.coroutines.* /** * Test runner for native suspend tests. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.test.dispatcher.testSuspend) */ public actual fun testSuspend( context: CoroutineContext, diff --git a/ktor-test-dispatcher/wasmJs/src/TestWasm.kt b/ktor-test-dispatcher/wasmJs/src/TestWasm.kt index 3d749100c99..f844106458c 100644 --- a/ktor-test-dispatcher/wasmJs/src/TestWasm.kt +++ b/ktor-test-dispatcher/wasmJs/src/TestWasm.kt @@ -11,6 +11,8 @@ import kotlin.time.* /** * Test runner for js suspend tests. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.test.dispatcher.testSuspend) */ public actual fun testSuspend( context: CoroutineContext, diff --git a/ktor-utils/common/src/io/ktor/util/Attributes.kt b/ktor-utils/common/src/io/ktor/util/Attributes.kt index 3bd25c290af..a3accb7fe61 100644 --- a/ktor-utils/common/src/io/ktor/util/Attributes.kt +++ b/ktor-utils/common/src/io/ktor/util/Attributes.kt @@ -10,6 +10,9 @@ import kotlin.reflect.* /** * Specifies a key for an attribute in [Attributes] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.AttributeKey) + * * @param T is a type of the value stored in the attribute * @param name is a name of the attribute for diagnostic purposes. Can't be blank */ @@ -19,6 +22,9 @@ public inline fun AttributeKey(name: String): AttributeKey /** * Specifies a key for an attribute in [Attributes] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.AttributeKey) + * * @param T is a type of the value stored in the attribute * @property name is a name of the attribute for diagnostic purposes. Can't be blank * @property type the recorded kotlin type of T @@ -36,6 +42,9 @@ public data class AttributeKey @JvmOverloads constructor( /** * A version of [AttributeKey] that overrides [equals] and [hashCode] using [name] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.EquatableAttributeKey) + * * @param T is a type of the value stored in the attribute * @param name is a name of the attribute */ @@ -48,62 +57,86 @@ public typealias EquatableAttributeKey = AttributeKey /** * Creates an attributes instance suitable for the particular platform + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.Attributes) */ public expect fun Attributes(concurrent: Boolean = false): Attributes /** * Map of attributes accessible by [AttributeKey] in a typed manner + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.Attributes) */ public interface Attributes { /** * Gets a value of the attribute for the specified [key], or throws an exception if an attribute doesn't exist + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.Attributes.get) */ public operator fun get(key: AttributeKey): T = getOrNull(key) ?: throw IllegalStateException("No instance for key $key") /** * Gets a value of the attribute for the specified [key], or return `null` if an attribute doesn't exist + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.Attributes.getOrNull) */ public fun getOrNull(key: AttributeKey): T? /** * Checks if an attribute with the specified [key] exists + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.Attributes.contains) */ public operator fun contains(key: AttributeKey<*>): Boolean /** * Creates or changes an attribute with the specified [key] using [value] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.Attributes.put) */ public fun put(key: AttributeKey, value: T) /** * Removes an attribute with the specified [key] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.Attributes.remove) */ public fun remove(key: AttributeKey) /** * Removes an attribute with the specified [key] and returns its current value, throws an exception if an attribute doesn't exist + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.Attributes.take) */ public fun take(key: AttributeKey): T = get(key).also { remove(key) } /** * Removes an attribute with the specified [key] and returns its current value, returns `null` if an attribute doesn't exist + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.Attributes.takeOrNull) */ public fun takeOrNull(key: AttributeKey): T? = getOrNull(key).also { remove(key) } /** * Gets a value of the attribute for the specified [key], or calls supplied [block] to compute its value + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.Attributes.computeIfAbsent) */ public fun computeIfAbsent(key: AttributeKey, block: () -> T): T /** * Returns [List] of all [AttributeKey] instances in this map + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.Attributes.allKeys) */ public val allKeys: List> } /** * Adds all attributes from another collection, replacing original values if any. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.putAll) */ public fun Attributes.putAll(other: Attributes) { other.allKeys.forEach { diff --git a/ktor-utils/common/src/io/ktor/util/Base64.kt b/ktor-utils/common/src/io/ktor/util/Base64.kt index 2d67dedaa21..6d56fe00cf2 100644 --- a/ktor-utils/common/src/io/ktor/util/Base64.kt +++ b/ktor-utils/common/src/io/ktor/util/Base64.kt @@ -19,6 +19,8 @@ private val BASE64_INVERSE_ALPHABET = IntArray(256) { /** * Encode [String] in base64 format and UTF-8 character encoding. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.encodeBase64) */ public fun String.encodeBase64(): String = buildPacket { writeText(this@encodeBase64) @@ -26,6 +28,8 @@ public fun String.encodeBase64(): String = buildPacket { /** * Encode [ByteArray] in base64 format + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.encodeBase64) */ public fun ByteArray.encodeBase64(): String { val array = this@encodeBase64 @@ -68,11 +72,15 @@ public fun ByteArray.encodeBase64(): String { /** * Encode [ByteReadPacket] in base64 format + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.encodeBase64) */ public fun Source.encodeBase64(): String = readByteArray().encodeBase64() /** * Decode [String] from base64 format encoded in UTF-8. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.decodeBase64String) */ public fun String.decodeBase64String(): String { val bytes = decodeBase64Bytes() @@ -81,6 +89,8 @@ public fun String.decodeBase64String(): String { /** * Decode [String] from base64 format + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.decodeBase64Bytes) */ public fun String.decodeBase64Bytes(): ByteArray = buildPacket { writeText(dropLastWhile { it == BASE64_PAD }) @@ -88,6 +98,8 @@ public fun String.decodeBase64Bytes(): ByteArray = buildPacket { /** * Decode [ByteReadPacket] from base64 format + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.decodeBase64Bytes) */ public fun Source.decodeBase64Bytes(): Input = buildPacket { val data = ByteArray(4) diff --git a/ktor-utils/common/src/io/ktor/util/ByteChannels.kt b/ktor-utils/common/src/io/ktor/util/ByteChannels.kt index 781945e4f05..91403a67a8c 100644 --- a/ktor-utils/common/src/io/ktor/util/ByteChannels.kt +++ b/ktor-utils/common/src/io/ktor/util/ByteChannels.kt @@ -14,6 +14,8 @@ private const val CHUNK_BUFFER_SIZE = 4096L /** * Split source [ByteReadChannel] into 2 new ones. * Cancel of one channel in split (input or both outputs) cancels other channels. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.split) */ public fun ByteReadChannel.split(coroutineScope: CoroutineScope): Pair { val first = ByteChannel(autoFlush = true) @@ -52,6 +54,8 @@ public fun ByteReadChannel.split(coroutineScope: CoroutineScope): Pair : MutableMap { private val delegate = mutableMapOf() diff --git a/ktor-utils/common/src/io/ktor/util/Charset.kt b/ktor-utils/common/src/io/ktor/util/Charset.kt index 644a40863e0..dc15c611062 100644 --- a/ktor-utils/common/src/io/ktor/util/Charset.kt +++ b/ktor-utils/common/src/io/ktor/util/Charset.kt @@ -6,10 +6,14 @@ package io.ktor.util /** * Check if [Char] is in lower case + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.isLowerCase) */ public fun Char.isLowerCase(): Boolean = lowercaseChar() == this /** * Convert [String] to [CharArray] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.toCharArray) */ public fun String.toCharArray(): CharArray = CharArray(length) { get(it) } diff --git a/ktor-utils/common/src/io/ktor/util/Collections.kt b/ktor-utils/common/src/io/ktor/util/Collections.kt index 930b224bb9d..4c504049c73 100644 --- a/ktor-utils/common/src/io/ktor/util/Collections.kt +++ b/ktor-utils/common/src/io/ktor/util/Collections.kt @@ -6,10 +6,14 @@ package io.ktor.util /** * Create an instance of case-insensitive mutable map. For internal use only. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.caseInsensitiveMap) */ public fun caseInsensitiveMap(): MutableMap = CaseInsensitiveMap() /** * Freeze selected set. May do nothing on some platforms. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.unmodifiable) */ public expect fun Set.unmodifiable(): Set diff --git a/ktor-utils/common/src/io/ktor/util/ContentEncoder.kt b/ktor-utils/common/src/io/ktor/util/ContentEncoder.kt index 42c970a5ec6..a75f43718fa 100644 --- a/ktor-utils/common/src/io/ktor/util/ContentEncoder.kt +++ b/ktor-utils/common/src/io/ktor/util/ContentEncoder.kt @@ -9,21 +9,29 @@ import kotlin.coroutines.* /** * A request/response content encoder. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.ContentEncoder) */ public interface ContentEncoder : Encoder { /** * Encoder identifier to use in http headers. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.ContentEncoder.name) */ public val name: String /** * Provides an estimation for the compressed length based on the originalLength or return null if it's impossible. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.ContentEncoder.predictCompressedLength) */ public fun predictCompressedLength(contentLength: Long): Long? = null } /** * Implementation of [ContentEncoder] using gzip algorithm + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.GZipEncoder) */ public expect object GZipEncoder : ContentEncoder { override val name: String @@ -46,6 +54,8 @@ public expect object GZipEncoder : ContentEncoder { /** * Implementation of [ContentEncoder] using deflate algorithm + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.DeflateEncoder) */ public expect object DeflateEncoder : ContentEncoder { override val name: String @@ -68,6 +78,8 @@ public expect object DeflateEncoder : ContentEncoder { /** * Implementation of [ContentEncoder] using identity algorithm + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.IdentityEncoder) */ public object IdentityEncoder : ContentEncoder, Encoder by Identity { override val name: String = "identity" diff --git a/ktor-utils/common/src/io/ktor/util/CoroutinesUtils.kt b/ktor-utils/common/src/io/ktor/util/CoroutinesUtils.kt index 2141e473057..08ef65634c7 100644 --- a/ktor-utils/common/src/io/ktor/util/CoroutinesUtils.kt +++ b/ktor-utils/common/src/io/ktor/util/CoroutinesUtils.kt @@ -9,6 +9,8 @@ import kotlin.coroutines.* /** * Print [Job] children tree. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.printDebugTree) */ public fun Job.printDebugTree(offset: Int = 0) { println(" ".repeat(offset) + this) @@ -22,6 +24,8 @@ public fun Job.printDebugTree(offset: Int = 0) { /** * Supervisor with empty coroutine exception handler ignoring all exceptions. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.SilentSupervisor) */ @Suppress("FunctionName") public fun SilentSupervisor(parent: Job? = null): CoroutineContext = diff --git a/ktor-utils/common/src/io/ktor/util/Crypto.kt b/ktor-utils/common/src/io/ktor/util/Crypto.kt index 0996de3e017..782fc9b0f01 100644 --- a/ktor-utils/common/src/io/ktor/util/Crypto.kt +++ b/ktor-utils/common/src/io/ktor/util/Crypto.kt @@ -18,6 +18,8 @@ internal const val NONCE_SIZE_IN_BYTES = 16 /** * Encode [bytes] as a HEX string with no spaces, newlines and `0x` prefixes. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.hex) */ public fun hex(bytes: ByteArray): String { val result = CharArray(bytes.size * 2) @@ -35,6 +37,8 @@ public fun hex(bytes: ByteArray): String { /** * Decode bytes from HEX string. It should be no spaces and `0x` prefixes. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.hex) */ public fun hex(s: String): ByteArray { val result = ByteArray(s.length / 2) @@ -50,11 +54,15 @@ public fun hex(s: String): ByteArray { /** * Generates a nonce string. Could block if the system's entropy source is empty + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.generateNonce) */ public expect fun generateNonce(): String /** * Generates a nonce bytes of [size]. Could block if the system's entropy source is empty + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.generateNonce) */ public fun generateNonce(size: Int): ByteArray = buildPacket { while (this.size < size) { @@ -64,37 +72,51 @@ public fun generateNonce(size: Int): ByteArray = buildPacket { /** * Compute SHA-1 hash for the specified [bytes] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.sha1) */ public expect fun sha1(bytes: ByteArray): ByteArray /** * Create [Digest] from specified hash [name]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.Digest) */ @Suppress("FunctionName") public expect fun Digest(name: String): Digest /** * Stateful digest class specified to calculate digest. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.Digest) */ public interface Digest { /** * Add [bytes] to digest value. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.Digest.plusAssign) */ public operator fun plusAssign(bytes: ByteArray) /** * Reset [Digest] state. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.Digest.reset) */ public fun reset() /** * Calculate digest bytes. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.Digest.build) */ public suspend fun build(): ByteArray } /** * Calculate digest from current state and specified [bytes]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.build) */ @InternalAPI public suspend fun Digest.build(bytes: ByteArray): ByteArray { @@ -104,6 +126,8 @@ public suspend fun Digest.build(bytes: ByteArray): ByteArray { /** * Calculate digest from current state and specified [string]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.build) */ @InternalAPI public suspend fun Digest.build(string: String, charset: Charset = Charsets.UTF_8): ByteArray { diff --git a/ktor-utils/common/src/io/ktor/util/Encoders.kt b/ktor-utils/common/src/io/ktor/util/Encoders.kt index 97d801a2aea..693071536b1 100644 --- a/ktor-utils/common/src/io/ktor/util/Encoders.kt +++ b/ktor-utils/common/src/io/ktor/util/Encoders.kt @@ -9,6 +9,8 @@ import kotlin.coroutines.* /** * Empty [Encoder] that doesn't do any changes. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.Identity) */ public object Identity : Encoder { override fun encode( @@ -29,10 +31,14 @@ public object Identity : Encoder { /** * Content encoder. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.Encoder) */ public interface Encoder { /** * Launch coroutine to encode [source] bytes. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.Encoder.encode) */ public fun encode( source: ByteReadChannel, @@ -41,6 +47,8 @@ public interface Encoder { /** * Launch coroutine to encode [source] bytes. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.Encoder.encode) */ public fun encode( source: ByteWriteChannel, @@ -49,6 +57,8 @@ public interface Encoder { /** * Launch coroutine to decode [source] bytes. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.Encoder.decode) */ public fun decode( source: ByteReadChannel, diff --git a/ktor-utils/common/src/io/ktor/util/NonceManager.kt b/ktor-utils/common/src/io/ktor/util/NonceManager.kt index 810722524a1..c2d74a9b46f 100644 --- a/ktor-utils/common/src/io/ktor/util/NonceManager.kt +++ b/ktor-utils/common/src/io/ktor/util/NonceManager.kt @@ -13,15 +13,22 @@ import io.ktor.utils.io.* * Depending on it's underlying implementation it could be stateful or stateless. * Note that there is usually some timeout for nonce values to reduce memory usage and to avoid replay attacks. * Nonce length is unspecified. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.NonceManager) */ public interface NonceManager { /** * Generate new nonce instance + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.NonceManager.newNonce) */ public suspend fun newNonce(): String /** * Verify [nonce] value + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.NonceManager.verifyNonce) + * * @return `true` if [nonce] is valid */ public suspend fun verifyNonce(nonce: String): Boolean @@ -29,6 +36,8 @@ public interface NonceManager { /** * This implementation does only generate nonce values but doesn't validate them. This is recommended for testing only. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.GenerateOnlyNonceManager) */ public object GenerateOnlyNonceManager : NonceManager { override suspend fun newNonce(): String { diff --git a/ktor-utils/common/src/io/ktor/util/Ranges.kt b/ktor-utils/common/src/io/ktor/util/Ranges.kt index 01776e2d385..256061be7a3 100644 --- a/ktor-utils/common/src/io/ktor/util/Ranges.kt +++ b/ktor-utils/common/src/io/ktor/util/Ranges.kt @@ -6,6 +6,8 @@ package io.ktor.util /** * Returns `true` if [other] range is fully contained inside [this] range + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.contains) */ public operator fun LongRange.contains(other: LongRange): Boolean = other.first >= start && other.last <= endInclusive diff --git a/ktor-utils/common/src/io/ktor/util/StringValues.kt b/ktor-utils/common/src/io/ktor/util/StringValues.kt index 7d625196f5d..7376e4b6236 100644 --- a/ktor-utils/common/src/io/ktor/util/StringValues.kt +++ b/ktor-utils/common/src/io/ktor/util/StringValues.kt @@ -6,16 +6,23 @@ package io.ktor.util /** * Provides data structure for associating a [String] with a [List] of Strings + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.StringValues) */ public interface StringValues { public companion object { /** * Empty [StringValues] instance + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.StringValues.Companion.Empty) */ public val Empty: StringValues = StringValuesImpl() /** * Builds a [StringValues] instance with the given [builder] function + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.StringValues.Companion.build) + * * @param caseInsensitiveName specifies if map should have case-sensitive or case-insensitive names * @param builder specifies a function to build a map */ @@ -27,36 +34,50 @@ public interface StringValues { /** * Specifies if map has case-sensitive or case-insensitive names + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.StringValues.caseInsensitiveName) */ public val caseInsensitiveName: Boolean /** * Gets first value from the list of values associated with a [name], or null if the name is not present + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.StringValues.get) */ public operator fun get(name: String): String? = getAll(name)?.firstOrNull() /** * Gets all values associated with the [name], or null if the name is not present + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.StringValues.getAll) */ public fun getAll(name: String): List? /** * Gets all names from the map + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.StringValues.names) */ public fun names(): Set /** * Gets all entries from the map + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.StringValues.entries) */ public fun entries(): Set>> /** * Checks if the given [name] exists in the map + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.StringValues.contains) */ public operator fun contains(name: String): Boolean = getAll(name) != null /** * Checks if the given [name] and [value] pair exists in the map + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.StringValues.contains) */ public fun contains(name: String, value: String): Boolean = getAll(name)?.contains(value) ?: false @@ -64,11 +85,15 @@ public interface StringValues { * Iterates over all entries in this map and calls [body] for each pair * * Can be optimized in implementations + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.StringValues.forEach) */ public fun forEach(body: (String, List) -> Unit): Unit = entries().forEach { (k, v) -> body(k, v) } /** * Checks if this map is empty + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.StringValues.isEmpty) */ public fun isEmpty(): Boolean } @@ -289,6 +314,8 @@ public open class StringValuesBuilderImpl( /** * Build an instance of [StringValues] from a vararg list of pairs + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.valuesOf) */ public fun valuesOf(vararg pairs: Pair>, caseInsensitiveKey: Boolean = false): StringValues { return StringValuesImpl(caseInsensitiveKey, pairs.asList().toMap()) @@ -296,6 +323,8 @@ public fun valuesOf(vararg pairs: Pair>, caseInsensitiveKey /** * Build an instance of [StringValues] from a single pair + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.valuesOf) */ public fun valuesOf(name: String, value: String, caseInsensitiveKey: Boolean = false): StringValues { return StringValuesSingleImpl(caseInsensitiveKey, name, listOf(value)) @@ -303,6 +332,8 @@ public fun valuesOf(name: String, value: String, caseInsensitiveKey: Boolean = f /** * Build an instance of [StringValues] with a single [name] and multiple [values] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.valuesOf) */ public fun valuesOf(name: String, values: List, caseInsensitiveKey: Boolean = false): StringValues { return StringValuesSingleImpl(caseInsensitiveKey, name, values) @@ -310,11 +341,15 @@ public fun valuesOf(name: String, values: List, caseInsensitiveKey: Bool /** * Build an empty [StringValues] instance. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.valuesOf) */ public fun valuesOf(): StringValues = StringValues.Empty /** * Build an instance of [StringValues] from the specified [map] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.valuesOf) */ public fun valuesOf(map: Map>, caseInsensitiveKey: Boolean = false): StringValues { val size = map.size @@ -330,12 +365,16 @@ public fun valuesOf(map: Map>, caseInsensitiveKey: Bool /** * Copy values to a new independent map + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.toMap) */ public fun StringValues.toMap(): Map> = entries().associateByTo(LinkedHashMap(), { it.key }, { it.value.toList() }) /** * Copy values to a list of pairs + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.flattenEntries) */ public fun StringValues.flattenEntries(): List> = entries().flatMap { e -> e.value.map { e.key to it } @@ -343,6 +382,8 @@ public fun StringValues.flattenEntries(): List> = entries() /** * Invoke [block] function for every value pair + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.flattenForEach) */ public fun StringValues.flattenForEach(block: (String, String) -> Unit): Unit = forEach { name, items -> items.forEach { block(name, it) } @@ -350,6 +391,9 @@ public fun StringValues.flattenForEach(block: (String, String) -> Unit): Unit = /** * Create a new instance of [StringValues] filtered by the specified [predicate] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.filter) + * * @param keepEmpty when `true` will keep empty lists otherwise keys with no values will be discarded */ public fun StringValues.filter(keepEmpty: Boolean = false, predicate: (String, String) -> Boolean): StringValues { @@ -369,6 +413,9 @@ public fun StringValues.filter(keepEmpty: Boolean = false, predicate: (String, S /** * Append values from [source] filtering values by the specified [predicate] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.appendFiltered) + * * @param keepEmpty when `true` will keep empty lists otherwise keys with no values will be discarded */ public fun StringValuesBuilder.appendFiltered( @@ -386,6 +433,8 @@ public fun StringValuesBuilder.appendFiltered( /** * Append all values from the specified [builder] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.appendAll) */ public fun StringValuesBuilder.appendAll(builder: StringValuesBuilder): StringValuesBuilder = apply { builder.entries().forEach { (name, values) -> @@ -395,6 +444,8 @@ public fun StringValuesBuilder.appendAll(builder: StringValuesBuilder): StringVa /** * Appends [name] [value] pair if there are no values associated with [name] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.appendIfNameAbsent) */ public fun StringValuesBuilder.appendIfNameAbsent(name: String, value: String): StringValuesBuilder = apply { if (contains(name)) return@apply @@ -403,6 +454,8 @@ public fun StringValuesBuilder.appendIfNameAbsent(name: String, value: String): /** * Appends [name] [value] pair if there is no existing [name] [value] pair + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.appendIfNameAndValueAbsent) */ public fun StringValuesBuilder.appendIfNameAndValueAbsent(name: String, value: String): StringValuesBuilder = apply { if (contains(name, value)) return@apply diff --git a/ktor-utils/common/src/io/ktor/util/Text.kt b/ktor-utils/common/src/io/ktor/util/Text.kt index 38474f40231..8004f5a41ea 100644 --- a/ktor-utils/common/src/io/ktor/util/Text.kt +++ b/ktor-utils/common/src/io/ktor/util/Text.kt @@ -6,6 +6,8 @@ package io.ktor.util /** * Escapes the characters in a String using HTML entities + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.escapeHTML) */ public fun String.escapeHTML(): String { val text = this@escapeHTML @@ -29,6 +31,8 @@ public fun String.escapeHTML(): String { * Splits the given string into two parts before and after separator. * * Useful together with destructuring declarations + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.chomp) */ public inline fun String.chomp( separator: String, @@ -43,6 +47,8 @@ public inline fun String.chomp( /** * Does the same as the regular [toLowerCase] except that locale-specific rules are not applied to ASCII characters * so latin characters are converted by the original english rules. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.toLowerCasePreservingASCIIRules) */ public fun String.toLowerCasePreservingASCIIRules(): String { val firstIndex = indexOfFirst { @@ -66,6 +72,8 @@ public fun String.toLowerCasePreservingASCIIRules(): String { /** * Does the same as the regular [toUpperCase] except that locale-specific rules are not applied to ASCII characters * so latin characters are converted by the original english rules. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.toUpperCasePreservingASCIIRules) */ public fun String.toUpperCasePreservingASCIIRules(): String { val firstIndex = indexOfFirst { diff --git a/ktor-utils/common/src/io/ktor/util/Throwable.kt b/ktor-utils/common/src/io/ktor/util/Throwable.kt index 5b6b9e119c7..ccd0d0cf4ff 100644 --- a/ktor-utils/common/src/io/ktor/util/Throwable.kt +++ b/ktor-utils/common/src/io/ktor/util/Throwable.kt @@ -8,6 +8,8 @@ import io.ktor.utils.io.* /** * Root cause of the [Throwable]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.rootCause) */ @InternalAPI public val Throwable.rootCause: Throwable? diff --git a/ktor-utils/common/src/io/ktor/util/cio/Channels.kt b/ktor-utils/common/src/io/ktor/util/cio/Channels.kt index a619f74d9a2..1f0927afb06 100644 --- a/ktor-utils/common/src/io/ktor/util/cio/Channels.kt +++ b/ktor-utils/common/src/io/ktor/util/cio/Channels.kt @@ -9,12 +9,16 @@ import kotlinx.io.IOException /** * An exception thrown when an IO error occurred during reading or writing to/from the underlying channel. * The typical error is "connection reset" and so on. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.cio.ChannelIOException) */ public open class ChannelIOException(message: String, exception: Throwable) : IOException(message, exception) /** * An exception that is thrown when an IO error occurred during writing to the destination channel. * Usually it happens when a remote client closed the connection. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.cio.ChannelWriteException) */ public class ChannelWriteException(message: String = "Cannot write to channel", exception: Throwable) : ChannelIOException(message, exception) @@ -22,6 +26,8 @@ public class ChannelWriteException(message: String = "Cannot write to channel", /** * An exception that is thrown when an IO error occurred during reading from the request channel. * Usually it happens when a remote client closed the connection. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.cio.ChannelReadException) */ public class ChannelReadException( message: String = "Cannot read from a channel", diff --git a/ktor-utils/common/src/io/ktor/util/cio/Readers.kt b/ktor-utils/common/src/io/ktor/util/cio/Readers.kt index cd1cbfe8fe2..a2b7a1cd260 100644 --- a/ktor-utils/common/src/io/ktor/util/cio/Readers.kt +++ b/ktor-utils/common/src/io/ktor/util/cio/Readers.kt @@ -11,6 +11,8 @@ import kotlin.contracts.* /** * Convert [ByteReadChannel] to [ByteArray] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.cio.toByteArray) */ public suspend fun ByteReadChannel.toByteArray(limit: Int = Int.MAX_VALUE): ByteArray = @@ -18,6 +20,8 @@ public suspend fun ByteReadChannel.toByteArray(limit: Int = Int.MAX_VALUE): Byte /** * Executes [block] on [ByteWriteChannel] and close it down correctly whether an exception + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.cio.use) */ @OptIn(ExperimentalContracts::class) diff --git a/ktor-utils/common/src/io/ktor/util/collections/ConcurrentMap.kt b/ktor-utils/common/src/io/ktor/util/collections/ConcurrentMap.kt index ed8830e2b8e..218a927eff1 100644 --- a/ktor-utils/common/src/io/ktor/util/collections/ConcurrentMap.kt +++ b/ktor-utils/common/src/io/ktor/util/collections/ConcurrentMap.kt @@ -8,6 +8,8 @@ internal const val INITIAL_CAPACITY = 32 /** * Ktor concurrent map implementation. Please do not use it. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.collections.ConcurrentMap) */ public expect class ConcurrentMap( initialCapacity: Int = INITIAL_CAPACITY @@ -15,11 +17,15 @@ public expect class ConcurrentMap( /** * Computes [block] and inserts result in map. The [block] will be evaluated at most once. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.collections.ConcurrentMap.computeIfAbsent) */ public fun computeIfAbsent(key: Key, block: () -> Value): Value /** * Removes [key] from map if it is mapped to [value]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.collections.ConcurrentMap.remove) */ public fun remove(key: Key, value: Value): Boolean diff --git a/ktor-utils/common/src/io/ktor/util/collections/ConcurrentSet.kt b/ktor-utils/common/src/io/ktor/util/collections/ConcurrentSet.kt index 9bad0ddbc90..6b1b9e644d6 100644 --- a/ktor-utils/common/src/io/ktor/util/collections/ConcurrentSet.kt +++ b/ktor-utils/common/src/io/ktor/util/collections/ConcurrentSet.kt @@ -6,6 +6,8 @@ package io.ktor.util.collections /** * Concurrent set implemented on top of [ConcurrentMap] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.collections.ConcurrentSet) */ @Suppress("FunctionName") public fun ConcurrentSet(): MutableSet = object : MutableSet { diff --git a/ktor-utils/common/src/io/ktor/util/collections/CopyOnWriteHashMap.kt b/ktor-utils/common/src/io/ktor/util/collections/CopyOnWriteHashMap.kt index ada3e67859e..dfd14b5e1cc 100644 --- a/ktor-utils/common/src/io/ktor/util/collections/CopyOnWriteHashMap.kt +++ b/ktor-utils/common/src/io/ktor/util/collections/CopyOnWriteHashMap.kt @@ -11,12 +11,17 @@ import kotlinx.atomicfu.* /** * This is an internal implementation for copy-on-write concurrent map. * It is very limited since it is not intended as general purpose implementation. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.collections.CopyOnWriteHashMap) */ @InternalAPI public class CopyOnWriteHashMap { private val current = atomic(emptyMap()) /** + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.collections.CopyOnWriteHashMap.put) + * * @see MutableMap.put */ public fun put(key: K, value: V): V? { @@ -31,18 +36,26 @@ public class CopyOnWriteHashMap { } /** + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.collections.CopyOnWriteHashMap.get) + * * @see Map.get */ public operator fun get(key: K): V? = current.value[key] /** * Operator function for array access syntax + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.collections.CopyOnWriteHashMap.set) */ public operator fun set(key: K, value: V) { put(key, value) } /** + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.collections.CopyOnWriteHashMap.remove) + * * @see MutableMap.remove */ public fun remove(key: K): V? { @@ -57,6 +70,9 @@ public class CopyOnWriteHashMap { } /** + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.collections.CopyOnWriteHashMap.computeIfAbsent) + * * @see MutableMap.computeIfAbsent */ public fun computeIfAbsent(key: K, producer: (key: K) -> V): V { diff --git a/ktor-utils/common/src/io/ktor/util/converters/ConversionService.kt b/ktor-utils/common/src/io/ktor/util/converters/ConversionService.kt index e898205ad5d..f8d45ce4182 100644 --- a/ktor-utils/common/src/io/ktor/util/converters/ConversionService.kt +++ b/ktor-utils/common/src/io/ktor/util/converters/ConversionService.kt @@ -9,21 +9,29 @@ import kotlin.reflect.* /** * Data conversion service that does serialization and deserialization to/from list of strings + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.converters.ConversionService) */ public interface ConversionService { /** * Deserialize [values] to an instance of [type] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.converters.ConversionService.fromValues) */ public fun fromValues(values: List, type: TypeInfo): Any? /** * Serialize a [value] to values list + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.converters.ConversionService.toValues) */ public fun toValues(value: Any?): List } /** * The default conversion service that supports only basic types and enums + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.converters.DefaultConversionService) */ public object DefaultConversionService : ConversionService { override fun toValues(value: Any?): List { @@ -112,5 +120,7 @@ internal expect fun platformDefaultToValues(value: Any): List? /** * Thrown when failed to convert value + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.converters.DataConversionException) */ public open class DataConversionException(message: String = "Invalid data format") : Exception(message) diff --git a/ktor-utils/common/src/io/ktor/util/converters/DataConversion.kt b/ktor-utils/common/src/io/ktor/util/converters/DataConversion.kt index 0c53198d864..069b49ac828 100644 --- a/ktor-utils/common/src/io/ktor/util/converters/DataConversion.kt +++ b/ktor-utils/common/src/io/ktor/util/converters/DataConversion.kt @@ -11,6 +11,8 @@ import kotlin.reflect.* /** * Data conversion plugin to serialize and deserialize types using [converters] registry + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.converters.DataConversion) */ public class DataConversion(configuration: Configuration) : ConversionService { private val converters: Map, ConversionService> = configuration.converters.toMap() @@ -31,6 +33,8 @@ public class DataConversion(configuration: Configuration) : ConversionService { /** * Data conversion service configuration + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.converters.DataConversion.Configuration) */ @KtorDsl public class Configuration { @@ -38,6 +42,8 @@ public class DataConversion(configuration: Configuration) : ConversionService { /** * Register a [convertor] for [type] type + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.converters.DataConversion.Configuration.convert) */ public fun convert(type: KClass<*>, convertor: ConversionService) { converters[type] = convertor @@ -45,6 +51,8 @@ public class DataConversion(configuration: Configuration) : ConversionService { /** * Register and [configure] convertor for type [klass] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.converters.DataConversion.Configuration.convert) */ @Suppress("UNCHECKED_CAST") public fun convert(type: KType, configure: DelegatingConversionService.Configuration.() -> Unit) { @@ -61,6 +69,8 @@ public class DataConversion(configuration: Configuration) : ConversionService { /** * Register and [configure] convertor for reified type [T] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.converters.DataConversion.Configuration.convert) */ public inline fun convert( noinline configure: DelegatingConversionService.Configuration.() -> Unit @@ -70,6 +80,8 @@ public class DataConversion(configuration: Configuration) : ConversionService { /** * Implementation of [ConversionService] that delegates [fromValues] and [toValues] to [decoder] and [encoder] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.converters.DelegatingConversionService) */ public class DelegatingConversionService( private val klass: KClass<*>, @@ -89,6 +101,8 @@ public class DelegatingConversionService( /** * Custom convertor builder to be used in [DataConversion.Configuration] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.converters.DelegatingConversionService.Configuration) */ public class Configuration @PublishedApi internal constructor(internal val klass: KClass) { @@ -97,6 +111,9 @@ public class DelegatingConversionService( /** * Configure decoder function. Only one decoder could be supplied + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.converters.DelegatingConversionService.Configuration.decode) + * * @throws IllegalStateException */ public fun decode(converter: (values: List) -> T) { @@ -106,6 +123,9 @@ public class DelegatingConversionService( /** * Configure encoder function. Only one encoder could be supplied + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.converters.DelegatingConversionService.Configuration.encode) + * * @throws IllegalStateException */ public fun encode(converter: (value: T) -> List) { diff --git a/ktor-utils/common/src/io/ktor/util/date/Date.kt b/ktor-utils/common/src/io/ktor/util/date/Date.kt index 885b8fd076b..290a4431c7e 100644 --- a/ktor-utils/common/src/io/ktor/util/date/Date.kt +++ b/ktor-utils/common/src/io/ktor/util/date/Date.kt @@ -12,6 +12,8 @@ import kotlin.time.* /** * Day of week * [value] is 3 letter shortcut + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.date.WeekDay) */ public enum class WeekDay(public val value: String) { MONDAY("Mon"), @@ -25,11 +27,15 @@ public enum class WeekDay(public val value: String) { public companion object { /** * Lookup an instance by [ordinal] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.date.WeekDay.Companion.from) */ public fun from(ordinal: Int): WeekDay = entries[ordinal] /** * Lookup an instance by short week day name [WeekDay.value] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.date.WeekDay.Companion.from) */ public fun from(value: String): WeekDay = entries.find { it.value == value } ?: error("Invalid day of week: $value") @@ -39,6 +45,8 @@ public enum class WeekDay(public val value: String) { /** * Month * [value] is 3 letter shortcut + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.date.Month) */ public enum class Month(public val value: String) { JANUARY("Jan"), @@ -57,11 +65,15 @@ public enum class Month(public val value: String) { public companion object { /** * Lookup an instance by [ordinal] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.date.Month.Companion.from) */ public fun from(ordinal: Int): Month = entries[ordinal] /** * Lookup an instance by short month name [Month.value] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.date.Month.Companion.from) */ public fun from(value: String): Month = entries.find { it.value == value } ?: error("Invalid month: $value") @@ -71,6 +83,9 @@ public enum class Month(public val value: String) { /** * Date in GMT timezone * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.date.GMTDate) + * * @property seconds: seconds from 0 to 60(last is for leap second) * @property minutes: minutes from 0 to 59 * @property hours: hours from 0 to 23 @@ -105,6 +120,8 @@ public data class GMTDate( public companion object { /** * An instance of [GMTDate] corresponding to the epoch beginning + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.date.GMTDate.Companion.START) */ public val START: GMTDate = GMTDate(0) } @@ -112,41 +129,58 @@ public data class GMTDate( /** * Create new gmt date from the [timestamp]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.date.GMTDate) + * * @param timestamp is a number of epoch milliseconds (it is `now` by default). */ public expect fun GMTDate(timestamp: Long? = null): GMTDate /** * Create an instance of [GMTDate] from the specified date/time components + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.date.GMTDate) */ public expect fun GMTDate(seconds: Int, minutes: Int, hours: Int, dayOfMonth: Int, month: Month, year: Int): GMTDate /** * Adds the specified number of [milliseconds] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.date.plus) */ public operator fun GMTDate.plus(milliseconds: Long): GMTDate = GMTDate(timestamp + milliseconds) /** * Subtracts the specified number of [milliseconds] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.date.minus) */ public operator fun GMTDate.minus(milliseconds: Long): GMTDate = GMTDate(timestamp - milliseconds) /** * Adds the specified [duration] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.date.plus) */ public operator fun GMTDate.plus(duration: Duration): GMTDate = GMTDate(timestamp + duration.inWholeMilliseconds) /** * Subtracts the specified [duration] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.date.minus) */ public operator fun GMTDate.minus(duration: Duration): GMTDate = GMTDate(timestamp - duration.inWholeMilliseconds) /** * Truncate to seconds by discarding sub-second part + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.date.truncateToSeconds) */ public fun GMTDate.truncateToSeconds(): GMTDate = GMTDate(seconds, minutes, hours, dayOfMonth, month, year) /** * Gets current system time in milliseconds since certain moment in the past, only delta between two subsequent calls makes sense. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.date.getTimeMillis) */ public expect fun getTimeMillis(): Long diff --git a/ktor-utils/common/src/io/ktor/util/date/GMTDateParser.kt b/ktor-utils/common/src/io/ktor/util/date/GMTDateParser.kt index b77cb603ba8..11c7fe53dc8 100644 --- a/ktor-utils/common/src/io/ktor/util/date/GMTDateParser.kt +++ b/ktor-utils/common/src/io/ktor/util/date/GMTDateParser.kt @@ -16,6 +16,8 @@ package io.ktor.util.date * | Month | M | parse month from Jan to Dec(see [Month] for details) | * | Year | Y | parse year | * | Any char | * | Match any character | + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.date.GMTDateParser) */ public class GMTDateParser(private val pattern: String) { init { @@ -24,6 +26,8 @@ public class GMTDateParser(private val pattern: String) { /** * Parse [GMTDate] from [dateString] using [pattern]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.date.GMTDateParser.parse) */ public fun parse(dateString: String): GMTDate { val builder = GMTDateBuilder() @@ -119,6 +123,8 @@ internal class GMTDateBuilder { /** * Thrown when the date string doesn't the string pattern. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.date.InvalidDateStringException) */ public class InvalidDateStringException( data: String, diff --git a/ktor-utils/common/src/io/ktor/util/debug/ContextUtils.kt b/ktor-utils/common/src/io/ktor/util/debug/ContextUtils.kt index a77a49ddf56..0940c277f08 100644 --- a/ktor-utils/common/src/io/ktor/util/debug/ContextUtils.kt +++ b/ktor-utils/common/src/io/ktor/util/debug/ContextUtils.kt @@ -10,6 +10,8 @@ import kotlin.coroutines.* /** * Initialize plugins debug mode for [block] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.debug.initContextInDebugMode) */ public suspend fun initContextInDebugMode( block: suspend () -> T @@ -22,6 +24,8 @@ public suspend fun initContextInDebugMode( /** * Adds [pluginName] to the current [CoroutineContext] if Intellij JVM debugger is attached. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.debug.addToContextInDebugMode) */ public suspend fun addToContextInDebugMode( pluginName: String, @@ -36,6 +40,8 @@ public suspend fun addToContextInDebugMode( /** * Performs [action] on the current element of the [CoroutineContext] with the given [key] if Intellij JVM debugger is * attached. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.debug.useContextElementInDebugMode) * */ public suspend fun useContextElementInDebugMode( key: CoroutineContext.Key, diff --git a/ktor-utils/common/src/io/ktor/util/debug/plugins/PluginName.kt b/ktor-utils/common/src/io/ktor/util/debug/plugins/PluginName.kt index 945a0289c59..02e1d37c710 100644 --- a/ktor-utils/common/src/io/ktor/util/debug/plugins/PluginName.kt +++ b/ktor-utils/common/src/io/ktor/util/debug/plugins/PluginName.kt @@ -9,6 +9,8 @@ import kotlin.coroutines.CoroutineContext /** * Name of the Ktor plugin that is currently being invoked. This name is used in debugging mode. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.debug.plugins.PluginName) */ public data class PluginName( /** @@ -18,11 +20,15 @@ public data class PluginName( ) : AbstractCoroutineContextElement(PluginName) { /** * Key for [PluginName] instance in the coroutine context. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.debug.plugins.PluginName.Key) */ public companion object Key : CoroutineContext.Key /** * Returns a string representation of the object. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.debug.plugins.PluginName.toString) */ override fun toString(): String = "PluginName($pluginName)" } diff --git a/ktor-utils/common/src/io/ktor/util/debug/plugins/PluginsTrace.kt b/ktor-utils/common/src/io/ktor/util/debug/plugins/PluginsTrace.kt index a6ee4737883..0fe34bb087e 100644 --- a/ktor-utils/common/src/io/ktor/util/debug/plugins/PluginsTrace.kt +++ b/ktor-utils/common/src/io/ktor/util/debug/plugins/PluginsTrace.kt @@ -9,6 +9,8 @@ import kotlin.coroutines.* /** * Contains information of all the plugins that have been executed during the current call. * Is used in Intellij Idea debugger to show plugin execution order. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.debug.plugins.PluginsTrace) */ public data class PluginsTrace( /** @@ -19,11 +21,15 @@ public data class PluginsTrace( /** * Key for [PluginsTrace] instance in the coroutine context. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.debug.plugins.PluginsTrace.Key) */ public companion object Key : CoroutineContext.Key /** * Returns a string representation of the object. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.debug.plugins.PluginsTrace.toString) */ override fun toString(): String = "PluginsTrace(${eventOrder.joinToString()})" } @@ -31,6 +37,8 @@ public data class PluginsTrace( /** * Contains information about the plugin and handler (onCall, onReceive, and so on) that is currently being executed. * Is used in Intellij Idea debugger to show plugin execution order. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.debug.plugins.PluginTraceElement) * */ public data class PluginTraceElement(val pluginName: String, val handler: String, val event: PluginEvent) { public enum class PluginEvent { diff --git a/ktor-utils/common/src/io/ktor/util/internal/ExceptionUtils.kt b/ktor-utils/common/src/io/ktor/util/internal/ExceptionUtils.kt index d7bf04dda11..fafd0f71963 100644 --- a/ktor-utils/common/src/io/ktor/util/internal/ExceptionUtils.kt +++ b/ktor-utils/common/src/io/ktor/util/internal/ExceptionUtils.kt @@ -6,5 +6,7 @@ package io.ktor.util.internal /** * Internal helper for setting cause on [Throwable] in MPP + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.internal.initCauseBridge) */ public expect fun Throwable.initCauseBridge(cause: Throwable) diff --git a/ktor-utils/common/src/io/ktor/util/internal/LockFreeLinkedList.kt b/ktor-utils/common/src/io/ktor/util/internal/LockFreeLinkedList.kt index edd2a6c3b7c..c73df71e549 100644 --- a/ktor-utils/common/src/io/ktor/util/internal/LockFreeLinkedList.kt +++ b/ktor-utils/common/src/io/ktor/util/internal/LockFreeLinkedList.kt @@ -34,13 +34,25 @@ internal val LIST_EMPTY: Any = Symbol("LIST_EMPTY") private val REMOVE_PREPARED: Any = Symbol("REMOVE_PREPARED") -/** @suppress **This is unstable API and it is subject to change.** */ +/** + * @suppress **This is unstable API and it is subject to change.** + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.internal.RemoveFirstDesc) + */ public typealias RemoveFirstDesc = LockFreeLinkedListNode.RemoveFirstDesc -/** @suppress **This is unstable API and it is subject to change.** */ +/** + * @suppress **This is unstable API and it is subject to change.** + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.internal.AddLastDesc) + */ public typealias AddLastDesc = LockFreeLinkedListNode.AddLastDesc -/** @suppress **This is unstable API and it is subject to change.** */ +/** + * @suppress **This is unstable API and it is subject to change.** + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.internal.AbstractAtomicDesc) + */ public typealias AbstractAtomicDesc = LockFreeLinkedListNode.AbstractAtomicDesc private class Symbol(val symbol: String) { @@ -51,12 +63,17 @@ private class Symbol(val symbol: String) { * The most abstract operation that can be in process. Other threads observing an instance of this * class in the fields of their object shall invoke [perform] to help. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.internal.OpDescriptor) + * * @suppress **This is unstable API and it is subject to change.** */ public abstract class OpDescriptor { /** * Returns `null` is operation was performed successfully or some other * object that indicates the failure reason. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.internal.OpDescriptor.perform) */ public abstract fun perform(affected: Any?): Any? } @@ -72,6 +89,9 @@ private val NO_DECISION: Any = Symbol("NO_DECISION") * Note: parts of atomic operation must be globally ordered. Otherwise, this implementation will produce * `StackOverflowError`. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.internal.AtomicOp) + * * @suppress **This is unstable API and it is subject to change.** */ public abstract class AtomicOp : OpDescriptor() { @@ -107,6 +127,9 @@ public abstract class AtomicOp : OpDescriptor() { /** * A part of multi-step atomic operation [AtomicOp]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.internal.AtomicDesc) + * * @suppress **This is unstable API and it is subject to change.** */ public abstract class AtomicDesc { @@ -131,6 +154,9 @@ public abstract class AtomicDesc { * efficiently linearize them with atomic multi-step head-removal operations. In short, * support for [describeRemoveFirst] operation precludes ability to add items at the beginning. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.internal.LockFreeLinkedListNode) + * * @suppress **This is unstable API and it is subject to change.** */ @Suppress("LeakingThis") @@ -219,6 +245,8 @@ public open class LockFreeLinkedListNode { /** * Adds last item to this list. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.internal.LockFreeLinkedListNode.addLast) */ public fun addLast(node: Node) { while (true) { // lock-free loop on prev.next @@ -231,6 +259,8 @@ public open class LockFreeLinkedListNode { /** * Adds last item to this list atomically if the [condition] is true. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.internal.LockFreeLinkedListNode.addLastIf) */ public inline fun addLastIf(node: Node, crossinline condition: () -> Boolean): Boolean { val condAdd = makeCondAddOp(node, condition) @@ -254,6 +284,9 @@ public open class LockFreeLinkedListNode { /** * Adds the specified [node] at the end of the list atomically if the previous node matches the given [predicate]. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.internal.LockFreeLinkedListNode.addLastIfPrevAndIf) + * * @param node the node to be added * @param predicate a function that evaluates the previous node * @param condition an atomic condition that must be `true` for the node to be added @@ -331,6 +364,8 @@ public open class LockFreeLinkedListNode { * **Note**: Invocation of this operation does not guarantee that remove was actually complete if result was `false`. * In particular, invoking [nextNode].[prevNode] might still return this node even though it is "already removed". * Invoke [helpRemove] to make sure that remove was completed. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.internal.LockFreeLinkedListNode.remove) */ public open fun remove(): Boolean { while (true) { // lock-free loop on next @@ -780,6 +815,9 @@ internal fun Any.unwrap(): Node = (this as? Removed)?.ref ?: this as Node /** * Head (sentinel) item of the linked list that is never removed. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.internal.LockFreeLinkedListHead) + * * @suppress **This is unstable API and it is subject to change.** */ public open class LockFreeLinkedListHead : LockFreeLinkedListNode() { @@ -787,6 +825,8 @@ public open class LockFreeLinkedListHead : LockFreeLinkedListNode() { /** * Iterates over all elements in this list of a specified type. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.internal.LockFreeLinkedListHead.forEach) */ public inline fun forEach(block: (T) -> Unit) { var cur: Node = next as Node diff --git a/ktor-utils/common/src/io/ktor/util/logging/Logger.kt b/ktor-utils/common/src/io/ktor/util/logging/Logger.kt index df152d51403..ab12d2bb6ac 100644 --- a/ktor-utils/common/src/io/ktor/util/logging/Logger.kt +++ b/ktor-utils/common/src/io/ktor/util/logging/Logger.kt @@ -21,6 +21,8 @@ public expect val Logger.isTraceEnabled: Boolean /** * Logs an error from an [exception] using its message + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.logging.error) */ public fun Logger.error(exception: Throwable) { error(exception.message ?: "Exception of type ${exception::class}", exception) @@ -28,6 +30,8 @@ public fun Logger.error(exception: Throwable) { /** * Check `isTraceEnabled` flag before logging to save some memory allocations. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.logging.trace) */ public inline fun Logger.trace(message: () -> String) { if (isTraceEnabled) trace(message()) diff --git a/ktor-utils/common/src/io/ktor/util/network/NetworkAddress.kt b/ktor-utils/common/src/io/ktor/util/network/NetworkAddress.kt index 829fcc0e612..b473f3322b2 100644 --- a/ktor-utils/common/src/io/ktor/util/network/NetworkAddress.kt +++ b/ktor-utils/common/src/io/ktor/util/network/NetworkAddress.kt @@ -9,6 +9,9 @@ package io.ktor.util.network * * The address will be resolved after construction. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.network.NetworkAddress) + * * @throws UnresolvedAddressException if the [hostname] cannot be resolved. */ public expect abstract class NetworkAddress @@ -18,24 +21,33 @@ public expect abstract class NetworkAddress * * The address will be resolved after construction. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.network.NetworkAddress) + * * @throws UnresolvedAddressException if the [hostname] cannot be resolved. */ public expect fun NetworkAddress(hostname: String, port: Int): NetworkAddress /** * Network address hostname. This may trigger a reverse lookup. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.network.hostname) */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER") public expect val NetworkAddress.hostname: String /** * Network address. Usually, it's an IP address in string form. This will not trigger a reverse lookup. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.network.address) */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER") public expect val NetworkAddress.address: String /** * Network address port. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.network.port) */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER") public expect val NetworkAddress.port: Int diff --git a/ktor-utils/common/src/io/ktor/util/pipeline/Pipeline.kt b/ktor-utils/common/src/io/ktor/util/pipeline/Pipeline.kt index a03265f5637..9cabc2b9bf6 100644 --- a/ktor-utils/common/src/io/ktor/util/pipeline/Pipeline.kt +++ b/ktor-utils/common/src/io/ktor/util/pipeline/Pipeline.kt @@ -26,6 +26,8 @@ internal expect fun pipelineStartCoroutineUnint /** * Represents an execution pipeline for asynchronous extensible computations + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.pipeline.Pipeline) */ public open class Pipeline( @@ -33,11 +35,15 @@ public open class Pipeline( ) { /** * Provides common place to store pipeline attributes + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.pipeline.Pipeline.attributes) */ public val attributes: Attributes = Attributes(concurrent = true) /** * Indicated if debug mode is enabled. In debug mode users will get more details in the stacktrace. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.pipeline.Pipeline.developmentMode) */ public open val developmentMode: Boolean = false @@ -47,6 +53,8 @@ public open class Pipeline( /** * Phases of this pipeline + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.pipeline.Pipeline.items) */ public val items: List get() = phasesRaw.map { @@ -54,6 +62,9 @@ public open class Pipeline( } /** + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.pipeline.Pipeline.isEmpty) + * * @return `true` if there are no interceptors installed regardless number of phases */ public val isEmpty: Boolean @@ -74,12 +85,16 @@ public open class Pipeline( /** * Executes this pipeline in the given [context] and with the given [subject] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.pipeline.Pipeline.execute) */ public suspend fun execute(context: TContext, subject: TSubject): TSubject = createContext(context, subject, coroutineContext).execute(subject) /** * Adds [phase] to the end of this pipeline + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.pipeline.Pipeline.addPhase) */ public fun addPhase(phase: PipelinePhase) { if (hasPhase(phase)) { @@ -99,6 +114,8 @@ public open class Pipeline( * pipeline.insertPhaseAfter(a, c) * assertEquals(listOf(a, b, c), pipeline.items) * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.pipeline.Pipeline.insertPhaseAfter) */ public fun insertPhaseAfter(reference: PipelinePhase, phase: PipelinePhase) { if (hasPhase(phase)) return @@ -130,6 +147,8 @@ public open class Pipeline( * pipeline.insertPhaseBefore(c, b) * assertEquals(listOf(a, b, c), pipeline.items) * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.pipeline.Pipeline.insertPhaseBefore) */ public fun insertPhaseBefore(reference: PipelinePhase, phase: PipelinePhase) { if (hasPhase(phase)) return @@ -144,6 +163,8 @@ public open class Pipeline( /** * Adds [block] to the [phase] of this pipeline + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.pipeline.Pipeline.intercept) */ public fun intercept(phase: PipelinePhase, block: PipelineInterceptor) { val phaseContent = findPhase(phase) @@ -163,6 +184,8 @@ public open class Pipeline( /** * Invoked after an interceptor has been installed + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.pipeline.Pipeline.afterIntercepted) */ public open fun afterIntercepted() { } @@ -226,6 +249,8 @@ public open class Pipeline( /** * Merges another pipeline into this pipeline, maintaining relative phases order + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.pipeline.Pipeline.merge) */ public fun merge(from: Pipeline) { if (fastPathMerge(from)) { @@ -238,6 +263,8 @@ public open class Pipeline( /** * Reset current pipeline from other. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.pipeline.Pipeline.resetFrom) */ public fun resetFrom(from: Pipeline) { phasesRaw.clear() @@ -470,6 +497,8 @@ public open class Pipeline( /** * Executes this pipeline + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.pipeline.execute) */ @Suppress("NOTHING_TO_INLINE") public suspend inline fun Pipeline.execute( @@ -484,6 +513,8 @@ public suspend inline fun Pipeline.execute( /** * Intercepts an untyped pipeline when the subject is of the given type + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.pipeline.intercept) */ public inline fun Pipeline<*, TContext>.intercept( phase: PipelinePhase, @@ -500,6 +531,8 @@ public inline fun Pipeline<*, TContext> /** * Represents an interceptor type which is a suspend extension function for a context + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.pipeline.PipelineInterceptor) */ public typealias PipelineInterceptor = suspend PipelineContext.(TSubject) -> Unit diff --git a/ktor-utils/common/src/io/ktor/util/pipeline/PipelineContext.kt b/ktor-utils/common/src/io/ktor/util/pipeline/PipelineContext.kt index 80d9bdbf843..4e284228edd 100644 --- a/ktor-utils/common/src/io/ktor/util/pipeline/PipelineContext.kt +++ b/ktor-utils/common/src/io/ktor/util/pipeline/PipelineContext.kt @@ -13,6 +13,9 @@ internal expect val DISABLE_SFG: Boolean /** * Represents running execution of a pipeline * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.pipeline.PipelineContext) + * * @param context: object representing context in which pipeline executes */ @KtorDsl @@ -22,21 +25,29 @@ public abstract class PipelineContext( /** * Subject of this pipeline execution that goes along the pipeline + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.pipeline.PipelineContext.subject) */ public abstract var subject: TSubject /** * Finishes current pipeline execution + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.pipeline.PipelineContext.finish) */ public abstract fun finish() /** * Continues execution of the pipeline with the given subject + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.pipeline.PipelineContext.proceedWith) */ public abstract suspend fun proceedWith(subject: TSubject): TSubject /** * Continues execution of the pipeline with the same subject + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.pipeline.PipelineContext.proceed) */ public abstract suspend fun proceed(): TSubject diff --git a/ktor-utils/common/src/io/ktor/util/pipeline/PipelinePhase.kt b/ktor-utils/common/src/io/ktor/util/pipeline/PipelinePhase.kt index da0a73f2d12..15049b08cd0 100644 --- a/ktor-utils/common/src/io/ktor/util/pipeline/PipelinePhase.kt +++ b/ktor-utils/common/src/io/ktor/util/pipeline/PipelinePhase.kt @@ -7,6 +7,9 @@ package io.ktor.util.pipeline /** * Represents a phase in a pipeline * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.pipeline.PipelinePhase) + * * @param name a name for this phase */ public class PipelinePhase(public val name: String) { @@ -15,5 +18,7 @@ public class PipelinePhase(public val name: String) { /** * An exception about misconfigured phases in a pipeline + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.pipeline.InvalidPhaseException) */ public class InvalidPhaseException(message: String) : Throwable(message) diff --git a/ktor-utils/common/src/io/ktor/util/reflect/Type.kt b/ktor-utils/common/src/io/ktor/util/reflect/Type.kt index d5f4189796f..3ab7e9679e6 100644 --- a/ktor-utils/common/src/io/ktor/util/reflect/Type.kt +++ b/ktor-utils/common/src/io/ktor/util/reflect/Type.kt @@ -8,6 +8,8 @@ import kotlin.reflect.* /** * Information about type. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.reflect.Type) */ @Deprecated("Not used anymore in common code as it was needed only for JVM target.") public expect interface Type @@ -18,6 +20,9 @@ public expect val KType.platformType: Type /** * Ktor type information. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.reflect.TypeInfo) + * * @property type Source KClass<*> * @property kotlinType Kotlin reified type with all generic type parameters. */ @@ -54,11 +59,15 @@ public class TypeInfo( /** * Returns [TypeInfo] for the specified type [T] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.reflect.typeInfo) */ public inline fun typeInfo(): TypeInfo = TypeInfo(T::class, typeOfOrNull()) /** * Check [this] is instance of [type]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.reflect.instanceOf) */ public expect fun Any.instanceOf(type: KClass<*>): Boolean diff --git a/ktor-utils/js/src/io/ktor/util/date/DateJs.kt b/ktor-utils/js/src/io/ktor/util/date/DateJs.kt index 15530a93039..26e333e759f 100644 --- a/ktor-utils/js/src/io/ktor/util/date/DateJs.kt +++ b/ktor-utils/js/src/io/ktor/util/date/DateJs.kt @@ -8,6 +8,9 @@ import kotlin.js.* /** * Create new gmt date from the [timestamp]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.date.GMTDate) + * * @param timestamp is a number of epoch milliseconds (it is `now` by default). */ public actual fun GMTDate(timestamp: Long?): GMTDate { @@ -40,6 +43,8 @@ public actual fun GMTDate(timestamp: Long?): GMTDate { /** * Create an instance of [GMTDate] from the specified date/time components + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.date.GMTDate) */ public actual fun GMTDate(seconds: Int, minutes: Int, hours: Int, dayOfMonth: Int, month: Month, year: Int): GMTDate { val timestamp = Date.UTC(year, month.ordinal, dayOfMonth, hours, minutes, seconds).toLong() @@ -48,6 +53,8 @@ public actual fun GMTDate(seconds: Int, minutes: Int, hours: Int, dayOfMonth: In /** * Invalid exception: possible overflow or underflow + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.date.InvalidTimestampException) */ public class InvalidTimestampException(timestamp: Long) : IllegalStateException( "Invalid date timestamp exception: $timestamp" @@ -55,5 +62,7 @@ public class InvalidTimestampException(timestamp: Long) : IllegalStateException( /** * Gets current system time in milliseconds since certain moment in the past, only delta between two subsequent calls makes sense. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.date.getTimeMillis) */ public actual fun getTimeMillis(): Long = Date().getTime().toLong() diff --git a/ktor-utils/jsAndWasmShared/src/io/ktor/util/AttributesJs.kt b/ktor-utils/jsAndWasmShared/src/io/ktor/util/AttributesJs.kt index 45688d8aa28..020a32db7ee 100644 --- a/ktor-utils/jsAndWasmShared/src/io/ktor/util/AttributesJs.kt +++ b/ktor-utils/jsAndWasmShared/src/io/ktor/util/AttributesJs.kt @@ -6,6 +6,8 @@ package io.ktor.util /** * Create ES specific [Attributes] instance. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.Attributes) */ @JsName("AttributesJsFn") public actual fun Attributes(concurrent: Boolean): Attributes = AttributesJs() diff --git a/ktor-utils/jsAndWasmShared/src/io/ktor/util/ContentEncodersJs.kt b/ktor-utils/jsAndWasmShared/src/io/ktor/util/ContentEncodersJs.kt index ff34211f0bf..5b7987cf8af 100644 --- a/ktor-utils/jsAndWasmShared/src/io/ktor/util/ContentEncodersJs.kt +++ b/ktor-utils/jsAndWasmShared/src/io/ktor/util/ContentEncodersJs.kt @@ -8,6 +8,8 @@ package io.ktor.util /** * Implementation of [ContentEncoder] using gzip algorithm + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.GZipEncoder) */ public actual object GZipEncoder : ContentEncoder, Encoder by Identity { actual override val name: String = "gzip" @@ -15,6 +17,8 @@ public actual object GZipEncoder : ContentEncoder, Encoder by Identity { /** * Implementation of [ContentEncoder] using deflate algorithm + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.DeflateEncoder) */ public actual object DeflateEncoder : ContentEncoder, Encoder by Identity { actual override val name: String = "deflate" diff --git a/ktor-utils/jsAndWasmShared/src/io/ktor/util/CryptoJs.kt b/ktor-utils/jsAndWasmShared/src/io/ktor/util/CryptoJs.kt index 144934773e3..2d201560df5 100644 --- a/ktor-utils/jsAndWasmShared/src/io/ktor/util/CryptoJs.kt +++ b/ktor-utils/jsAndWasmShared/src/io/ktor/util/CryptoJs.kt @@ -10,6 +10,8 @@ import kotlin.js.* /** * Generates a nonce string. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.generateNonce) */ public actual fun generateNonce(): String { val buffer = ByteArray(NONCE_SIZE_IN_BYTES).toJsArray() @@ -19,6 +21,8 @@ public actual fun generateNonce(): String { /** * Create [Digest] from specified hash [name]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.Digest) */ public actual fun Digest(name: String): Digest = object : Digest { private val state = mutableListOf() @@ -55,5 +59,7 @@ private external class SubtleCrypto { /** * Compute SHA-1 hash for the specified [bytes] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.sha1) */ public actual fun sha1(bytes: ByteArray): ByteArray = Sha1().digest(bytes) diff --git a/ktor-utils/jsAndWasmShared/src/io/ktor/util/collections/ConcurrentMapJs.kt b/ktor-utils/jsAndWasmShared/src/io/ktor/util/collections/ConcurrentMapJs.kt index ab18a4f3928..3ba1a43b1ac 100644 --- a/ktor-utils/jsAndWasmShared/src/io/ktor/util/collections/ConcurrentMapJs.kt +++ b/ktor-utils/jsAndWasmShared/src/io/ktor/util/collections/ConcurrentMapJs.kt @@ -6,12 +6,16 @@ package io.ktor.util.collections /** * Ktor concurrent map implementation. Please do not use it. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.collections.ConcurrentMap) */ public actual class ConcurrentMap public actual constructor(initialCapacity: Int) : MutableMap { private val delegate = LinkedHashMap(initialCapacity) /** * Computes [block] and inserts result in map. The [block] will be evaluated at most once. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.collections.ConcurrentMap.computeIfAbsent) */ public actual fun computeIfAbsent(key: Key, block: () -> Value): Value { if (delegate.containsKey(key)) return delegate[key]!! diff --git a/ktor-utils/jsAndWasmShared/src/io/ktor/util/internal/ExceptionUtilsJs.kt b/ktor-utils/jsAndWasmShared/src/io/ktor/util/internal/ExceptionUtilsJs.kt index 7babf5f4f62..f7cd15506e4 100644 --- a/ktor-utils/jsAndWasmShared/src/io/ktor/util/internal/ExceptionUtilsJs.kt +++ b/ktor-utils/jsAndWasmShared/src/io/ktor/util/internal/ExceptionUtilsJs.kt @@ -6,5 +6,7 @@ package io.ktor.util.internal /** * Internal helper for setting cause on [Throwable] in MPP + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.internal.initCauseBridge) */ public actual fun Throwable.initCauseBridge(cause: Throwable) {} diff --git a/ktor-utils/jsAndWasmShared/src/io/ktor/util/network/NetworkAddressJs.kt b/ktor-utils/jsAndWasmShared/src/io/ktor/util/network/NetworkAddressJs.kt index d8dc30ea376..aa9c89c3d48 100644 --- a/ktor-utils/jsAndWasmShared/src/io/ktor/util/network/NetworkAddressJs.kt +++ b/ktor-utils/jsAndWasmShared/src/io/ktor/util/network/NetworkAddressJs.kt @@ -9,6 +9,9 @@ package io.ktor.util.network * * The address will be resolved after construction. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.network.NetworkAddress) + * * @throws UnresolvedAddressException if the [hostname] cannot be resolved. */ public actual abstract class NetworkAddress internal constructor( @@ -19,18 +22,24 @@ public actual abstract class NetworkAddress internal constructor( /** * Network address hostname. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.network.hostname) */ public actual val NetworkAddress.hostname: String get() = hostname /** * Network address hostname. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.network.address) */ public actual val NetworkAddress.address: String get() = hostname /** * Network address port. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.network.port) */ public actual val NetworkAddress.port: Int get() = port @@ -40,6 +49,9 @@ public actual val NetworkAddress.port: Int * * The address will be resolved after construction. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.network.NetworkAddress) + * * @throws UnresolvedAddressException if the [hostname] cannot be resolved. */ public actual fun NetworkAddress(hostname: String, port: Int): NetworkAddress = diff --git a/ktor-utils/jsAndWasmShared/src/io/ktor/util/reflect/TypeInfoJs.kt b/ktor-utils/jsAndWasmShared/src/io/ktor/util/reflect/TypeInfoJs.kt index 1c879f4e7b7..3b45f34ff7b 100644 --- a/ktor-utils/jsAndWasmShared/src/io/ktor/util/reflect/TypeInfoJs.kt +++ b/ktor-utils/jsAndWasmShared/src/io/ktor/util/reflect/TypeInfoJs.kt @@ -19,6 +19,8 @@ public fun typeInfoImpl(reifiedType: Type, kClass: KClass<*>, kType: KType?): Ty /** * Check [this] is instance of [type]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.reflect.instanceOf) */ public actual fun Any.instanceOf(type: KClass<*>): Boolean = type.isInstance(this) diff --git a/ktor-utils/jvm/src/io/ktor/util/AttributesJvm.kt b/ktor-utils/jvm/src/io/ktor/util/AttributesJvm.kt index cbfa4fb4312..f400eaef8ab 100644 --- a/ktor-utils/jvm/src/io/ktor/util/AttributesJvm.kt +++ b/ktor-utils/jvm/src/io/ktor/util/AttributesJvm.kt @@ -8,6 +8,8 @@ import java.util.concurrent.* /** * Create JVM specific attributes instance. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.Attributes) */ public actual fun Attributes(concurrent: Boolean): Attributes = if (concurrent) ConcurrentSafeAttributes() else HashMapAttributes() diff --git a/ktor-utils/jvm/src/io/ktor/util/BufferViewJvm.kt b/ktor-utils/jvm/src/io/ktor/util/BufferViewJvm.kt index 93fd025c3db..53ee0df7a1e 100644 --- a/ktor-utils/jvm/src/io/ktor/util/BufferViewJvm.kt +++ b/ktor-utils/jvm/src/io/ktor/util/BufferViewJvm.kt @@ -12,6 +12,9 @@ import java.nio.channels.* /** * Read from a NIO channel into the specified [buffer] * Could return `0` if the channel is non-blocking or [buffer] has no free space + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.read) + * * @return number of bytes read (possibly 0) or -1 if EOF */ public fun ReadableByteChannel.read(buffer: Buffer): Int { @@ -28,6 +31,9 @@ public fun ReadableByteChannel.read(buffer: Buffer): Int { /** * Write bytes to a NIO channel from the specified [buffer] * Could return `0` if the channel is non-blocking or [buffer] has no free space + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.write) + * * @return number of bytes written (possibly 0) */ @InternalAPI diff --git a/ktor-utils/jvm/src/io/ktor/util/Cache.kt b/ktor-utils/jvm/src/io/ktor/util/Cache.kt index ecb365f268a..145305dbd1d 100644 --- a/ktor-utils/jvm/src/io/ktor/util/Cache.kt +++ b/ktor-utils/jvm/src/io/ktor/util/Cache.kt @@ -19,6 +19,8 @@ private const val CACHE_LOAD_FACTOR = 0.75f /** * Create a new instance of thread safe [LRUCache] and return it. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.createLRUCache) */ @InternalAPI public fun createLRUCache(supplier: (K) -> V, close: (V) -> Unit, maxSize: Int): Map = diff --git a/ktor-utils/jvm/src/io/ktor/util/CollectionsJvm.kt b/ktor-utils/jvm/src/io/ktor/util/CollectionsJvm.kt index f174cd44daf..c49c8b77db6 100644 --- a/ktor-utils/jvm/src/io/ktor/util/CollectionsJvm.kt +++ b/ktor-utils/jvm/src/io/ktor/util/CollectionsJvm.kt @@ -8,5 +8,7 @@ import java.util.* /** * Wraps into an unmodifiable set + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.unmodifiable) */ public actual fun Set.unmodifiable(): Set = Collections.unmodifiableSet(this) diff --git a/ktor-utils/jvm/src/io/ktor/util/ContentEncodersJvm.kt b/ktor-utils/jvm/src/io/ktor/util/ContentEncodersJvm.kt index fc1b0ba4e55..2fa29e41f42 100644 --- a/ktor-utils/jvm/src/io/ktor/util/ContentEncodersJvm.kt +++ b/ktor-utils/jvm/src/io/ktor/util/ContentEncodersJvm.kt @@ -6,6 +6,8 @@ package io.ktor.util /** * Implementation of [ContentEncoder] using gzip algorithm + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.GZipEncoder) */ public actual object GZipEncoder : ContentEncoder, Encoder by GZip { actual override val name: String = "gzip" @@ -13,6 +15,8 @@ public actual object GZipEncoder : ContentEncoder, Encoder by GZip { /** * Implementation of [ContentEncoder] using deflate algorithm + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.DeflateEncoder) */ public actual object DeflateEncoder : ContentEncoder, Encoder by Deflate { actual override val name: String = "deflate" diff --git a/ktor-utils/jvm/src/io/ktor/util/CryptoJvm.kt b/ktor-utils/jvm/src/io/ktor/util/CryptoJvm.kt index 4615a3df729..7dbd38a8882 100644 --- a/ktor-utils/jvm/src/io/ktor/util/CryptoJvm.kt +++ b/ktor-utils/jvm/src/io/ktor/util/CryptoJvm.kt @@ -13,6 +13,9 @@ import java.security.* /** * Create a digest function with the specified [algorithm] and [salt] provider. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.getDigestFunction) + * * @param algorithm digest algorithm name * @param salt a function computing a salt for a particular hash input value */ @@ -28,12 +31,16 @@ private fun getDigest(text: String, algorithm: String, salt: (String) -> String) /** * Compute SHA-1 hash for the specified [bytes] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.sha1) */ public actual fun sha1(bytes: ByteArray): ByteArray = MessageDigest.getInstance("SHA1").digest(bytes) /** * Create [Digest] from specified hash [name]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.Digest) */ public actual fun Digest(name: String): Digest = DigestImpl(MessageDigest.getInstance(name)) @@ -52,6 +59,8 @@ private value class DigestImpl(val delegate: MessageDigest) : Digest { /** * Generates a nonce string 16 characters long. Could block if the system's entropy source is empty + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.generateNonce) */ public actual fun generateNonce(): String { val nonce = seedChannel.tryReceive().getOrNull() diff --git a/ktor-utils/jvm/src/io/ktor/util/Deflater.kt b/ktor-utils/jvm/src/io/ktor/util/Deflater.kt index 904ca036b6c..86d3b5b67a3 100644 --- a/ktor-utils/jvm/src/io/ktor/util/Deflater.kt +++ b/ktor-utils/jvm/src/io/ktor/util/Deflater.kt @@ -100,6 +100,8 @@ private suspend fun ByteReadChannel.deflateTo( /** * Launch a coroutine on [coroutineContext] that does deflate compression * optionally doing CRC and writing GZIP header and trailer if [gzip] = `true` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.deflated) */ @OptIn(DelicateCoroutinesApi::class) public fun ByteReadChannel.deflated( @@ -113,6 +115,8 @@ public fun ByteReadChannel.deflated( /** * Launch a coroutine on [coroutineContext] that does deflate compression * optionally doing CRC and writing GZIP header and trailer if [gzip] = `true` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.deflated) */ @OptIn(DelicateCoroutinesApi::class) public fun ByteWriteChannel.deflated( diff --git a/ktor-utils/jvm/src/io/ktor/util/EncodersJvm.kt b/ktor-utils/jvm/src/io/ktor/util/EncodersJvm.kt index 1af2de7be07..e3c0876150b 100644 --- a/ktor-utils/jvm/src/io/ktor/util/EncodersJvm.kt +++ b/ktor-utils/jvm/src/io/ktor/util/EncodersJvm.kt @@ -37,6 +37,8 @@ private infix fun Int.has(flag: Int) = this and flag != 0 /** * Implementation of Deflate [Encoder]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.Deflate) */ public val Deflate: Encoder = object : Encoder { override fun encode(source: ByteReadChannel, coroutineContext: CoroutineContext): ByteReadChannel = @@ -51,6 +53,8 @@ public val Deflate: Encoder = object : Encoder { /** * Implementation of GZip [Encoder]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.GZip) */ public val GZip: Encoder = object : Encoder { override fun encode(source: ByteReadChannel, coroutineContext: CoroutineContext): ByteReadChannel = diff --git a/ktor-utils/jvm/src/io/ktor/util/InputJvm.kt b/ktor-utils/jvm/src/io/ktor/util/InputJvm.kt index 5930d370f1c..53ccdc3b1e0 100644 --- a/ktor-utils/jvm/src/io/ktor/util/InputJvm.kt +++ b/ktor-utils/jvm/src/io/ktor/util/InputJvm.kt @@ -9,6 +9,8 @@ import java.io.* /** * Convert io.ktor.utils.io [Input] to java [InputStream] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.asStream) */ public fun Input.asStream(): InputStream = object : InputStream() { diff --git a/ktor-utils/jvm/src/io/ktor/util/NIO.kt b/ktor-utils/jvm/src/io/ktor/util/NIO.kt index 75d21ea8f09..047ee10ffc2 100644 --- a/ktor-utils/jvm/src/io/ktor/util/NIO.kt +++ b/ktor-utils/jvm/src/io/ktor/util/NIO.kt @@ -11,6 +11,9 @@ import java.nio.charset.* /** * Moves bytes from `this` buffer to the [destination] buffer * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.moveTo) + * * @param destination is the buffer to copy bytes to * @param limit is an optional parameter specifying maximum number of bytes to be moved * @return number of bytes moved @@ -30,6 +33,8 @@ public fun ByteBuffer.moveTo(destination: ByteBuffer, limit: Int = Int.MAX_VALUE /** * Moves bytes from `this` buffer into newly created [ByteArray] and returns it + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.moveToByteArray) */ public fun ByteBuffer.moveToByteArray(): ByteArray { val array = ByteArray(remaining()) @@ -39,6 +44,8 @@ public fun ByteBuffer.moveToByteArray(): ByteArray { /** * Decodes a string from `this` buffer with the specified [charset] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.decodeString) */ public fun ByteBuffer.decodeString(charset: Charset = Charsets.UTF_8): String { return charset.decode(this).toString() @@ -46,6 +53,8 @@ public fun ByteBuffer.decodeString(charset: Charset = Charsets.UTF_8): String { /** * Moves all bytes in `this` buffer to a newly created buffer with the optionally specified [size] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.copy) */ public fun ByteBuffer.copy(size: Int = remaining()): ByteBuffer { return ByteBuffer.allocate(size).apply { @@ -56,6 +65,8 @@ public fun ByteBuffer.copy(size: Int = remaining()): ByteBuffer { /** * Moves all bytes in `this` buffer to a newly created buffer with the optionally specified [size] by allocating it from the given [pool] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.copy) */ public fun ByteBuffer.copy(pool: ObjectPool, size: Int = remaining()): ByteBuffer = pool.borrow().apply { limit(size) diff --git a/ktor-utils/jvm/src/io/ktor/util/NioPath.kt b/ktor-utils/jvm/src/io/ktor/util/NioPath.kt index 5d0b3651570..89cb358f252 100644 --- a/ktor-utils/jvm/src/io/ktor/util/NioPath.kt +++ b/ktor-utils/jvm/src/io/ktor/util/NioPath.kt @@ -11,6 +11,8 @@ import java.nio.file.Path /** * Append a [relativePath] safely that means that adding any extra `..` path elements will not let * access anything out of the reference directory (unless you have symbolic or hard links or multiple mount points) + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.combineSafe) */ public fun Path.combineSafe(relativePath: Path): Path { val normalized = relativePath.normalizeAndRelativize() @@ -28,6 +30,8 @@ public fun Path.combineSafe(relativePath: Path): Path { /** * Remove all redundant `.` and `..` path elements. Leading `..` are also considered redundant. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.normalizeAndRelativize) */ public fun Path.normalizeAndRelativize(): Path = root?.relativize(this)?.normalize()?.dropLeadingTopDirs() ?: normalize().dropLeadingTopDirs() @@ -41,6 +45,8 @@ private fun Path.dropLeadingTopDirs(): Path { /** * Append a [relativePath] safely that means that adding any extra `..` path elements will not let * access anything out of the reference directory (unless you have symbolic or hard links or multiple mount points) + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.combineSafe) */ public fun File.combineSafe(relativePath: Path): File { val normalized = relativePath.normalizeAndRelativize() diff --git a/ktor-utils/jvm/src/io/ktor/util/Path.kt b/ktor-utils/jvm/src/io/ktor/util/Path.kt index 7596ee94d17..870e3edd7d9 100644 --- a/ktor-utils/jvm/src/io/ktor/util/Path.kt +++ b/ktor-utils/jvm/src/io/ktor/util/Path.kt @@ -9,11 +9,15 @@ import java.io.* /** * Append a [relativePath] safely that means that adding any extra `..` path elements will not let * access anything out of the reference directory (unless you have symbolic or hard links or multiple mount points) + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.combineSafe) */ public fun File.combineSafe(relativePath: String): File = combineSafe(this, File(relativePath)) /** * Remove all redundant `.` and `..` path elements. Leading `..` are also considered redundant. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.normalizeAndRelativize) */ public fun File.normalizeAndRelativize(): File = normalize().notRooted().dropLeadingTopDirs() diff --git a/ktor-utils/jvm/src/io/ktor/util/StatelessHmacNonceManager.kt b/ktor-utils/jvm/src/io/ktor/util/StatelessHmacNonceManager.kt index 921cbae05b5..f404f5392a1 100644 --- a/ktor-utils/jvm/src/io/ktor/util/StatelessHmacNonceManager.kt +++ b/ktor-utils/jvm/src/io/ktor/util/StatelessHmacNonceManager.kt @@ -11,6 +11,9 @@ import javax.crypto.spec.* /** * Stateless nonce manager implementation with HMAC verification and timeout. * Every nonce provided by this manager consist of a random part, timestamp and HMAC. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.StatelessHmacNonceManager) + * * @property keySpec secret key spec for HMAC * @property algorithm HMAC algorithm name, `HmacSHA256` by default * @property timeoutMillis specifies the amount of time for a nonce to be considered valid @@ -24,6 +27,8 @@ public class StatelessHmacNonceManager( ) : NonceManager { /** * Helper constructor that makes a secret key from [key] ByteArray + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.StatelessHmacNonceManager.StatelessHmacNonceManager) */ public constructor( key: ByteArray, diff --git a/ktor-utils/jvm/src/io/ktor/util/cio/ByteBufferPool.kt b/ktor-utils/jvm/src/io/ktor/util/cio/ByteBufferPool.kt index d64da3ce673..4c53bb510a3 100644 --- a/ktor-utils/jvm/src/io/ktor/util/cio/ByteBufferPool.kt +++ b/ktor-utils/jvm/src/io/ktor/util/cio/ByteBufferPool.kt @@ -12,5 +12,7 @@ internal const val DEFAULT_KTOR_POOL_SIZE = 2048 /** * The default ktor byte buffer pool + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.cio.KtorDefaultPool) */ public val KtorDefaultPool: ObjectPool = ByteBufferPool(DEFAULT_KTOR_POOL_SIZE, DEFAULT_BUFFER_SIZE) diff --git a/ktor-utils/jvm/src/io/ktor/util/cio/FileChannels.kt b/ktor-utils/jvm/src/io/ktor/util/cio/FileChannels.kt index c6b72d89991..15e2fbf046c 100644 --- a/ktor-utils/jvm/src/io/ktor/util/cio/FileChannels.kt +++ b/ktor-utils/jvm/src/io/ktor/util/cio/FileChannels.kt @@ -17,6 +17,8 @@ import kotlin.coroutines.* * your async code and freeze the whole application when runs on a pool that is not intended for blocking operations. * This is why [coroutineContext] should have [Dispatchers.IO] or * a coroutine dispatcher that is properly configured for blocking IO. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.cio.readChannel) */ public fun File.readChannel( start: Long = 0, @@ -92,6 +94,8 @@ internal suspend fun SeekableByteChannel.writeToScope( * your async code and freeze the whole application when runs on a pool that is not intended for blocking operations. * This is why [coroutineContext] should have [Dispatchers.IO] or * a coroutine dispatcher that is properly configured for blocking IO. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.cio.writeChannel) */ @OptIn(DelicateCoroutinesApi::class) public fun File.writeChannel( diff --git a/ktor-utils/jvm/src/io/ktor/util/cio/FileChannelsAtNioPath.kt b/ktor-utils/jvm/src/io/ktor/util/cio/FileChannelsAtNioPath.kt index 875464345d4..fc7ebd3612d 100644 --- a/ktor-utils/jvm/src/io/ktor/util/cio/FileChannelsAtNioPath.kt +++ b/ktor-utils/jvm/src/io/ktor/util/cio/FileChannelsAtNioPath.kt @@ -16,6 +16,8 @@ import kotlin.io.use * your async code and freeze the whole application when runs on a pool that is not intended for blocking operations. * This is why [coroutineContext] should have [Dispatchers.IO] or * a coroutine dispatcher that is properly configured for blocking IO. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.cio.readChannel) */ public fun Path.readChannel( start: Long = 0, diff --git a/ktor-utils/jvm/src/io/ktor/util/cio/InputStreamAdapters.kt b/ktor-utils/jvm/src/io/ktor/util/cio/InputStreamAdapters.kt index 08965188090..0a4f389eee0 100644 --- a/ktor-utils/jvm/src/io/ktor/util/cio/InputStreamAdapters.kt +++ b/ktor-utils/jvm/src/io/ktor/util/cio/InputStreamAdapters.kt @@ -16,6 +16,8 @@ import io.ktor.utils.io.jvm.javaio.toByteReadChannel as toByteReadChannelImpl * Open a channel and launch a coroutine to copy bytes from the input stream to the channel. * Please note that it may block your async code when started on [Dispatchers.Unconfined] * since [InputStream] is blocking on it's nature + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.cio.toByteReadChannel) */ @Deprecated( "Use variant from 'ktor-io' module instead", diff --git a/ktor-utils/jvm/src/io/ktor/util/cio/OutputStreamAdapters.kt b/ktor-utils/jvm/src/io/ktor/util/cio/OutputStreamAdapters.kt index d41c776890f..f9c94216718 100644 --- a/ktor-utils/jvm/src/io/ktor/util/cio/OutputStreamAdapters.kt +++ b/ktor-utils/jvm/src/io/ktor/util/cio/OutputStreamAdapters.kt @@ -11,12 +11,16 @@ import java.nio.charset.* /** * Open a buffered writer to the channel + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.cio.bufferedWriter) */ public fun ByteWriteChannel.bufferedWriter(charset: Charset = Charsets.UTF_8): BufferedWriter = toOutputStream().bufferedWriter(charset) /** * Open a writer to the channel + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.cio.writer) */ public fun ByteWriteChannel.writer(charset: Charset = Charsets.UTF_8): Writer = toOutputStream().writer(charset) diff --git a/ktor-utils/jvm/src/io/ktor/util/cio/ReadersJvm.kt b/ktor-utils/jvm/src/io/ktor/util/cio/ReadersJvm.kt index b7c07d310a1..562f556709f 100644 --- a/ktor-utils/jvm/src/io/ktor/util/cio/ReadersJvm.kt +++ b/ktor-utils/jvm/src/io/ktor/util/cio/ReadersJvm.kt @@ -9,6 +9,8 @@ import java.nio.* /** * Read data chunks from [ByteReadChannel] using buffer + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.cio.pass) */ @InternalAPI public suspend inline fun ByteReadChannel.pass(buffer: ByteBuffer, block: (ByteBuffer) -> Unit) { diff --git a/ktor-utils/jvm/src/io/ktor/util/collections/ConcurrentMapJvm.kt b/ktor-utils/jvm/src/io/ktor/util/collections/ConcurrentMapJvm.kt index be5b2ae05ed..5020d16f4d5 100644 --- a/ktor-utils/jvm/src/io/ktor/util/collections/ConcurrentMapJvm.kt +++ b/ktor-utils/jvm/src/io/ktor/util/collections/ConcurrentMapJvm.kt @@ -8,12 +8,16 @@ import java.util.concurrent.* /** * Ktor concurrent map implementation. Please do not use it. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.collections.ConcurrentMap) */ public actual class ConcurrentMap public actual constructor(initialCapacity: Int) : MutableMap { private val delegate = ConcurrentHashMap(initialCapacity) /** * Computes [block] and inserts result in map. The [block] will be evaluated at most once. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.collections.ConcurrentMap.computeIfAbsent) */ public actual fun computeIfAbsent(key: Key, block: () -> Value): Value = delegate.computeIfAbsent(key) { block() diff --git a/ktor-utils/jvm/src/io/ktor/util/date/DateJvm.kt b/ktor-utils/jvm/src/io/ktor/util/date/DateJvm.kt index 96d8032f663..c11ea900b73 100644 --- a/ktor-utils/jvm/src/io/ktor/util/date/DateJvm.kt +++ b/ktor-utils/jvm/src/io/ktor/util/date/DateJvm.kt @@ -10,6 +10,9 @@ private val GMT_TIMEZONE = TimeZone.getTimeZone("GMT") /** * Create new gmt date from the [timestamp]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.date.GMTDate) + * * @param timestamp is a number of epoch milliseconds (it is `now` by default). */ @Suppress("FunctionName") @@ -18,6 +21,8 @@ public actual fun GMTDate(timestamp: Long?): GMTDate = /** * Create an instance of [GMTDate] from the specified date/time components + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.date.GMTDate) */ @Suppress("FunctionName") public actual fun GMTDate( @@ -67,10 +72,14 @@ public fun Calendar.toDate(timestamp: Long?): GMTDate { /** * Convert to [Date] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.date.toJvmDate) */ public fun GMTDate.toJvmDate(): Date = Date(timestamp) /** * Gets current system time in milliseconds since certain moment in the past, only delta between two subsequent calls makes sense. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.date.getTimeMillis) */ public actual fun getTimeMillis(): Long = System.currentTimeMillis() diff --git a/ktor-utils/jvm/src/io/ktor/util/internal/ExceptionUtilsJvm.kt b/ktor-utils/jvm/src/io/ktor/util/internal/ExceptionUtilsJvm.kt index e6d4b398540..e6c00aee870 100644 --- a/ktor-utils/jvm/src/io/ktor/util/internal/ExceptionUtilsJvm.kt +++ b/ktor-utils/jvm/src/io/ktor/util/internal/ExceptionUtilsJvm.kt @@ -6,6 +6,8 @@ package io.ktor.util.internal /** * Internal helper for setting cause on [Throwable] in MPP + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.internal.initCauseBridge) */ public actual fun Throwable.initCauseBridge(cause: Throwable) { initCause(cause) diff --git a/ktor-utils/jvm/src/io/ktor/util/network/NetworkAddressJvm.kt b/ktor-utils/jvm/src/io/ktor/util/network/NetworkAddressJvm.kt index c9248558e7e..f7f178f61ca 100644 --- a/ktor-utils/jvm/src/io/ktor/util/network/NetworkAddressJvm.kt +++ b/ktor-utils/jvm/src/io/ktor/util/network/NetworkAddressJvm.kt @@ -11,6 +11,9 @@ import java.net.* * * The address will be resolved after construction. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.network.NetworkAddress) + * * @throws UnresolvedAddressException if the [hostname] cannot be resolved. */ public actual typealias NetworkAddress = SocketAddress diff --git a/ktor-utils/jvm/src/io/ktor/util/reflect/ServiceLoader.kt b/ktor-utils/jvm/src/io/ktor/util/reflect/ServiceLoader.kt index bc57341211e..2de99a29ef5 100644 --- a/ktor-utils/jvm/src/io/ktor/util/reflect/ServiceLoader.kt +++ b/ktor-utils/jvm/src/io/ktor/util/reflect/ServiceLoader.kt @@ -13,6 +13,9 @@ import java.util.* /** * Loads implementations of the service [T] using [ServiceLoader.load] and returns them as a sequence. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.reflect.loadServicesAsSequence) + * * @see loadServices */ @InternalAPI @@ -23,6 +26,9 @@ public inline fun loadServicesAsSequence(): Sequence = Serv /** * Loads all implementations of the service [T] using [ServiceLoader.load]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.reflect.loadServices) + * * @see loadServiceOrNull * @see loadServicesAsSequence */ @@ -32,6 +38,9 @@ public inline fun loadServices(): List = loadServicesAsSequ /** * Loads single implementation of the service [T] using [ServiceLoader.load] * returns `null` if there are no any implementations. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.reflect.loadServiceOrNull) + * * @see loadServices */ @InternalAPI diff --git a/ktor-utils/jvm/src/io/ktor/util/reflect/TypeInfoJvm.kt b/ktor-utils/jvm/src/io/ktor/util/reflect/TypeInfoJvm.kt index 18bfb20f9d5..4e59f9460c6 100644 --- a/ktor-utils/jvm/src/io/ktor/util/reflect/TypeInfoJvm.kt +++ b/ktor-utils/jvm/src/io/ktor/util/reflect/TypeInfoJvm.kt @@ -9,7 +9,11 @@ import kotlin.reflect.* @Deprecated("Not used anymore in common code as it was needed only for JVM target.") public actual typealias Type = java.lang.reflect.Type -/** Type with substituted generics. */ +/** + * Type with substituted generics. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.reflect.reifiedType) + */ @OptIn(ExperimentalStdlibApi::class) public val TypeInfo.reifiedType: java.lang.reflect.Type // Fallback to a type without generics if we couldn't get KType. @@ -22,6 +26,8 @@ public fun typeInfoImpl(reifiedType: Type, kClass: KClass<*>, kType: KType?): Ty /** * Check [this] is instance of [type]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.reflect.instanceOf) */ public actual fun Any.instanceOf(type: KClass<*>): Boolean = type.java.isInstance(this) diff --git a/ktor-utils/mingwX64/src/io/ktor/util/date/DateMingw.kt b/ktor-utils/mingwX64/src/io/ktor/util/date/DateMingw.kt index b8df3367a4d..48874652942 100644 --- a/ktor-utils/mingwX64/src/io/ktor/util/date/DateMingw.kt +++ b/ktor-utils/mingwX64/src/io/ktor/util/date/DateMingw.kt @@ -17,6 +17,8 @@ internal actual fun system_time(tm: CValuesRef?): Long { /** * Gets current system time in milliseconds since a certain moment in the past, * only delta between two subsequent calls makes sense. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.date.getTimeMillis) */ @OptIn(ExperimentalForeignApi::class) public actual fun getTimeMillis(): Long = memScoped { diff --git a/ktor-utils/nix/src/io/ktor/util/date/DateNix.kt b/ktor-utils/nix/src/io/ktor/util/date/DateNix.kt index f1d9766f4a4..72452811693 100644 --- a/ktor-utils/nix/src/io/ktor/util/date/DateNix.kt +++ b/ktor-utils/nix/src/io/ktor/util/date/DateNix.kt @@ -14,6 +14,8 @@ internal actual fun system_time(tm: CValuesRef?): Long = timegm(tm).convert( /** * Gets current system time in milliseconds since a certain moment in the past, * only delta between two subsequent calls makes sense. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.date.getTimeMillis) */ @OptIn(UnsafeNumber::class, ExperimentalForeignApi::class) public actual fun getTimeMillis(): Long = memScoped { diff --git a/ktor-utils/posix/src/io/ktor/util/AttributesNative.kt b/ktor-utils/posix/src/io/ktor/util/AttributesNative.kt index 9a1db9d0471..ca10b62cf5e 100644 --- a/ktor-utils/posix/src/io/ktor/util/AttributesNative.kt +++ b/ktor-utils/posix/src/io/ktor/util/AttributesNative.kt @@ -10,6 +10,8 @@ private const val ATTRIBUTES_INITIAL_CAPACITY = 32 /** * Create native specific attributes instance. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.Attributes) */ public actual fun Attributes(concurrent: Boolean): Attributes = AttributesNative() diff --git a/ktor-utils/posix/src/io/ktor/util/ContentEncodersNative.kt b/ktor-utils/posix/src/io/ktor/util/ContentEncodersNative.kt index 5cfe765706a..4fb26307527 100644 --- a/ktor-utils/posix/src/io/ktor/util/ContentEncodersNative.kt +++ b/ktor-utils/posix/src/io/ktor/util/ContentEncodersNative.kt @@ -6,6 +6,8 @@ package io.ktor.util /** * Implementation of [ContentEncoder] using gzip algorithm + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.GZipEncoder) */ public actual object GZipEncoder : ContentEncoder, Encoder by Identity { actual override val name: String = "gzip" @@ -13,6 +15,8 @@ public actual object GZipEncoder : ContentEncoder, Encoder by Identity { /** * Implementation of [ContentEncoder] using deflate algorithm + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.DeflateEncoder) */ public actual object DeflateEncoder : ContentEncoder, Encoder by Identity { actual override val name: String = "deflate" diff --git a/ktor-utils/posix/src/io/ktor/util/CryptoNative.kt b/ktor-utils/posix/src/io/ktor/util/CryptoNative.kt index e670e634b55..006c9d697a4 100644 --- a/ktor-utils/posix/src/io/ktor/util/CryptoNative.kt +++ b/ktor-utils/posix/src/io/ktor/util/CryptoNative.kt @@ -6,6 +6,8 @@ package io.ktor.util /** * Generates a nonce string 32 characters long. Could block if the system's entropy source is empty + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.generateNonce) */ public actual fun generateNonce(): String { val bytes = ByteArray(16) @@ -17,10 +19,14 @@ internal expect fun secureRandom(bytes: ByteArray) /** * Create [Digest] from specified hash [name]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.Digest) */ public actual fun Digest(name: String): Digest = error("[Digest] is not supported on Darwin") /** * Compute SHA-1 hash for the specified [bytes] + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.sha1) */ public actual fun sha1(bytes: ByteArray): ByteArray = Sha1().digest(bytes) diff --git a/ktor-utils/posix/src/io/ktor/util/collections/ConcurrentMapNative.kt b/ktor-utils/posix/src/io/ktor/util/collections/ConcurrentMapNative.kt index daa781ce2de..472738dade5 100644 --- a/ktor-utils/posix/src/io/ktor/util/collections/ConcurrentMapNative.kt +++ b/ktor-utils/posix/src/io/ktor/util/collections/ConcurrentMapNative.kt @@ -9,6 +9,8 @@ import io.ktor.utils.io.locks.* /** * Ktor concurrent map implementation. Please do not use it. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.collections.ConcurrentMap) */ @OptIn(InternalAPI::class) public actual class ConcurrentMap public actual constructor( @@ -19,6 +21,8 @@ public actual class ConcurrentMap public actual constructor( /** * Computes [block] and inserts result in map. The [block] will be evaluated at most once. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.collections.ConcurrentMap.computeIfAbsent) */ public actual fun computeIfAbsent(key: Key, block: () -> Value): Value = synchronized(lock) { if (delegate.containsKey(key)) return delegate[key]!! diff --git a/ktor-utils/posix/src/io/ktor/util/collections/LockFreeMPSCQueueNative.kt b/ktor-utils/posix/src/io/ktor/util/collections/LockFreeMPSCQueueNative.kt index ca8d4de7995..f45c4ac2d27 100644 --- a/ktor-utils/posix/src/io/ktor/util/collections/LockFreeMPSCQueueNative.kt +++ b/ktor-utils/posix/src/io/ktor/util/collections/LockFreeMPSCQueueNative.kt @@ -19,6 +19,8 @@ private typealias Core = LockFreeMPSCQueueCore * Thread 1: addLast(1) = true, removeFirstOrNull() = null * Thread 2: addLast(2) = 2 // this operation is concurrent with both operations in the first thread * ``` + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.collections.LockFreeMPSCQueue) */ @InternalAPI public class LockFreeMPSCQueue { diff --git a/ktor-utils/posix/src/io/ktor/util/date/DateNative.kt b/ktor-utils/posix/src/io/ktor/util/date/DateNative.kt index 7276a4e5701..405773c3830 100644 --- a/ktor-utils/posix/src/io/ktor/util/date/DateNative.kt +++ b/ktor-utils/posix/src/io/ktor/util/date/DateNative.kt @@ -9,6 +9,9 @@ import platform.posix.* /** * Create new gmt date from the [timestamp]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.date.GMTDate) + * * @param timestamp is a number of epoch milliseconds (it is `now` by default). */ @OptIn(UnsafeNumber::class, ExperimentalForeignApi::class) @@ -47,6 +50,8 @@ public actual fun GMTDate(timestamp: Long?): GMTDate = memScoped { /** * Create an instance of [GMTDate] from the specified date/time components + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.date.GMTDate) */ @OptIn(ExperimentalForeignApi::class) public actual fun GMTDate( diff --git a/ktor-utils/posix/src/io/ktor/util/internal/ExceptionUtilsPosix.kt b/ktor-utils/posix/src/io/ktor/util/internal/ExceptionUtilsPosix.kt index 7babf5f4f62..f7cd15506e4 100644 --- a/ktor-utils/posix/src/io/ktor/util/internal/ExceptionUtilsPosix.kt +++ b/ktor-utils/posix/src/io/ktor/util/internal/ExceptionUtilsPosix.kt @@ -6,5 +6,7 @@ package io.ktor.util.internal /** * Internal helper for setting cause on [Throwable] in MPP + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.internal.initCauseBridge) */ public actual fun Throwable.initCauseBridge(cause: Throwable) {} diff --git a/ktor-utils/posix/src/io/ktor/util/network/NetworkAddressNative.kt b/ktor-utils/posix/src/io/ktor/util/network/NetworkAddressNative.kt index 1a731465cbe..cedc114d013 100644 --- a/ktor-utils/posix/src/io/ktor/util/network/NetworkAddressNative.kt +++ b/ktor-utils/posix/src/io/ktor/util/network/NetworkAddressNative.kt @@ -13,6 +13,9 @@ import kotlinx.atomicfu.* * * The address will be resolved after construction. * + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.network.NetworkAddress) + * * @throws UnresolvedAddressException if the [hostname] cannot be resolved. */ public actual abstract class NetworkAddress( @@ -27,6 +30,8 @@ public actual abstract class NetworkAddress( /** * Resolve current socket address. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.network.NetworkAddress.toString) */ override fun toString(): String = "NetworkAddress[$hostname:$port]" diff --git a/ktor-utils/posix/src/io/ktor/util/reflect/TypeInfoNative.kt b/ktor-utils/posix/src/io/ktor/util/reflect/TypeInfoNative.kt index da8c65b6f8e..af47301da4e 100644 --- a/ktor-utils/posix/src/io/ktor/util/reflect/TypeInfoNative.kt +++ b/ktor-utils/posix/src/io/ktor/util/reflect/TypeInfoNative.kt @@ -15,6 +15,8 @@ internal fun typeInfoImpl(reifiedType: Type, kClass: KClass<*>, kType: KType): T /** * Check [this] is instance of [type]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.reflect.instanceOf) */ public actual fun Any.instanceOf(type: KClass<*>): Boolean = type.isInstance(this) diff --git a/ktor-utils/wasmJs/src/io/ktor/util/date/DateWasm.kt b/ktor-utils/wasmJs/src/io/ktor/util/date/DateWasm.kt index 582ce8b9409..3b1654c64a6 100644 --- a/ktor-utils/wasmJs/src/io/ktor/util/date/DateWasm.kt +++ b/ktor-utils/wasmJs/src/io/ktor/util/date/DateWasm.kt @@ -6,6 +6,9 @@ package io.ktor.util.date /** * Create new gmt date from the [timestamp]. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.date.GMTDate) + * * @param timestamp is a number of epoch milliseconds (it is `now` by default). */ public actual fun GMTDate(timestamp: Long?): GMTDate { @@ -38,6 +41,8 @@ public actual fun GMTDate(timestamp: Long?): GMTDate { /** * Create an instance of [GMTDate] from the specified date/time components + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.date.GMTDate) */ public actual fun GMTDate(seconds: Int, minutes: Int, hours: Int, dayOfMonth: Int, month: Month, year: Int): GMTDate { val timestamp = Date.UTC(year, month.ordinal, dayOfMonth, hours, minutes, seconds).toLong() @@ -46,6 +51,8 @@ public actual fun GMTDate(seconds: Int, minutes: Int, hours: Int, dayOfMonth: In /** * Invalid exception: possible overflow or underflow + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.date.InvalidTimestampException) */ public class InvalidTimestampException(timestamp: Long) : IllegalStateException( "Invalid date timestamp exception: $timestamp" @@ -53,5 +60,7 @@ public class InvalidTimestampException(timestamp: Long) : IllegalStateException( /** * Gets current system time in milliseconds since certain moment in the past, only delta between two subsequent calls makes sense. + * + * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.util.date.getTimeMillis) */ public actual fun getTimeMillis(): Long = Date().getTime().toLong()