or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

builtin-plugins.mdcaching.mdcookies.mdengine-configuration.mdforms.mdhttp-client.mdindex.mdplugin-system.mdrequest-building.mdresponse-handling.mdresponse-observation.mdutilities.mdwebsockets.md

utilities.mddocs/

0

# Utilities and Extensions

1

2

The Ktor HTTP Client Core provides a comprehensive set of utility classes and extension functions for common HTTP client operations. These utilities include exception types, content handling utilities, coroutine integration helpers, client events, and platform-specific extensions that simplify HTTP client development.

3

4

## Exception Types

5

6

### Timeout Exceptions

7

8

Specialized exception types for handling various timeout scenarios in HTTP client operations.

9

10

```kotlin { .api }

11

class ConnectTimeoutException(

12

message: String,

13

cause: Throwable? = null

14

) : Exception(message, cause)

15

16

class SocketTimeoutException(

17

message: String,

18

cause: Throwable? = null

19

) : Exception(message, cause)

20

21

class HttpRequestTimeoutException(

22

request: HttpRequestData,

23

cause: Throwable? = null

24

) : Exception("Request timeout has expired", cause) {

25

val request: HttpRequestData = request

26

}

27

```

28

29

### Plugin-Specific Exceptions

30

31

```kotlin { .api }

32

class SaveBodyAbandonedReadException : Exception("Response body read operation was abandoned")

33

34

class NoTransformationFoundException(

35

from: TypeInfo,

36

to: TypeInfo

37

) : Exception("No transformation found from $from to $to")

38

39

class DoubleReceiveException : Exception("Response has already been received")

40

```

41

42

### Client Configuration Exceptions

43

44

```kotlin { .api }

45

class ClientEngineClosedException : Exception("Client engine is closed")

46

47

class UnsupportedContentTypeException(

48

contentType: ContentType

49

) : Exception("Unsupported content type: $contentType")

50

```

51

52

## Response Extension Functions

53

54

### Body Reading Extensions

55

56

Extension functions for reading response bodies in various formats with proper resource management.

57

58

```kotlin { .api }

59

// Read response as text

60

suspend fun HttpResponse.bodyAsText(charset: Charset = Charsets.UTF_8): String

61

62

// Read response as byte array

63

suspend fun HttpResponse.bodyAsBytes(): ByteArray

64

65

// Get response body as byte read channel

66

fun HttpResponse.bodyAsChannel(): ByteReadChannel

67

68

// Read response as typed object (requires serialization plugin)

69

suspend inline fun <reified T> HttpResponse.body(): T

70

suspend fun <T> HttpResponse.body(typeInfo: TypeInfo): T

71

72

// Save response to file

73

suspend fun HttpResponse.bodyAsChannel(): ByteReadChannel

74

suspend fun HttpResponse.readBytes(): ByteArray

75

suspend fun HttpResponse.readText(charset: Charset = Charsets.UTF_8): String

76

```

77

78

### Response Metadata Extensions

79

80

```kotlin { .api }

81

// Content type utilities

82

fun HttpResponse.contentType(): ContentType?

83

fun HttpResponse.contentLength(): Long?

84

fun HttpResponse.charset(): Charset?

85

86

// Header utilities

87

fun HttpResponse.etag(): String?

88

fun HttpResponse.lastModified(): GMTDate?

89

fun HttpResponse.cacheControl(): List<HeaderValue>?

90

91

// Status utilities

92

fun HttpResponse.isSuccess(): Boolean = status.isSuccess()

93

fun HttpResponse.isInformational(): Boolean = status.value in 100..199

94

fun HttpResponse.isRedirection(): Boolean = status.value in 300..399

95

fun HttpResponse.isClientError(): Boolean = status.value in 400..499

96

fun HttpResponse.isServerError(): Boolean = status.value in 500..599

97

```

98

99

## Content Utilities

100

101

### Content Type Handling

102

103

Utilities for working with HTTP content types and content negotiation.

104

105

```kotlin { .api }

106

// Content type matching and parsing

107

fun ContentType.match(other: ContentType): Boolean

108

fun ContentType.matchesWildcard(pattern: ContentType): Boolean

109

fun ContentType.withCharset(charset: Charset): ContentType

110

fun ContentType.withParameter(name: String, value: String): ContentType

111

112

// Default content types for common scenarios

113

object ContentType {

114

object Application {

115

val Json = ContentType("application", "json")

116

val Xml = ContentType("application", "xml")

117

val FormUrlEncoded = ContentType("application", "x-www-form-urlencoded")

118

val OctetStream = ContentType("application", "octet-stream")

119

val Pdf = ContentType("application", "pdf")

120

val Zip = ContentType("application", "zip")

121

}

122

123

object Text {

124

val Plain = ContentType("text", "plain")

125

val Html = ContentType("text", "html")

126

val CSS = ContentType("text", "css")

127

val JavaScript = ContentType("text", "javascript")

128

val CSV = ContentType("text", "csv")

129

}

130

131

object Image {

132

val JPEG = ContentType("image", "jpeg")

133

val PNG = ContentType("image", "png")

134

val GIF = ContentType("image", "gif")

135

val SVG = ContentType("image", "svg+xml")

136

val Any = ContentType("image", "*")

137

}

138

139

object Video {

140

val MP4 = ContentType("video", "mp4")

141

val AVI = ContentType("video", "x-msvideo")

142

val QuickTime = ContentType("video", "quicktime")

143

}

144

145

object Audio {

146

val MP3 = ContentType("audio", "mpeg")

147

val WAV = ContentType("audio", "wav")

148

val OGG = ContentType("audio", "ogg")

149

}

150

151

object MultiPart {

152

val FormData = ContentType("multipart", "form-data")

153

val Mixed = ContentType("multipart", "mixed")

154

val Alternative = ContentType("multipart", "alternative")

155

}

156

}

157

158

// File extension to content type mapping

159

fun ContentType.Companion.defaultForFile(file: File): ContentType

160

fun ContentType.Companion.defaultForExtension(extension: String): ContentType

161

```

162

163

### Content Encoding Utilities

164

165

```kotlin { .api }

166

// Content encoding support

167

enum class ContentEncoding(val value: String) {

168

GZIP("gzip"),

169

DEFLATE("deflate"),

170

BR("br"),

171

COMPRESS("compress"),

172

IDENTITY("identity")

173

}

174

175

// Content length calculation

176

fun OutgoingContent.contentLength(): Long?

177

fun OutgoingContent.isChunked(): Boolean

178

```

179

180

### Upgrade Content

181

182

Special content type for protocol upgrades like WebSockets.

183

184

```kotlin { .api }

185

class ClientUpgradeContent : OutgoingContent {

186

override val contentType: ContentType? = null

187

override val contentLength: Long? = null

188

189

override fun upgrade(

190

input: ByteReadChannel,

191

output: ByteWriteChannel,

192

engineContext: CoroutineContext,

193

userContext: CoroutineContext

194

): Job

195

}

196

```

197

198

## Client Events

199

200

### Event System

201

202

Event definitions for monitoring HTTP client lifecycle and operations.

203

204

```kotlin { .api }

205

// Request lifecycle events

206

object HttpRequestCreated : EventDefinition<HttpRequestBuilder>()

207

object HttpRequestIsReadyForSending : EventDefinition<HttpRequest>()

208

209

// Response lifecycle events

210

object HttpResponseReceived : EventDefinition<HttpResponseContainer>()

211

object HttpResponseCancelled : EventDefinition<HttpResponseContainer>()

212

213

// Connection events

214

object HttpConnectionCreated : EventDefinition<HttpConnection>()

215

object HttpConnectionClosed : EventDefinition<HttpConnection>()

216

217

// Event containers

218

data class HttpResponseContainer(

219

val response: HttpResponse

220

)

221

222

data class HttpConnection(

223

val host: String,

224

val port: Int,

225

val secure: Boolean

226

)

227

```

228

229

### Event Monitoring

230

231

```kotlin { .api }

232

// Event monitoring with Events interface

233

interface Events {

234

fun <T> subscribe(definition: EventDefinition<T>, handler: suspend (T) -> Unit): Closeable

235

suspend fun <T> raise(definition: EventDefinition<T>, value: T)

236

}

237

238

// Usage example

239

val client = HttpClient()

240

241

val subscription = client.monitor.subscribe(HttpResponseReceived) { container ->

242

println("Response received: ${container.response.status}")

243

}

244

245

// Don't forget to unsubscribe

246

subscription.close()

247

```

248

249

## Coroutine Utilities

250

251

### Coroutine Context Management

252

253

Utilities for proper coroutine context handling in HTTP client operations.

254

255

```kotlin { .api }

256

// Coroutine context utilities

257

fun CoroutineContext.clientContext(): CoroutineContext

258

fun CoroutineContext.withClientDefaults(): CoroutineContext

259

260

// Supervisor job for request isolation

261

fun SupervisorJob.createChildJob(): Job

262

263

// Cancellation utilities

264

suspend fun <T> withCancellation(block: suspend CoroutineScope.() -> T): T

265

fun Job.cancelWithCause(cause: Throwable? = null)

266

```

267

268

### Timeout Utilities

269

270

```kotlin { .api }

271

// Timeout configuration

272

data class HttpTimeoutConfig(

273

val requestTimeoutMillis: Long? = null,

274

val connectTimeoutMillis: Long? = null,

275

val socketTimeoutMillis: Long? = null

276

)

277

278

// Timeout application

279

suspend fun <T> withHttpTimeout(

280

config: HttpTimeoutConfig,

281

block: suspend CoroutineScope.() -> T

282

): T

283

284

// Per-request timeout

285

fun HttpRequestBuilder.timeout(block: HttpTimeoutConfig.() -> Unit)

286

```

287

288

## Header Utilities

289

290

### Header Construction and Manipulation

291

292

Utilities for building and manipulating HTTP headers with type safety.

293

294

```kotlin { .api }

295

// Header building utilities

296

fun headersOf(vararg pairs: Pair<String, String>): Headers

297

fun headersOf(vararg pairs: Pair<String, List<String>>): Headers

298

299

class HeadersBuilder {

300

fun append(name: String, value: String)

301

fun appendAll(headers: Headers)

302

fun remove(name: String)

303

fun clear()

304

fun build(): Headers

305

}

306

307

// Common header utilities

308

fun Headers.authorization(): String?

309

fun Headers.cacheControl(): List<HeaderValue>

310

fun Headers.contentType(): ContentType?

311

fun Headers.contentLength(): Long?

312

fun Headers.userAgent(): String?

313

314

// Header value parsing

315

data class HeaderValue(

316

val value: String,

317

val parameters: Map<String, String> = emptyMap()

318

) {

319

companion object {

320

fun parse(headerValue: String): HeaderValue

321

fun parseList(headerValue: String): List<HeaderValue>

322

}

323

}

324

```

325

326

### Authentication Headers

327

328

```kotlin { .api }

329

// Authentication header utilities

330

fun HeadersBuilder.bearerAuth(token: String) {

331

append(HttpHeaders.Authorization, "Bearer $token")

332

}

333

334

fun HeadersBuilder.basicAuth(username: String, password: String) {

335

val credentials = "$username:$password".encodeBase64()

336

append(HttpHeaders.Authorization, "Basic $credentials")

337

}

338

339

fun HeadersBuilder.apiKeyAuth(apiKey: String, headerName: String = "X-API-Key") {

340

append(headerName, apiKey)

341

}

342

```

343

344

## ByteChannel Utilities

345

346

### Channel Extensions

347

348

Extension functions for working with ByteReadChannel and ByteWriteChannel.

349

350

```kotlin { .api }

351

// ByteReadChannel utilities

352

suspend fun ByteReadChannel.readUTF8Line(limit: Int = Int.MAX_VALUE): String?

353

suspend fun ByteReadChannel.readBytes(): ByteArray

354

suspend fun ByteReadChannel.readBytes(count: Int): ByteArray

355

suspend fun ByteReadChannel.copyTo(output: ByteWriteChannel): Long

356

suspend fun ByteReadChannel.copyTo(output: OutputStream): Long

357

358

// ByteWriteChannel utilities

359

suspend fun ByteWriteChannel.writeStringUtf8(s: String)

360

suspend fun ByteWriteChannel.writeFully(src: ByteArray)

361

suspend fun ByteWriteChannel.writeFully(src: ByteArray, offset: Int, length: Int)

362

363

// Content reading utilities

364

suspend fun ByteReadChannel.readRemaining(limit: Long = Long.MAX_VALUE): ByteReadPacket

365

suspend fun ByteReadChannel.readText(charset: Charset = Charsets.UTF_8): String

366

```

367

368

### Stream Conversion

369

370

```kotlin { .api }

371

// Convert between different stream types

372

fun ByteReadChannel.toInputStream(): InputStream

373

fun InputStream.toByteReadChannel(): ByteReadChannel

374

fun ByteWriteChannel.toOutputStream(): OutputStream

375

fun OutputStream.toByteWriteChannel(): ByteWriteChannel

376

377

// Buffered operations

378

fun ByteReadChannel.buffered(bufferSize: Int = DEFAULT_BUFFER_SIZE): ByteReadChannel

379

fun ByteWriteChannel.buffered(bufferSize: Int = DEFAULT_BUFFER_SIZE): ByteWriteChannel

380

```

381

382

## Cache Control Utilities

383

384

### Cache Directive Handling

385

386

Utilities for parsing and constructing HTTP cache control directives.

387

388

```kotlin { .api }

389

// Cache control directive parsing

390

data class CacheControl(

391

val maxAge: Int? = null,

392

val maxStale: Int? = null,

393

val minFresh: Int? = null,

394

val noCache: Boolean = false,

395

val noStore: Boolean = false,

396

val noTransform: Boolean = false,

397

val onlyIfCached: Boolean = false,

398

val mustRevalidate: Boolean = false,

399

val public: Boolean = false,

400

val private: Boolean = false,

401

val proxyRevalidate: Boolean = false,

402

val immutable: Boolean = false,

403

val staleWhileRevalidate: Int? = null,

404

val staleIfError: Int? = null

405

) {

406

companion object {

407

fun parse(headerValue: String): CacheControl

408

}

409

410

fun toHeaderValue(): String

411

}

412

413

// Cache control builder

414

fun cacheControl(block: CacheControlBuilder.() -> Unit): CacheControl

415

416

class CacheControlBuilder {

417

fun maxAge(seconds: Int)

418

fun noCache()

419

fun noStore()

420

fun mustRevalidate()

421

fun private()

422

fun public()

423

// ... other directives

424

}

425

```

426

427

## URL Utilities

428

429

### URL Building and Manipulation

430

431

```kotlin { .api }

432

// URL construction utilities

433

fun URLBuilder.takeFrom(url: Url): URLBuilder

434

fun URLBuilder.takeFrom(url: String): URLBuilder

435

436

// URL parameter utilities

437

fun URLBuilder.parameter(key: String, value: Any?)

438

fun URLBuilder.parameters(parameters: Parameters)

439

fun URLBuilder.encodedParameters(parameters: String)

440

441

// Path utilities

442

fun URLBuilder.path(vararg components: String)

443

fun URLBuilder.appendEncodedPathSegments(segments: String)

444

fun URLBuilder.pathSegments(segments: List<String>)

445

446

// Fragment utilities

447

fun URLBuilder.fragment(fragment: String?)

448

fun URLBuilder.encodedFragment(fragment: String?)

449

```

450

451

## Platform-Specific Utilities

452

453

### JVM Platform Extensions

454

455

```kotlin { .api }

456

// JVM-specific HttpClient extensions

457

fun HttpClient.executeBlocking(request: HttpRequestBuilder): HttpResponse

458

459

// Service loader integration

460

fun HttpClientEngineFactory.Companion.fromServiceLoader(): List<HttpClientEngineFactory<*>>

461

462

// Java interop utilities

463

fun HttpResponse.toCompletableFuture(): CompletableFuture<HttpResponse>

464

fun HttpClient.async(): AsyncHttpClient

465

```

466

467

### JavaScript Platform Extensions

468

469

```kotlin { .api }

470

// JavaScript Fetch API integration

471

external interface FetchOptions {

472

var method: String?

473

var headers: dynamic

474

var body: dynamic

475

var mode: String?

476

var credentials: String?

477

}

478

479

// Browser-specific utilities

480

fun HttpClient.withCredentials(include: Boolean = true): HttpClient

481

fun HttpRequestBuilder.cors(block: CorsConfig.() -> Unit)

482

483

class CorsConfig {

484

var mode: RequestMode = RequestMode.CORS

485

var credentials: RequestCredentials = RequestCredentials.SAME_ORIGIN

486

}

487

```

488

489

### Native Platform Extensions

490

491

```kotlin { .api }

492

// Native platform networking utilities

493

fun HttpClientEngineConfig.configureNativeSocket(block: NativeSocketConfig.() -> Unit)

494

495

class NativeSocketConfig {

496

var keepAlive: Boolean = true

497

var tcpNoDelay: Boolean = true

498

var socketTimeout: Duration? = null

499

}

500

501

// Platform-specific SSL configuration

502

fun HttpClientEngineConfig.configureTLS(block: TLSConfig.() -> Unit)

503

504

class TLSConfig {

505

var trustManager: X509TrustManager? = null

506

var keyManager: X509KeyManager? = null

507

var protocols: List<String> = listOf("TLSv1.2", "TLSv1.3")

508

}

509

```

510

511

## Error Handling Utilities

512

513

### Exception Wrapping and Conversion

514

515

```kotlin { .api }

516

// Exception conversion utilities

517

fun Throwable.wrapIfNeeded(): Exception

518

fun Exception.unwrapCancellation(): Exception?

519

520

// HTTP-specific exception utilities

521

fun HttpStatusCode.toException(response: HttpResponse): Exception

522

fun createHttpException(status: HttpStatusCode, message: String): Exception

523

524

// Retry utilities

525

suspend fun <T> retryIO(

526

times: Int = 3,

527

initialDelay: Long = 100,

528

maxDelay: Long = 1000,

529

factor: Double = 2.0,

530

block: suspend () -> T

531

): T

532

```

533

534

### Validation Utilities

535

536

```kotlin { .api }

537

// Request validation

538

fun HttpRequestBuilder.validate()

539

fun validateUrl(url: String): Boolean

540

fun validateHeaders(headers: Headers): List<String>

541

542

// Response validation

543

fun HttpResponse.validateContentType(expected: ContentType): Boolean

544

fun HttpResponse.validateStatus(validStatuses: Set<HttpStatusCode>): Boolean

545

```

546

547

## Best Practices

548

549

1. **Use Extension Functions**: Leverage extension functions for cleaner, more readable code

550

2. **Handle Exceptions Properly**: Catch and handle specific exception types appropriately

551

3. **Resource Management**: Always close resources like InputStreams and channels

552

4. **Content Type Detection**: Use utility functions for accurate content type handling

553

5. **Timeout Configuration**: Set appropriate timeouts for different operation types

554

6. **Header Utilities**: Use header utility functions instead of string manipulation

555

7. **Platform Awareness**: Use platform-specific utilities when targeting specific platforms

556

8. **Error Propagation**: Properly propagate errors with meaningful exception types

557

9. **Memory Efficiency**: Use streaming utilities for large content to avoid memory issues

558

10. **Thread Safety**: Be aware that many utilities are not thread-safe by default

559

11. **Charset Handling**: Always specify charset explicitly when working with text content

560

12. **Validation**: Use validation utilities to catch configuration errors early