0
# Engine System
1
2
HTTP client engines for different platforms and engine configuration options that provide the underlying HTTP implementation.
3
4
## Capabilities
5
6
### HttpClientEngine Interface
7
8
Core interface for HTTP client engines that handle the actual HTTP communication.
9
10
```kotlin { .api }
11
/**
12
* HTTP client engine interface for platform-specific HTTP implementations
13
*/
14
interface HttpClientEngine : CoroutineScope, Closeable {
15
/** Coroutine dispatcher for engine operations */
16
val dispatcher: CoroutineDispatcher
17
18
/** Engine configuration */
19
val config: HttpClientEngineConfig
20
21
/** Set of capabilities supported by this engine */
22
val supportedCapabilities: Set<HttpClientEngineCapability<*>>
23
24
/**
25
* Execute an HTTP request
26
* @param data Request data to execute
27
* @return Response data from server
28
*/
29
suspend fun execute(data: HttpRequestData): HttpResponseData
30
31
/**
32
* Install the engine with a client
33
* @param client HttpClient instance using this engine
34
*/
35
fun install(client: HttpClient)
36
}
37
```
38
39
### HttpClientEngineFactory Interface
40
41
Factory interface for creating engine instances with configuration.
42
43
```kotlin { .api }
44
/**
45
* Factory for creating HTTP client engines
46
*/
47
interface HttpClientEngineFactory<out T : HttpClientEngineConfig> {
48
/**
49
* Create an engine instance with configuration
50
* @param block Configuration block for the engine
51
* @return Configured engine instance
52
*/
53
fun create(block: T.() -> Unit = {}): HttpClientEngine
54
}
55
```
56
57
**Usage Examples:**
58
59
```kotlin
60
import io.ktor.client.*
61
import io.ktor.client.engine.cio.*
62
63
// Create client with specific engine factory
64
val client = HttpClient(CIO) {
65
engine {
66
threadsCount = 4
67
pipelining = true
68
}
69
}
70
71
// Create engine directly
72
val engine = CIO.create {
73
threadsCount = 2
74
pipelining = false
75
}
76
val client2 = HttpClient(engine)
77
```
78
79
### HttpClientEngineConfig Class
80
81
Base configuration class for HTTP client engines.
82
83
```kotlin { .api }
84
/**
85
* Base configuration for HTTP client engines
86
*/
87
open class HttpClientEngineConfig {
88
/** Coroutine dispatcher for engine operations, null for default */
89
var dispatcher: CoroutineDispatcher? = null
90
91
/** Whether to enable HTTP pipelining */
92
var pipelining: Boolean = false
93
94
/** Number of threads to use for HTTP operations */
95
var threadsCount: Int = 4
96
97
/** Proxy configuration */
98
var proxy: ProxyConfig? = null
99
}
100
```
101
102
**Usage Examples:**
103
104
```kotlin
105
import io.ktor.client.*
106
import io.ktor.client.engine.cio.*
107
import kotlinx.coroutines.Dispatchers
108
109
val client = HttpClient(CIO) {
110
engine {
111
// Configure dispatcher
112
dispatcher = Dispatchers.IO
113
114
// Enable pipelining for better performance
115
pipelining = true
116
117
// Set thread count
118
threadsCount = 8
119
120
// Configure proxy if needed
121
proxy = ProxyBuilder.http("http://proxy.example.com:8080")
122
}
123
}
124
```
125
126
### Engine Capabilities
127
128
System for declaring and checking engine capabilities.
129
130
```kotlin { .api }
131
/**
132
* Marker interface for engine capabilities
133
*/
134
interface HttpClientEngineCapability<T : Any>
135
136
/**
137
* WebSocket capability marker
138
*/
139
data object WebSocketCapability : HttpClientEngineCapability<Unit>
140
141
/**
142
* Server-Sent Events capability marker
143
*/
144
data object SSECapability : HttpClientEngineCapability<Unit>
145
```
146
147
**Usage Examples:**
148
149
```kotlin
150
import io.ktor.client.*
151
import io.ktor.client.engine.*
152
153
val client = HttpClient()
154
155
// Check if engine supports WebSockets
156
if (client.isSupported(WebSocketCapability)) {
157
// Use WebSocket functionality
158
client.webSocket("wss://example.com/ws") {
159
// WebSocket operations
160
}
161
}
162
163
// Check if engine supports Server-Sent Events
164
if (client.isSupported(SSECapability)) {
165
// Use SSE functionality
166
client.sse("https://example.com/events") {
167
// SSE operations
168
}
169
}
170
```
171
172
### HttpResponseData Class
173
174
Data class representing the raw response data from an engine.
175
176
```kotlin { .api }
177
/**
178
* Raw HTTP response data from engine
179
*/
180
class HttpResponseData(
181
val statusCode: HttpStatusCode,
182
val requestTime: GMTDate,
183
val headers: Headers,
184
val version: HttpProtocolVersion,
185
val body: Any,
186
val callContext: CoroutineContext
187
) {
188
/** Timestamp when response was received */
189
val responseTime: GMTDate = GMTDate.now()
190
}
191
```
192
193
### Proxy Configuration
194
195
Configuration classes for HTTP proxy support.
196
197
```kotlin { .api }
198
/**
199
* Proxy configuration
200
*/
201
sealed class ProxyConfig {
202
abstract val url: Url
203
}
204
205
/**
206
* HTTP proxy configuration
207
*/
208
class ProxyBuilder {
209
companion object {
210
/**
211
* Create HTTP proxy configuration
212
* @param url Proxy URL
213
* @return ProxyConfig for HTTP proxy
214
*/
215
fun http(url: String): ProxyConfig
216
217
/**
218
* Create SOCKS proxy configuration
219
* @param host Proxy host
220
* @param port Proxy port
221
* @return ProxyConfig for SOCKS proxy
222
*/
223
fun socks(host: String, port: Int): ProxyConfig
224
}
225
}
226
```
227
228
**Usage Examples:**
229
230
```kotlin
231
import io.ktor.client.*
232
import io.ktor.client.engine.cio.*
233
234
val client = HttpClient(CIO) {
235
engine {
236
// HTTP proxy
237
proxy = ProxyBuilder.http("http://proxy.example.com:8080")
238
239
// SOCKS proxy
240
proxy = ProxyBuilder.socks("socks.example.com", 1080)
241
}
242
}
243
```
244
245
## Platform-Specific Engines
246
247
### JVM Engines
248
249
Available engines for JVM platform:
250
251
```kotlin { .api }
252
/**
253
* CIO engine factory for JVM (Coroutine-based I/O)
254
*/
255
object CIO : HttpClientEngineFactory<CIOEngineConfig>
256
257
/**
258
* Apache HTTP client engine factory
259
*/
260
object Apache : HttpClientEngineFactory<ApacheEngineConfig>
261
262
/**
263
* Java HTTP client engine factory (Java 11+)
264
*/
265
object Java : HttpClientEngineFactory<JavaHttpConfig>
266
267
/**
268
* Jetty HTTP client engine factory
269
*/
270
object Jetty : HttpClientEngineFactory<JettyEngineConfig>
271
272
/**
273
* OkHttp engine factory
274
*/
275
object OkHttp : HttpClientEngineFactory<OkHttpConfig>
276
```
277
278
### JavaScript Engines
279
280
Available engines for JavaScript platform:
281
282
```kotlin { .api }
283
/**
284
* JavaScript engine using browser APIs
285
*/
286
object Js : HttpClientEngineFactory<HttpClientEngineConfig>
287
288
/**
289
* Fetch API engine for modern browsers
290
*/
291
object JsFetch : HttpClientEngineFactory<HttpClientEngineConfig>
292
```
293
294
### Native Engines
295
296
Available engines for Native platforms:
297
298
```kotlin { .api }
299
/**
300
* Native engine using platform-specific HTTP implementations
301
*/
302
object Native : HttpClientEngineFactory<HttpClientEngineConfig>
303
304
/**
305
* WinHttp engine for Windows Native
306
*/
307
object WinHttp : HttpClientEngineFactory<WinHttpEngineConfig>
308
309
/**
310
* Darwin engine for iOS/macOS Native
311
*/
312
object Darwin : HttpClientEngineFactory<DarwinEngineConfig>
313
```
314
315
**Usage Examples:**
316
317
```kotlin
318
// JVM - CIO engine
319
val cioClient = HttpClient(CIO) {
320
engine {
321
threadsCount = 4
322
pipelining = true
323
}
324
}
325
326
// JVM - Apache engine
327
val apacheClient = HttpClient(Apache) {
328
engine {
329
threadsCount = 8
330
followRedirects = true
331
}
332
}
333
334
// JavaScript - Fetch API
335
val jsClient = HttpClient(JsFetch)
336
337
// Native - Darwin engine (iOS/macOS)
338
val darwinClient = HttpClient(Darwin) {
339
engine {
340
configureRequest {
341
setAllowsCellularAccess(false)
342
}
343
}
344
}
345
```
346
347
## Engine Exceptions
348
349
Exceptions specific to engine operations:
350
351
```kotlin { .api }
352
/**
353
* Thrown when engine is already closed
354
*/
355
class ClientEngineClosedException : IllegalStateException()
356
357
/**
358
* Thrown when using unsafe headers
359
*/
360
class UnsafeHeaderException(header: String) : IllegalArgumentException()
361
362
/**
363
* Connection timeout exception
364
*/
365
class ConnectTimeoutException(
366
message: String,
367
cause: Throwable? = null
368
) : IOException(message, cause)
369
370
/**
371
* Socket timeout exception
372
*/
373
class SocketTimeoutException(
374
message: String,
375
cause: Throwable? = null
376
) : IOException(message, cause)
377
```
378
379
**Usage Examples:**
380
381
```kotlin
382
import io.ktor.client.*
383
import io.ktor.client.engine.*
384
import io.ktor.client.request.*
385
386
val client = HttpClient()
387
388
try {
389
val response = client.get("https://slow-api.example.com")
390
} catch (e: ConnectTimeoutException) {
391
println("Connection timeout: ${e.message}")
392
} catch (e: SocketTimeoutException) {
393
println("Socket timeout: ${e.message}")
394
} catch (e: ClientEngineClosedException) {
395
println("Engine was closed")
396
} finally {
397
client.close()
398
}
399
```
400
401
## Types
402
403
Engine system related types:
404
405
```kotlin { .api }
406
/**
407
* Attribute key for engine capabilities
408
*/
409
val ENGINE_CAPABILITIES_KEY: AttributeKey<MutableMap<HttpClientEngineCapability<*>, Any>>
410
411
/**
412
* Outgoing content types for request bodies
413
*/
414
sealed class OutgoingContent {
415
abstract class ByteArrayContent : OutgoingContent()
416
abstract class ReadChannelContent : OutgoingContent()
417
abstract class WriteChannelContent : OutgoingContent()
418
abstract class ProtocolUpgrade : OutgoingContent()
419
abstract class NoContent : OutgoingContent()
420
}
421
422
/**
423
* Content type representation
424
*/
425
data class ContentType(
426
val contentType: String,
427
val contentSubtype: String,
428
val parameters: List<HeaderValueParam>
429
) {
430
companion object {
431
val Any = ContentType("*", "*")
432
433
object Application {
434
val Json = ContentType("application", "json")
435
val Xml = ContentType("application", "xml")
436
val FormUrlEncoded = ContentType("application", "x-www-form-urlencoded")
437
val OctetStream = ContentType("application", "octet-stream")
438
}
439
440
object Text {
441
val Plain = ContentType("text", "plain")
442
val Html = ContentType("text", "html")
443
val CSS = ContentType("text", "css")
444
}
445
446
object Image {
447
val PNG = ContentType("image", "png")
448
val JPEG = ContentType("image", "jpeg")
449
val GIF = ContentType("image", "gif")
450
}
451
452
object MultiPart {
453
val FormData = ContentType("multipart", "form-data")
454
val Mixed = ContentType("multipart", "mixed")
455
}
456
}
457
458
fun match(other: ContentType): Boolean
459
fun withParameter(name: String, value: String): ContentType
460
}
461
```