0
# Ktor Client Content Encoding
1
2
Ktor Client Content Encoding is a plugin that provides content encoding and compression capabilities for Ktor HTTP client applications. It enables automatic compression of request bodies and decompression of response bodies using standard algorithms like gzip, deflate, and identity encoding.
3
4
## Package Information
5
6
- **Package Name**: ktor-client-encoding-jvm
7
- **Package Type**: maven
8
- **Language**: Kotlin
9
- **Group ID**: io.ktor
10
- **Artifact ID**: ktor-client-encoding-jvm
11
- **Installation**:
12
```kotlin
13
implementation("io.ktor:ktor-client-encoding-jvm:3.2.0")
14
```
15
16
## Core Imports
17
18
```kotlin
19
import io.ktor.client.plugins.compression.*
20
```
21
22
## Basic Usage
23
24
```kotlin
25
import io.ktor.client.*
26
import io.ktor.client.engine.cio.*
27
import io.ktor.client.plugins.compression.*
28
import io.ktor.client.request.*
29
import io.ktor.client.statement.*
30
import io.ktor.client.call.*
31
32
// Create client with content encoding support
33
val client = HttpClient(CIO) {
34
install(ContentEncoding) {
35
gzip()
36
deflate()
37
identity()
38
}
39
}
40
41
// Client will automatically decompress responses and set Accept-Encoding header
42
val response: HttpResponse = client.get("https://api.example.com/data")
43
val responseText = response.bodyAsText()
44
45
// Check which decoders were applied to the response
46
val appliedDecoders = response.appliedDecoders
47
println("Applied decoders: $appliedDecoders")
48
49
// Compress request body
50
client.post("https://api.example.com/upload") {
51
compress("gzip")
52
setBody("large data payload")
53
}
54
```
55
56
## Architecture
57
58
The ContentEncoding plugin is built around several key components:
59
60
- **Plugin Architecture**: Integrates with Ktor's client plugin system using `ClientPlugin<ContentEncodingConfig>`
61
- **Request Pipeline**: Hooks into the request pipeline to add Accept-Encoding headers and compress request bodies
62
- **Response Pipeline**: Intercepts responses to automatically decompress content based on Content-Encoding headers
63
- **ContentEncoder Interface**: Extensible system supporting built-in encoders (gzip, deflate, identity) and custom encoders
64
- **Mode System**: Configurable behavior for compression/decompression (request-only, response-only, or both)
65
66
## Capabilities
67
68
### Plugin Installation
69
70
Install and configure the ContentEncoding plugin on an HttpClient.
71
72
```kotlin { .api }
73
val ContentEncoding: ClientPlugin<ContentEncodingConfig>
74
75
fun HttpClientConfig<*>.ContentEncoding(
76
mode: ContentEncodingConfig.Mode = ContentEncodingConfig.Mode.DecompressResponse,
77
block: ContentEncodingConfig.() -> Unit = {
78
gzip()
79
deflate()
80
identity()
81
}
82
)
83
```
84
85
### Configuration
86
87
Configure encoding algorithms and compression modes.
88
89
```kotlin { .api }
90
@KtorDsl
91
class ContentEncodingConfig {
92
var mode: Mode
93
94
fun gzip(quality: Float? = null)
95
fun deflate(quality: Float? = null)
96
fun identity(quality: Float? = null)
97
fun customEncoder(encoder: ContentEncoder, quality: Float? = null)
98
}
99
100
enum class ContentEncodingConfig.Mode(
101
internal val request: Boolean,
102
internal val response: Boolean
103
) {
104
CompressRequest(true, false),
105
DecompressResponse(false, true),
106
All(true, true)
107
}
108
```
109
110
**Usage Examples:**
111
112
```kotlin
113
import io.ktor.client.*
114
import io.ktor.client.engine.cio.*
115
import io.ktor.client.plugins.compression.*
116
117
// Configure with specific mode and encoders
118
val client = HttpClient(CIO) {
119
ContentEncoding(mode = ContentEncodingConfig.Mode.All) {
120
gzip(quality = 1.0f)
121
deflate(quality = 0.8f)
122
// Custom encoder support
123
customEncoder(MyCustomEncoder, quality = 0.5f)
124
}
125
}
126
127
// Request compression only
128
val client = HttpClient(CIO) {
129
ContentEncoding(mode = ContentEncodingConfig.Mode.CompressRequest) {
130
gzip()
131
}
132
}
133
```
134
135
### Request Compression
136
137
Compress request bodies using specified encoding algorithms.
138
139
```kotlin { .api }
140
/**
141
* Compresses request body using ContentEncoding plugin
142
* @param contentEncoderName names of compression encoders to use
143
*/
144
fun HttpRequestBuilder.compress(vararg contentEncoderName: String)
145
146
/**
147
* Compress request body using ContentEncoding plugin
148
* @param contentEncoderNames names of compression encoders to use
149
*/
150
fun HttpRequestBuilder.compress(contentEncoderNames: List<String>)
151
```
152
153
**Usage Examples:**
154
155
```kotlin
156
import io.ktor.client.request.*
157
158
// Single encoder
159
client.post("/upload") {
160
compress("gzip")
161
setBody(largeData)
162
}
163
164
// Multiple encoders applied in sequence
165
client.post("/upload") {
166
compress("deflate", "gzip") // Applied as deflate first, then gzip
167
setBody(largeData)
168
}
169
170
// Using list
171
client.post("/upload") {
172
compress(listOf("gzip", "deflate"))
173
setBody(largeData)
174
}
175
```
176
177
### Response Decompression
178
179
Automatic decompression of response bodies and tracking of applied decoders.
180
181
```kotlin { .api }
182
/**
183
* List of ContentEncoder names that were used to decode response body
184
*/
185
val HttpResponse.appliedDecoders: List<String>
186
```
187
188
**Usage Examples:**
189
190
```kotlin
191
import io.ktor.client.call.*
192
193
val response = client.get("https://compressed-api.example.com/data")
194
195
// Check what decompression was applied
196
val decoders = response.appliedDecoders
197
if (decoders.contains("gzip")) {
198
println("Response was gzip compressed")
199
}
200
201
// Response body is automatically decompressed
202
val content = response.bodyAsText()
203
```
204
205
### Content Encoders
206
207
Built-in and extensible content encoder system.
208
209
```kotlin { .api }
210
interface ContentEncoder : Encoder {
211
val name: String
212
fun predictCompressedLength(contentLength: Long): Long?
213
}
214
215
interface Encoder {
216
fun encode(
217
source: ByteReadChannel,
218
coroutineContext: CoroutineContext = EmptyCoroutineContext
219
): ByteReadChannel
220
221
fun encode(
222
source: ByteWriteChannel,
223
coroutineContext: CoroutineContext = EmptyCoroutineContext
224
): ByteWriteChannel
225
226
fun decode(
227
source: ByteReadChannel,
228
coroutineContext: CoroutineContext = EmptyCoroutineContext
229
): ByteReadChannel
230
}
231
232
// Built-in encoders
233
object GZipEncoder : ContentEncoder {
234
override val name: String // = "gzip"
235
}
236
237
object DeflateEncoder : ContentEncoder {
238
override val name: String // = "deflate"
239
}
240
241
object IdentityEncoder : ContentEncoder {
242
override val name: String // = "identity"
243
override fun predictCompressedLength(contentLength: Long): Long
244
}
245
```
246
247
**Usage Examples:**
248
249
```kotlin
250
import io.ktor.util.*
251
import io.ktor.utils.io.*
252
import kotlin.coroutines.*
253
254
// Using built-in encoders by name
255
compress(GZipEncoder.name)
256
compress("gzip") // Equivalent
257
258
// Custom encoder implementation
259
object BrotliEncoder : ContentEncoder {
260
override val name = "br"
261
262
override fun encode(source: ByteReadChannel, coroutineContext: CoroutineContext): ByteReadChannel {
263
// Custom implementation
264
}
265
266
override fun decode(source: ByteReadChannel, coroutineContext: CoroutineContext): ByteReadChannel {
267
// Custom implementation
268
}
269
}
270
271
// Register custom encoder
272
val client = HttpClient(CIO) {
273
install(ContentEncoding) {
274
customEncoder(BrotliEncoder, quality = 0.9f)
275
}
276
}
277
```
278
279
### Error Handling
280
281
Exception handling for unsupported encoding algorithms.
282
283
```kotlin { .api }
284
class UnsupportedContentEncodingException(encoding: String) :
285
IllegalStateException("Content-Encoding: $encoding unsupported.")
286
```
287
288
**Usage Examples:**
289
290
```kotlin
291
try {
292
client.post("/upload") {
293
compress("unknown-algorithm")
294
setBody(data)
295
}
296
} catch (e: UnsupportedContentEncodingException) {
297
println("Encoding not supported: ${e.message}")
298
}
299
```
300
301
## Types
302
303
```kotlin { .api }
304
import io.ktor.util.*
305
import io.ktor.client.plugins.api.*
306
import io.ktor.http.content.*
307
308
// Request/Response pipeline attributes (internal use)
309
internal val CompressionListAttribute: AttributeKey<List<String>>
310
internal val DecompressionListAttribute: AttributeKey<List<String>>
311
312
// Hook interfaces for internal pipeline integration
313
internal object AfterRenderHook : ClientHook<suspend (HttpRequestBuilder, OutgoingContent) -> OutgoingContent?>
314
internal object ReceiveStateHook : ClientHook<suspend (HttpResponse) -> HttpResponse?>
315
```
316
317
## Dependencies
318
319
- **Ktor Client Core**: Core HTTP client functionality
320
- **Ktor Utils**: ContentEncoder interface and built-in encoder implementations
321
- **Kotlinx Coroutines**: Coroutine support for async operations
322
- **Ktor HTTP**: HTTP headers and content handling utilities