0
# Ktor Client Encoding
1
2
Ktor Client Encoding is an HTTP client plugin that provides automatic content compression and decompression capabilities for the Ktor framework. It handles Accept-Encoding headers and transparently processes compressed response content, supporting gzip, deflate, and identity encodings.
3
4
## Package Information
5
6
- **Package Name**: ktor-client-encoding-tvosarm64
7
- **Package Type**: maven
8
- **Language**: Kotlin
9
- **Platform**: tvOS ARM64
10
- **Installation**: Add dependency to your build.gradle.kts:
11
12
```kotlin
13
implementation("io.ktor:ktor-client-encoding-tvosarm64:2.3.13")
14
```
15
16
## Core Imports
17
18
```kotlin
19
import io.ktor.client.plugins.compression.ContentEncoding
20
import io.ktor.client.plugins.compression.ContentEncoder
21
import io.ktor.client.plugins.compression.UnsupportedContentEncodingException
22
import io.ktor.util.Encoder
23
import io.ktor.utils.io.ByteReadChannel
24
import kotlinx.coroutines.CoroutineScope
25
```
26
27
## Basic Usage
28
29
```kotlin
30
import io.ktor.client.*
31
import io.ktor.client.plugins.compression.*
32
import io.ktor.client.request.*
33
import io.ktor.client.statement.*
34
35
// Create client with content encoding
36
val client = HttpClient {
37
ContentEncoding {
38
gzip()
39
deflate()
40
identity()
41
}
42
}
43
44
// Make request - compression is handled automatically
45
val response: HttpResponse = client.get("https://api.example.com/data")
46
val content: String = response.body<String>() // Automatically decompressed
47
```
48
49
## Architecture
50
51
Ktor Client Encoding integrates with the Ktor HTTP client pipeline through two main interception points:
52
53
- **Request Pipeline**: Automatically adds Accept-Encoding headers based on configured encoders
54
- **Response Pipeline**: Transparently decompresses response content based on Content-Encoding headers
55
56
The plugin uses platform-specific encoder implementations:
57
- **JVM**: Full compression support using native Java libraries
58
- **JS**: Delegates to browser compression (Identity fallback)
59
- **Native/tvOS**: Simplified Identity implementation for compatibility
60
61
## Capabilities
62
63
### Plugin Installation and Configuration
64
65
Install the ContentEncoding plugin with customizable encoder configuration and quality values.
66
67
```kotlin { .api }
68
fun HttpClientConfig<*>.ContentEncoding(
69
block: ContentEncoding.Config.() -> Unit = {
70
gzip()
71
deflate()
72
identity()
73
}
74
): Unit
75
```
76
77
### Encoder Configuration
78
79
Configure individual content encoders with optional quality values for Accept-Encoding header negotiation.
80
81
```kotlin { .api }
82
@KtorDsl
83
class ContentEncoding.Config {
84
/**
85
* Installs the gzip encoder.
86
* @param quality a priority value to use in the Accept-Encoding header.
87
*/
88
fun gzip(quality: Float? = null): Unit
89
90
/**
91
* Installs the deflate encoder.
92
* @param quality a priority value to use in the Accept-Encoding header.
93
*/
94
fun deflate(quality: Float? = null): Unit
95
96
/**
97
* Installs the identity encoder.
98
* @param quality a priority value to use in the Accept-Encoding header.
99
*/
100
fun identity(quality: Float? = null): Unit
101
102
/**
103
* Installs a custom encoder.
104
* @param encoder a custom encoder to use.
105
* @param quality a priority value to use in the Accept-Encoding header.
106
*/
107
fun customEncoder(encoder: ContentEncoder, quality: Float? = null): Unit
108
}
109
```
110
111
**Parameters:**
112
- `quality`: Optional priority value (0.0..1.0) for Accept-Encoding header. Higher values indicate preferred encodings.
113
114
**Usage Examples:**
115
116
```kotlin
117
// Default configuration (all encoders, no quality values)
118
ContentEncoding()
119
120
// Custom quality preferences
121
ContentEncoding {
122
gzip(quality = 0.9f)
123
deflate(quality = 0.8f)
124
identity(quality = 0.1f)
125
}
126
127
// Selective encoders
128
ContentEncoding {
129
gzip()
130
// Only gzip encoding enabled
131
}
132
```
133
134
### Custom Encoder Support
135
136
Implement custom content encoders for specialized compression algorithms.
137
138
```kotlin { .api }
139
interface ContentEncoder : Encoder {
140
/**
141
* Encoder identifier to use in http headers.
142
*/
143
val name: String
144
}
145
146
interface Encoder {
147
/**
148
* Launch coroutine to encode source bytes.
149
*/
150
fun CoroutineScope.encode(source: ByteReadChannel): ByteReadChannel
151
152
/**
153
* Launch coroutine to decode source bytes.
154
*/
155
fun CoroutineScope.decode(source: ByteReadChannel): ByteReadChannel
156
}
157
```
158
159
**Properties:**
160
- `name`: Encoder identifier used in HTTP headers (e.g., "gzip", "br", "custom")
161
162
**Integration:**
163
164
```kotlin
165
object CustomEncoder : ContentEncoder {
166
override val name = "custom"
167
// Implement Encoder interface methods
168
}
169
170
// Register custom encoder
171
ContentEncoding {
172
customEncoder(CustomEncoder, quality = 0.7f)
173
}
174
```
175
176
### Plugin Implementation
177
178
Core plugin class implementing the HttpClientPlugin interface.
179
180
```kotlin { .api }
181
class ContentEncoding private constructor(
182
private val encoders: Map<String, ContentEncoder>,
183
private val qualityValues: Map<String, Float>
184
) {
185
@KtorDsl
186
class Config {
187
fun gzip(quality: Float? = null): Unit
188
fun deflate(quality: Float? = null): Unit
189
fun identity(quality: Float? = null): Unit
190
fun customEncoder(encoder: ContentEncoder, quality: Float? = null): Unit
191
}
192
193
companion object : HttpClientPlugin<Config, ContentEncoding> {
194
override val key: AttributeKey<ContentEncoding>
195
override fun prepare(block: Config.() -> Unit): ContentEncoding
196
override fun install(plugin: ContentEncoding, scope: HttpClient): Unit
197
}
198
}
199
```
200
201
### Error Handling
202
203
Exception thrown when encountering unsupported content encodings in response headers.
204
205
```kotlin { .api }
206
class UnsupportedContentEncodingException(encoding: String) :
207
IllegalStateException("Content-Encoding: \$encoding unsupported.")
208
```
209
210
**Parameters:**
211
- `encoding`: The unsupported encoding name from Content-Encoding header
212
213
**When Thrown:**
214
- Server responds with Content-Encoding not registered in plugin configuration
215
- Malformed or unrecognized encoding values in response headers
216
217
**Example:**
218
219
```kotlin
220
try {
221
val response = client.get("https://api.example.com/compressed")
222
val content = response.body<String>()
223
} catch (e: UnsupportedContentEncodingException) {
224
println("Unsupported encoding: ${e.message}")
225
// Handle unsupported encoding
226
}
227
```
228
229
## Types
230
231
### Built-in Encoder Support
232
233
The plugin provides built-in support for standard content encodings through internal encoder implementations:
234
235
```kotlin { .api }
236
// Internal encoder objects (not directly accessible)
237
internal object GZipEncoder : ContentEncoder, Encoder by GZip { // JVM only
238
override val name: String = "gzip"
239
}
240
241
internal object DeflateEncoder : ContentEncoder, Encoder by Deflate { // JVM only
242
override val name: String = "deflate"
243
}
244
245
internal object IdentityEncoder : ContentEncoder, Encoder by Identity {
246
override val name: String = "identity"
247
}
248
```
249
250
**Encoder Types:**
251
- **gzip**: GZip compression (JVM: full compression, JS/Native: delegates to Identity)
252
- **deflate**: Deflate compression (JVM: full compression, JS/Native: delegates to Identity)
253
- **identity**: No compression (available on all platforms)
254
255
**Platform-Specific Behavior:**
256
- **JVM**: Full compression/decompression using Java standard libraries (GZip, Deflate encoders delegate to io.ktor.util.GZip and io.ktor.util.Deflate)
257
- **JS**: Identity encoding only (browsers handle compression automatically - GZip and Deflate encoders delegate to Identity)
258
- **Native/tvOS ARM64**: Identity encoding only (simplified implementation for compatibility - GZip and Deflate encoders delegate to Identity)
259
260
### HTTP Header Integration
261
262
The plugin automatically manages HTTP headers for content negotiation:
263
264
**Request Headers:**
265
- Sets `Accept-Encoding` with configured encoders and quality values
266
- Example: `Accept-Encoding: gzip;q=0.9,deflate;q=0.8,identity;q=0.1`
267
268
**Response Processing:**
269
- Reads `Content-Encoding` header from server responses
270
- Applies appropriate decompression based on encoding chain
271
- Supports multiple encodings applied in sequence
272
273
## Error Scenarios
274
275
**Configuration Errors:**
276
- Invalid quality values (outside 0.0..1.0 range) throw IllegalArgumentException
277
- Quality values are validated during plugin preparation
278
279
**Runtime Errors:**
280
- UnsupportedContentEncodingException for unknown encodings
281
- Graceful handling of missing Content-Encoding headers (no decompression applied)
282
283
**Platform Limitations:**
284
- **tvOS ARM64**: All compression encoders (gzip, deflate) fall back to Identity encoding - no actual compression/decompression occurs
285
- **JavaScript**: Relies on browser compression capabilities - encoders delegate to Identity
286
- **JVM**: Full compression support with native Java libraries
287
288
## Thread Safety
289
290
The ContentEncoding plugin is thread-safe and can be used concurrently across multiple requests. Internal state is immutable after configuration, and platform-specific encoders handle concurrent access appropriately.