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

engine-configuration.mddocs/

0

# Engine Configuration

1

2

The HTTP engine abstraction layer provides pluggable HTTP implementations across platforms with comprehensive configuration options for connection management, proxies, and platform-specific settings.

3

4

## Core Engine Interface

5

6

```kotlin { .api }

7

interface HttpClientEngine : CoroutineScope, Closeable {

8

val config: HttpClientEngineConfig

9

val dispatcher: CoroutineDispatcher

10

val supportedCapabilities: Set<HttpClientEngineCapability<*>>

11

12

suspend fun execute(data: HttpRequestData): HttpResponseData

13

override fun close()

14

}

15

16

interface HttpClientEngineFactory<T : HttpClientEngineConfig> {

17

fun create(block: T.() -> Unit = {}): HttpClientEngine

18

}

19

20

abstract class HttpClientEngineBase(

21

engineName: String

22

) : HttpClientEngine {

23

protected val engine: String = engineName

24

protected abstract suspend fun execute(data: HttpRequestData): HttpResponseData

25

26

// Utility methods for subclasses

27

protected fun HttpRequestData.isUpgradeRequest(): Boolean

28

protected fun HttpRequestData.requiresDuplexConnection(): Boolean

29

}

30

```

31

32

## Engine Configuration

33

34

```kotlin { .api }

35

open class HttpClientEngineConfig {

36

var threadsCount: Int = 4

37

var pipelining: Boolean = false

38

var proxy: ProxyConfig? = null

39

40

// Connection settings

41

val requestsJob: CompletableJob = Job()

42

43

internal val clientConfig: HttpClientConfig<*>? = null

44

}

45

46

data class ProxyConfig(

47

val type: Type,

48

val address: SocketAddress

49

) {

50

enum class Type { HTTP, SOCKS }

51

52

companion object {

53

fun http(host: String, port: Int): ProxyConfig

54

fun socks(host: String, port: Int): ProxyConfig

55

}

56

}

57

```

58

59

## Engine Selection

60

61

### Platform Default Engines

62

```kotlin

63

// Uses platform-appropriate default engine

64

val client = HttpClient()

65

66

// Platform defaults:

67

// - JVM: CIO or OkHttp (if available)

68

// - JavaScript: Js (Fetch API)

69

// - Native: Curl

70

```

71

72

### Explicit Engine Selection

73

```kotlin

74

// Using specific engine factory

75

val client = HttpClient(engineFactory) {

76

// Engine-specific configuration

77

threadsCount = 8

78

pipelining = true

79

}

80

```

81

82

### Engine with Configuration

83

```kotlin

84

val client = HttpClient {

85

engine(engineFactory) {

86

// Engine configuration

87

threadsCount = 4

88

pipelining = false

89

90

// Proxy configuration

91

proxy = ProxyConfig.http("proxy.example.com", 8080)

92

}

93

}

94

```

95

96

## Proxy Configuration

97

98

### HTTP Proxy

99

```kotlin

100

val client = HttpClient {

101

engine(CIO) {

102

proxy = ProxyConfig.http("proxy.example.com", 8080)

103

}

104

}

105

```

106

107

### SOCKS Proxy

108

```kotlin

109

val client = HttpClient {

110

engine(CIO) {

111

proxy = ProxyConfig.socks("socks.example.com", 1080)

112

}

113

}

114

```

115

116

### No Proxy

117

```kotlin

118

val client = HttpClient {

119

engine(CIO) {

120

proxy = null // Disable proxy

121

}

122

}

123

```

124

125

## Engine Capabilities

126

127

```kotlin { .api }

128

interface HttpClientEngineCapability<T> {

129

val key: String

130

}

131

132

// Built-in capabilities

133

object HttpTimeoutCapability : HttpClientEngineCapability<HttpTimeoutConfig>

134

object WebSocketCapability : HttpClientEngineCapability<Unit>

135

object HttpRedirectCapability : HttpClientEngineCapability<HttpRedirect.Config>

136

```

137

138

### Checking Engine Capabilities

139

```kotlin

140

val engine = client.engine

141

142

if (WebSocketCapability in engine.supportedCapabilities) {

143

println("Engine supports WebSockets")

144

}

145

146

if (HttpTimeoutCapability in engine.supportedCapabilities) {

147

println("Engine supports timeouts")

148

}

149

```

150

151

## Connection Management

152

153

### Thread Pool Configuration

154

```kotlin

155

val client = HttpClient {

156

engine(CIO) {

157

// Set number of threads for connection pool

158

threadsCount = 8

159

160

// Enable HTTP pipelining

161

pipelining = true

162

}

163

}

164

```

165

166

### Connection Timeouts

167

Engine-specific timeout configuration:

168

169

```kotlin

170

val client = HttpClient {

171

engine(CIO) {

172

// CIO-specific timeouts

173

connectTimeout = 10000 // 10 seconds

174

requestTimeout = 30000 // 30 seconds

175

}

176

}

177

```

178

179

## Platform-Specific Engines

180

181

### JVM Platform

182

183

#### CIO Engine

184

```kotlin

185

val client = HttpClient(CIO) {

186

threadsCount = 4

187

pipelining = false

188

189

// CIO-specific settings

190

maxConnectionsCount = 1000

191

endpoint {

192

maxConnectionsPerRoute = 100

193

pipelineMaxSize = 20

194

keepAliveTime = 5000

195

connectTimeout = 5000

196

connectAttempts = 5

197

}

198

}

199

```

200

201

#### OkHttp Engine (if available)

202

```kotlin

203

val client = HttpClient(OkHttp) {

204

// OkHttp-specific configuration

205

config {

206

// Configure OkHttpClient

207

followRedirects(true)

208

connectTimeout(30, TimeUnit.SECONDS)

209

readTimeout(30, TimeUnit.SECONDS)

210

}

211

}

212

```

213

214

### JavaScript Platform

215

216

#### JS Engine (Fetch API)

217

```kotlin

218

val client = HttpClient(Js) {

219

// JS engine uses browser's fetch API

220

// Limited configuration options

221

}

222

```

223

224

### Native Platform

225

226

#### Curl Engine

227

```kotlin

228

val client = HttpClient(Curl) {

229

// Curl-specific configuration

230

sslOptions {

231

// SSL/TLS configuration

232

}

233

}

234

```

235

236

## Engine Lifecycle

237

238

### Manual Engine Management

239

```kotlin

240

val engine = engineFactory.create {

241

threadsCount = 4

242

pipelining = true

243

}

244

245

val client = HttpClient(engine)

246

247

// Manual cleanup

248

client.close()

249

engine.close()

250

```

251

252

### Shared Engine Instances

253

```kotlin

254

val sharedEngine = CIO.create {

255

threadsCount = 8

256

}

257

258

// Multiple clients can share the same engine

259

val client1 = HttpClient(sharedEngine)

260

val client2 = HttpClient(sharedEngine)

261

262

// Only close engine after all clients are closed

263

client1.close()

264

client2.close()

265

sharedEngine.close()

266

```

267

268

## Engine Utils

269

270

```kotlin { .api }

271

// Engine utility functions

272

fun HttpClientEngineConfig.proxy(type: ProxyConfig.Type, host: String, port: Int)

273

274

// Request data utilities

275

fun HttpRequestData.isWebSocketRequest(): Boolean

276

fun HttpRequestData.isUpgradeRequest(): Boolean

277

278

// Response data utilities

279

class HttpResponseData(

280

val statusCode: HttpStatusCode,

281

val requestTime: GMTDate,

282

val headers: Headers,

283

val version: HttpProtocolVersion,

284

val body: ByteReadChannel,

285

val callContext: CoroutineContext

286

)

287

```

288

289

## Custom Engine Implementation

290

291

### Basic Custom Engine

292

```kotlin

293

class MyCustomEngine(

294

override val config: MyCustomEngineConfig

295

) : HttpClientEngineBase("MyCustomEngine") {

296

297

override val dispatcher: CoroutineDispatcher = Dispatchers.IO

298

299

override suspend fun execute(data: HttpRequestData): HttpResponseData {

300

// Custom HTTP implementation

301

return HttpResponseData(

302

statusCode = HttpStatusCode.OK,

303

requestTime = GMTDate(),

304

headers = Headers.Empty,

305

version = HttpProtocolVersion.HTTP_1_1,

306

body = ByteReadChannel.Empty,

307

callContext = coroutineContext

308

)

309

}

310

311

override fun close() {

312

// Cleanup resources

313

}

314

}

315

316

class MyCustomEngineConfig : HttpClientEngineConfig() {

317

// Custom configuration properties

318

var customProperty: String = "default"

319

}

320

321

object MyCustomEngineFactory : HttpClientEngineFactory<MyCustomEngineConfig> {

322

override fun create(block: MyCustomEngineConfig.() -> Unit): HttpClientEngine {

323

val config = MyCustomEngineConfig().apply(block)

324

return MyCustomEngine(config)

325

}

326

}

327

```

328

329

### Using Custom Engine

330

```kotlin

331

val client = HttpClient(MyCustomEngineFactory) {

332

customProperty = "custom value"

333

threadsCount = 2

334

}

335

```

336

337

## Engine Testing

338

339

### Mock Engine for Testing

340

```kotlin

341

val mockEngine = MockEngine { request ->

342

respond(

343

content = """{"id": 1, "name": "John"}""",

344

status = HttpStatusCode.OK,

345

headers = headersOf(HttpHeaders.ContentType, "application/json")

346

)

347

}

348

349

val client = HttpClient(mockEngine)

350

val response = client.get("http://test.com/users/1")

351

// Response will be the mocked data

352

```

353

354

## Error Handling

355

356

### Engine-Specific Errors

357

```kotlin

358

try {

359

val response = client.get("https://example.com")

360

} catch (e: ConnectTimeoutException) {

361

println("Connection timeout")

362

} catch (e: SocketTimeoutException) {

363

println("Read timeout")

364

} catch (e: UnresolvedAddressException) {

365

println("DNS resolution failed")

366

} catch (e: ConnectException) {

367

println("Connection failed")

368

}

369

```

370

371

### Engine Capability Errors

372

```kotlin

373

try {

374

client.webSocket("wss://example.com/ws") {

375

// WebSocket code

376

}

377

} catch (e: UnsupportedOperationException) {

378

println("Current engine doesn't support WebSockets")

379

}

380

```