0
# Ktor Client Content Encoding
1
2
HTTP content compression and decompression plugin for Ktor client applications supporting gzip, deflate, and identity encodings with automatic header management and transparent content processing.
3
4
## Package Information
5
6
- **Name**: ktor-client-encoding
7
- **Type**: Ktor Client Plugin Library
8
- **Language**: Kotlin (Multiplatform)
9
- **Maven Coordinates**: `io.ktor:ktor-client-encoding:3.2.0`
10
11
## Installation
12
13
```kotlin
14
dependencies {
15
implementation("io.ktor:ktor-client-encoding:3.2.0")
16
}
17
```
18
19
## Core Imports
20
21
```kotlin
22
import io.ktor.client.*
23
import io.ktor.client.plugins.compression.*
24
import io.ktor.client.request.*
25
import io.ktor.client.statement.*
26
import io.ktor.http.content.*
27
import io.ktor.util.*
28
```
29
30
## Basic Usage
31
32
```kotlin
33
import io.ktor.client.*
34
import io.ktor.client.plugins.compression.*
35
36
val client = HttpClient {
37
install(ContentEncoding) {
38
gzip()
39
deflate()
40
identity()
41
}
42
}
43
44
// Automatic response decompression
45
val response = client.get("https://api.example.com/data")
46
val data = response.body<String>() // Automatically decompressed if needed
47
48
// Manual request compression
49
client.post("https://api.example.com/upload") {
50
compress("gzip")
51
setBody(largePayload)
52
}
53
```
54
55
## Architecture
56
57
The content encoding system consists of four main components:
58
59
1. **ContentEncoding Plugin** - Main plugin for HTTP client content processing
60
2. **ContentEncodingConfig** - Configuration DSL for encoding options and modes
61
3. **ContentEncoder Interface** - Abstraction for compression algorithms
62
4. **Operation Modes** - Control whether to compress requests, decompress responses, or both
63
64
## Plugin API
65
66
```kotlin { .api }
67
val ContentEncoding: ClientPlugin<ContentEncodingConfig>
68
69
fun HttpClientConfig<*>.ContentEncoding(
70
mode: ContentEncodingConfig.Mode = ContentEncodingConfig.Mode.DecompressResponse,
71
block: ContentEncodingConfig.() -> Unit = {
72
gzip()
73
deflate()
74
identity()
75
}
76
): Unit
77
```
78
79
## Configuration API
80
81
```kotlin { .api }
82
class ContentEncodingConfig {
83
enum class Mode(internal val request: Boolean, internal val response: Boolean) {
84
CompressRequest(true, false),
85
DecompressResponse(false, true),
86
All(true, true)
87
}
88
89
var mode: Mode
90
91
fun gzip(quality: Float? = null): Unit
92
fun deflate(quality: Float? = null): Unit
93
fun identity(quality: Float? = null): Unit
94
fun customEncoder(encoder: ContentEncoder, quality: Float? = null): Unit
95
}
96
```
97
98
## Core Capabilities
99
100
### Plugin Installation and Configuration
101
102
Install and configure the ContentEncoding plugin with compression algorithms, quality values, and operation modes.
103
104
```kotlin
105
import io.ktor.client.*
106
import io.ktor.client.plugins.compression.*
107
108
val client = HttpClient {
109
install(ContentEncoding) {
110
mode = ContentEncodingConfig.Mode.All
111
gzip(0.9f) // High priority
112
deflate(0.8f) // Medium priority
113
identity(0.1f) // Low priority fallback
114
}
115
}
116
```
117
118
**Key API:**
119
- `ContentEncoding` plugin object for installation
120
- `ContentEncodingConfig.Mode` enum for operation control
121
- Quality value specification for Accept-Encoding header preferences
122
123
See [Configuration](configuration.md) for detailed configuration options.
124
125
### Compression Modes
126
127
Control whether the plugin compresses outgoing requests, decompresses incoming responses, or handles both operations.
128
129
```kotlin { .api }
130
enum class ContentEncodingConfig.Mode(internal val request: Boolean, internal val response: Boolean) {
131
CompressRequest(true, false),
132
DecompressResponse(false, true),
133
All(true, true),
134
}
135
```
136
137
**Usage:**
138
```kotlin
139
// Only decompress responses (default)
140
install(ContentEncoding) {
141
mode = ContentEncodingConfig.Mode.DecompressResponse
142
}
143
144
// Only compress requests
145
install(ContentEncoding) {
146
mode = ContentEncodingConfig.Mode.CompressRequest
147
}
148
149
// Both compress requests and decompress responses
150
install(ContentEncoding) {
151
mode = ContentEncodingConfig.Mode.All
152
}
153
```
154
155
See [Configuration](configuration.md) for mode-specific behaviors and use cases.
156
157
### Built-in Encoders
158
159
Pre-built content encoders for standard HTTP compression algorithms with platform-specific implementations.
160
161
```kotlin { .api }
162
object GZipEncoder : ContentEncoder {
163
override val name: String // "gzip"
164
}
165
166
object DeflateEncoder : ContentEncoder {
167
override val name: String // "deflate"
168
}
169
170
object IdentityEncoder : ContentEncoder {
171
override val name: String // "identity"
172
}
173
```
174
175
**Usage:**
176
```kotlin
177
install(ContentEncoding) {
178
gzip() // Enable gzip compression
179
deflate() // Enable deflate compression
180
identity() // Enable identity (no-op) encoding
181
}
182
```
183
184
See [Encoders](encoders.md) for encoder details and custom encoder implementation.
185
186
### Request Compression
187
188
Compress outgoing request bodies using specified encoding algorithms for individual requests or globally.
189
190
```kotlin { .api }
191
fun HttpRequestBuilder.compress(vararg contentEncoderName: String): Unit
192
fun HttpRequestBuilder.compress(contentEncoderNames: List<String>): Unit
193
```
194
195
**Usage:**
196
```kotlin
197
// Per-request compression
198
client.post("/api/upload") {
199
compress("gzip", "deflate")
200
setBody(largeData)
201
}
202
203
// List-based compression
204
client.put("/api/update") {
205
compress(listOf("gzip"))
206
setBody(payload)
207
}
208
```
209
210
**Key Features:**
211
- Multiple encoder support per request
212
- Automatic Content-Encoding header management
213
- Pipeline integration with request processing
214
215
See [Request Compression](request-compression.md) for advanced compression scenarios and configuration.
216
217
### Response Decompression
218
219
Automatically decompress incoming response bodies based on Content-Encoding headers with transparent processing.
220
221
```kotlin { .api }
222
val HttpResponse.appliedDecoders: List<String>
223
```
224
225
**Usage:**
226
```kotlin
227
val response = client.get("https://api.example.com/compressed-data")
228
229
// Access decompressed content directly
230
val content = response.body<String>()
231
232
// Check which decoders were applied
233
val usedEncodings = response.appliedDecoders
234
println("Applied decoders: $usedEncodings") // e.g., ["gzip", "deflate"]
235
```
236
237
**Key Features:**
238
- Automatic Content-Encoding header parsing
239
- Multi-layer decompression support
240
- Decoder chain tracking for debugging
241
242
See [Response Decompression](response-decompression.md) for decompression behavior and troubleshooting.
243
244
### Content Compression Utilities
245
246
Utilities for compressing OutgoingContent using ContentEncoder implementations.
247
248
```kotlin { .api }
249
fun OutgoingContent.compressed(
250
contentEncoder: ContentEncoder,
251
coroutineContext: CoroutineContext = EmptyCoroutineContext
252
): OutgoingContent?
253
```
254
255
**Usage:**
256
```kotlin
257
import io.ktor.http.content.*
258
import io.ktor.util.*
259
260
// Manually compress content before sending
261
val originalContent: OutgoingContent = TextContent("Large text payload", ContentType.Text.Plain)
262
val compressedContent = originalContent.compressed(GZipEncoder)
263
```
264
265
**Key Features:**
266
- Support for all OutgoingContent types (ReadChannelContent, WriteChannelContent, ByteArrayContent)
267
- Automatic Content-Encoding header management
268
- Content-Length prediction when possible
269
- Preserves original content properties and headers
270
271
## Content Encoder Interface
272
273
```kotlin { .api }
274
interface ContentEncoder : Encoder {
275
/**
276
* Encoder identifier to use in http headers.
277
*/
278
val name: String
279
280
/**
281
* Provides an estimation for the compressed length based on the originalLength or return null if it's impossible.
282
*/
283
fun predictCompressedLength(contentLength: Long): Long? = null
284
}
285
286
interface Encoder {
287
/**
288
* Launch coroutine to encode source bytes.
289
*/
290
fun encode(
291
source: ByteReadChannel,
292
coroutineContext: CoroutineContext = EmptyCoroutineContext
293
): ByteReadChannel
294
295
/**
296
* Launch coroutine to encode source bytes.
297
*/
298
fun encode(
299
source: ByteWriteChannel,
300
coroutineContext: CoroutineContext = EmptyCoroutineContext
301
): ByteWriteChannel
302
303
/**
304
* Launch coroutine to decode source bytes.
305
*/
306
fun decode(
307
source: ByteReadChannel,
308
coroutineContext: CoroutineContext = EmptyCoroutineContext
309
): ByteReadChannel
310
}
311
```
312
313
## Exception Handling
314
315
```kotlin { .api }
316
class UnsupportedContentEncodingException(encoding: String) : IllegalStateException("Content-Encoding: $encoding unsupported.")
317
```
318
319
**Error Scenarios:**
320
```kotlin
321
try {
322
val response = client.get("https://api.example.com/data")
323
val content = response.body<String>()
324
} catch (e: UnsupportedContentEncodingException) {
325
println("Unsupported encoding: ${e.message}")
326
// Handle unsupported encoding
327
}
328
```
329
330
## Internal Attributes
331
332
Internal attribute keys used by the plugin for tracking compression state.
333
334
```kotlin { .api }
335
val CompressionListAttribute: AttributeKey<List<String>>
336
val DecompressionListAttribute: AttributeKey<List<String>>
337
```
338
339
**Usage:**
340
```kotlin
341
// These attributes are used internally by the plugin
342
// CompressionListAttribute - tracks requested compression encoders
343
// DecompressionListAttribute - tracks applied decompression encoders
344
345
// Access applied decoders through the convenience property
346
val appliedDecoders = response.appliedDecoders // Uses DecompressionListAttribute internally
347
```
348
349
## Complete Example
350
351
```kotlin
352
import io.ktor.client.*
353
import io.ktor.client.engine.cio.*
354
import io.ktor.client.plugins.compression.*
355
import io.ktor.client.request.*
356
import io.ktor.client.statement.*
357
358
suspend fun main() {
359
val client = HttpClient(CIO) {
360
install(ContentEncoding) {
361
mode = ContentEncodingConfig.Mode.All
362
gzip(0.9f)
363
deflate(0.8f)
364
identity()
365
}
366
}
367
368
// Upload with compression
369
val uploadResponse = client.post("https://api.example.com/upload") {
370
compress("gzip")
371
setBody("Large payload data...")
372
}
373
374
// Download with automatic decompression
375
val downloadResponse = client.get("https://api.example.com/download")
376
val content = downloadResponse.body<String>()
377
378
// Check applied decoders
379
val decoders = downloadResponse.appliedDecoders
380
println("Response decompressed with: $decoders")
381
382
client.close()
383
}
384
```