or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

client-configuration.mdcookie-management.mdforms-and-uploads.mdhttp-caching.mdhttp-requests.mdindex.mdplugin-system.mdresponse-handling.mdserver-sent-events.mdwebsockets.md

cookie-management.mddocs/

0

# Cookie Management

1

2

HTTP cookie handling with multiple storage implementations, automatic cookie management, and comprehensive cookie processing capabilities.

3

4

## Capabilities

5

6

### Cookie Plugin Installation

7

8

Install and configure the HttpCookies plugin for automatic cookie management.

9

10

```kotlin { .api }

11

/**

12

* HTTP Cookies plugin for automatic cookie handling

13

*/

14

object HttpCookies : HttpClientPlugin<HttpCookiesConfig, HttpCookiesConfig> {

15

override val key: AttributeKey<HttpCookiesConfig>

16

17

/**

18

* Cookies configuration

19

*/

20

class HttpCookiesConfig {

21

/** Cookie storage implementation */

22

var storage: CookiesStorage = AcceptAllCookiesStorage()

23

}

24

}

25

```

26

27

**Usage Examples:**

28

29

```kotlin

30

val client = HttpClient {

31

install(HttpCookies) {

32

// Use default storage (accepts all cookies)

33

storage = AcceptAllCookiesStorage()

34

}

35

}

36

37

// Client will now automatically handle cookies

38

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

39

// Cookies from previous requests are automatically included

40

}

41

42

// Set-Cookie headers in responses are automatically processed and stored

43

val loginResponse = client.post("https://example.com/login") {

44

setBody(FormDataContent(Parameters.build {

45

append("username", "user")

46

append("password", "pass")

47

}))

48

}

49

50

// Session cookies are automatically included in subsequent requests

51

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

52

```

53

54

### Cookie Storage Interface

55

56

Core interface for cookie storage implementations.

57

58

```kotlin { .api }

59

/**

60

* Cookie storage interface for managing HTTP cookies

61

*/

62

interface CookiesStorage {

63

/**

64

* Get cookies for a specific URL

65

* @param requestUrl Target URL

66

* @returns List of applicable cookies

67

*/

68

suspend fun get(requestUrl: Url): List<Cookie>

69

70

/**

71

* Add a cookie from a response

72

* @param requestUrl Original request URL

73

* @param cookie Cookie to store

74

*/

75

suspend fun addCookie(requestUrl: Url, cookie: Cookie)

76

77

/**

78

* Remove all cookies

79

*/

80

suspend fun close(): Unit = Unit

81

}

82

```

83

84

### Built-in Storage Implementations

85

86

Ready-to-use cookie storage implementations for different use cases.

87

88

```kotlin { .api }

89

/**

90

* Storage that accepts and stores all cookies

91

*/

92

class AcceptAllCookiesStorage : CookiesStorage {

93

override suspend fun get(requestUrl: Url): List<Cookie>

94

override suspend fun addCookie(requestUrl: Url, cookie: Cookie)

95

override suspend fun close()

96

}

97

98

/**

99

* Storage with predefined constant cookies

100

*/

101

class ConstantCookiesStorage(

102

private val cookies: List<Cookie>

103

) : CookiesStorage {

104

override suspend fun get(requestUrl: Url): List<Cookie>

105

override suspend fun addCookie(requestUrl: Url, cookie: Cookie)

106

}

107

108

/**

109

* Memory-based cookie storage with size limits

110

*/

111

class MemoryCookiesStorage(

112

private val maxCookies: Int = 1000

113

) : CookiesStorage {

114

override suspend fun get(requestUrl: Url): List<Cookie>

115

override suspend fun addCookie(requestUrl: Url, cookie: Cookie)

116

override suspend fun close()

117

}

118

```

119

120

**Usage Examples:**

121

122

```kotlin

123

// Accept all cookies (default)

124

val clientAcceptAll = HttpClient {

125

install(HttpCookies) {

126

storage = AcceptAllCookiesStorage()

127

}

128

}

129

130

// Use constant predefined cookies

131

val constantCookies = listOf(

132

Cookie("api_key", "abc123", domain = "api.example.com"),

133

Cookie("client_id", "mobile_app", domain = "api.example.com")

134

)

135

136

val clientConstant = HttpClient {

137

install(HttpCookies) {

138

storage = ConstantCookiesStorage(constantCookies)

139

}

140

}

141

142

// Memory storage with size limit

143

val clientMemory = HttpClient {

144

install(HttpCookies) {

145

storage = MemoryCookiesStorage(maxCookies = 500)

146

}

147

}

148

```

149

150

### Cookie Access Functions

151

152

Functions for accessing and managing cookies programmatically.

153

154

```kotlin { .api }

155

/**

156

* Get cookies for a specific URL

157

* @param urlString Target URL

158

* @returns List of cookies applicable to the URL

159

*/

160

suspend fun HttpClient.cookies(urlString: String): List<Cookie>

161

162

/**

163

* Get cookies for a specific URL object

164

* @param url Target URL

165

* @returns List of cookies applicable to the URL

166

*/

167

suspend fun HttpClient.cookies(url: Url): List<Cookie>

168

169

/**

170

* Add a cookie manually

171

* @param urlString URL to associate the cookie with

172

* @param cookie Cookie to add

173

*/

174

suspend fun HttpClient.addCookie(urlString: String, cookie: Cookie)

175

176

/**

177

* Clear all cookies from storage

178

*/

179

suspend fun HttpClient.clearCookies()

180

```

181

182

**Usage Examples:**

183

184

```kotlin

185

val client = HttpClient {

186

install(HttpCookies)

187

}

188

189

// Make initial request that sets cookies

190

client.get("https://example.com/login")

191

192

// Get cookies for a URL

193

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

194

cookies.forEach { cookie ->

195

println("Cookie: ${cookie.name}=${cookie.value}")

196

println("Domain: ${cookie.domain}")

197

println("Path: ${cookie.path}")

198

println("Expires: ${cookie.expires}")

199

println("HttpOnly: ${cookie.httpOnly}")

200

println("Secure: ${cookie.secure}")

201

println("---")

202

}

203

204

// Add cookie manually

205

val customCookie = Cookie(

206

name = "custom_setting",

207

value = "enabled",

208

domain = "example.com",

209

path = "/",

210

httpOnly = false,

211

secure = true

212

)

213

client.addCookie("https://example.com", customCookie)

214

215

// Clear all cookies

216

client.clearCookies()

217

```

218

219

### Cookie Data Class

220

221

Comprehensive cookie representation with all standard cookie attributes.

222

223

```kotlin { .api }

224

/**

225

* HTTP cookie representation

226

*/

227

data class Cookie(

228

/** Cookie name */

229

val name: String,

230

231

/** Cookie value */

232

val value: String,

233

234

/** Cookie encoding (default: UTF-8) */

235

val encoding: CookieEncoding = CookieEncoding.URI_ENCODING,

236

237

/** Maximum age in seconds */

238

val maxAge: Int = 0,

239

240

/** Expiration date */

241

val expires: GMTDate? = null,

242

243

/** Domain scope */

244

val domain: String? = null,

245

246

/** Path scope */

247

val path: String? = null,

248

249

/** Secure flag (HTTPS only) */

250

val secure: Boolean = false,

251

252

/** HttpOnly flag (no JavaScript access) */

253

val httpOnly: Boolean = false,

254

255

/** SameSite attribute */

256

val sameSite: SameSite? = null,

257

258

/** Additional cookie extensions */

259

val extensions: Map<String, String?> = emptyMap()

260

) {

261

companion object {

262

/**

263

* Parse cookie from Set-Cookie header value

264

* @param cookieHeader Set-Cookie header value

265

* @returns Parsed Cookie object

266

*/

267

fun parse(cookieHeader: String): Cookie

268

269

/**

270

* Create session cookie (no expiration)

271

* @param name Cookie name

272

* @param value Cookie value

273

* @param domain Optional domain

274

* @param path Optional path

275

* @returns Session cookie

276

*/

277

fun session(name: String, value: String, domain: String? = null, path: String? = null): Cookie

278

279

/**

280

* Create secure cookie with common security settings

281

* @param name Cookie name

282

* @param value Cookie value

283

* @param domain Cookie domain

284

* @returns Secure cookie with HttpOnly and Secure flags

285

*/

286

fun secure(name: String, value: String, domain: String): Cookie

287

}

288

}

289

290

/**

291

* Cookie encoding options

292

*/

293

enum class CookieEncoding {

294

/** URI encoding */

295

URI_ENCODING,

296

297

/** Base64 encoding */

298

BASE64_ENCODING,

299

300

/** DQuotes encoding */

301

DQUOTES,

302

303

/** Raw encoding (no encoding) */

304

RAW

305

}

306

307

/**

308

* SameSite cookie attribute

309

*/

310

enum class SameSite {

311

/** Strict SameSite policy */

312

Strict,

313

314

/** Lax SameSite policy */

315

Lax,

316

317

/** None SameSite policy (requires Secure) */

318

None

319

}

320

```

321

322

**Usage Examples:**

323

324

```kotlin

325

// Create various types of cookies

326

val sessionCookie = Cookie.session("session_id", "abc123", domain = "example.com")

327

328

val securityCookie = Cookie.secure("csrf_token", "xyz789", "example.com")

329

330

val customCookie = Cookie(

331

name = "preferences",

332

value = "theme=dark&lang=en",

333

domain = "example.com",

334

path = "/",

335

maxAge = 3600, // 1 hour

336

secure = true,

337

httpOnly = false,

338

sameSite = SameSite.Lax,

339

extensions = mapOf("Priority" to "High")

340

)

341

342

// Parse cookie from header

343

val headerValue = "sessionid=abc123; Path=/; Domain=.example.com; Secure; HttpOnly"

344

val parsedCookie = Cookie.parse(headerValue)

345

346

// Use cookies with client

347

val client = HttpClient {

348

install(HttpCookies)

349

}

350

351

client.addCookie("https://example.com", sessionCookie)

352

client.addCookie("https://example.com", securityCookie)

353

client.addCookie("https://example.com", customCookie)

354

```

355

356

### Custom Cookie Storage

357

358

Create custom cookie storage implementations for specific requirements.

359

360

```kotlin { .api }

361

/**

362

* Example: File-based cookie storage

363

*/

364

class FileCookiesStorage(

365

private val file: File

366

) : CookiesStorage {

367

private val cookies = mutableListOf<Cookie>()

368

369

init {

370

loadCookiesFromFile()

371

}

372

373

override suspend fun get(requestUrl: Url): List<Cookie> {

374

return cookies.filter { cookie ->

375

cookieMatchesUrl(cookie, requestUrl)

376

}

377

}

378

379

override suspend fun addCookie(requestUrl: Url, cookie: Cookie) {

380

// Remove existing cookie with same name and domain

381

cookies.removeAll { it.name == cookie.name && it.domain == cookie.domain }

382

383

// Add new cookie if not expired

384

if (!isCookieExpired(cookie)) {

385

cookies.add(cookie)

386

saveCookiesToFile()

387

}

388

}

389

390

override suspend fun close() {

391

saveCookiesToFile()

392

}

393

394

private fun loadCookiesFromFile() {

395

// Implementation for loading cookies from file

396

}

397

398

private fun saveCookiesToFile() {

399

// Implementation for saving cookies to file

400

}

401

402

private fun cookieMatchesUrl(cookie: Cookie, url: Url): Boolean {

403

// Implementation for matching cookie to URL

404

return true

405

}

406

407

private fun isCookieExpired(cookie: Cookie): Boolean {

408

// Implementation for checking cookie expiration

409

return false

410

}

411

}

412

413

/**

414

* Example: Database-backed cookie storage

415

*/

416

class DatabaseCookiesStorage(

417

private val database: Database

418

) : CookiesStorage {

419

override suspend fun get(requestUrl: Url): List<Cookie> {

420

// Query database for cookies matching URL

421

return database.queryCookies(requestUrl)

422

}

423

424

override suspend fun addCookie(requestUrl: Url, cookie: Cookie) {

425

// Store cookie in database

426

database.storeCookie(requestUrl, cookie)

427

}

428

429

override suspend fun close() {

430

database.close()

431

}

432

}

433

```

434

435

**Usage Examples:**

436

437

```kotlin

438

// Use file-based storage

439

val fileStorage = FileCookiesStorage(File("cookies.json"))

440

val clientFile = HttpClient {

441

install(HttpCookies) {

442

storage = fileStorage

443

}

444

}

445

446

// Use database storage

447

val dbStorage = DatabaseCookiesStorage(createDatabase())

448

val clientDb = HttpClient {

449

install(HttpCookies) {

450

storage = dbStorage

451

}

452

}

453

454

// Custom storage with filtering

455

class FilteredCookiesStorage(

456

private val delegate: CookiesStorage,

457

private val allowedDomains: Set<String>

458

) : CookiesStorage {

459

override suspend fun get(requestUrl: Url): List<Cookie> {

460

return delegate.get(requestUrl).filter { cookie ->

461

cookie.domain in allowedDomains

462

}

463

}

464

465

override suspend fun addCookie(requestUrl: Url, cookie: Cookie) {

466

if (cookie.domain in allowedDomains) {

467

delegate.addCookie(requestUrl, cookie)

468

}

469

}

470

471

override suspend fun close() {

472

delegate.close()

473

}

474

}

475

476

val filteredStorage = FilteredCookiesStorage(

477

AcceptAllCookiesStorage(),

478

setOf("example.com", "api.example.com")

479

)

480

481

val clientFiltered = HttpClient {

482

install(HttpCookies) {

483

storage = filteredStorage

484

}

485

}

486

```

487

488

### Cookie Debugging and Inspection

489

490

Utilities for debugging and inspecting cookie behavior.

491

492

```kotlin { .api }

493

/**

494

* Cookie debugging utilities

495

*/

496

object CookieDebugUtils {

497

/**

498

* Print all cookies for a URL

499

* @param client HttpClient instance

500

* @param url Target URL

501

*/

502

suspend fun printCookies(client: HttpClient, url: String) {

503

val cookies = client.cookies(url)

504

println("Cookies for $url:")

505

cookies.forEach { cookie ->

506

println(" ${cookie.name}=${cookie.value} (domain=${cookie.domain}, path=${cookie.path})")

507

}

508

}

509

510

/**

511

* Validate cookie attributes

512

* @param cookie Cookie to validate

513

* @returns List of validation issues

514

*/

515

fun validateCookie(cookie: Cookie): List<String> {

516

val issues = mutableListOf<String>()

517

518

if (cookie.name.isBlank()) {

519

issues.add("Cookie name cannot be blank")

520

}

521

522

if (cookie.secure && cookie.sameSite == SameSite.None) {

523

issues.add("SameSite=None requires Secure flag")

524

}

525

526

return issues

527

}

528

}

529

```

530

531

**Usage Examples:**

532

533

```kotlin

534

val client = HttpClient {

535

install(HttpCookies)

536

}

537

538

// Make some requests to accumulate cookies

539

client.get("https://example.com")

540

client.post("https://example.com/login") { /* login data */ }

541

542

// Debug cookies

543

CookieDebugUtils.printCookies(client, "https://example.com")

544

545

// Validate a cookie

546

val cookie = Cookie(

547

name = "test",

548

value = "value",

549

secure = false,

550

sameSite = SameSite.None

551

)

552

553

val issues = CookieDebugUtils.validateCookie(cookie)

554

if (issues.isNotEmpty()) {

555

println("Cookie validation issues:")

556

issues.forEach { println(" - $it") }

557

}

558

```

559

560

## Types

561

562

### Cookie Types

563

564

```kotlin { .api }

565

/**

566

* GMT date for cookie expiration

567

*/

568

data class GMTDate(

569

val timestamp: Long,

570

val seconds: Int,

571

val minutes: Int,

572

val hours: Int,

573

val dayOfMonth: Int,

574

val month: Month,

575

val year: Int,

576

val dayOfWeek: DayOfWeek,

577

val dayOfYear: Int

578

) {

579

companion object {

580

fun now(): GMTDate

581

fun parse(dateString: String): GMTDate

582

fun fromTimestamp(timestamp: Long): GMTDate

583

}

584

585

fun toEpochMilliseconds(): Long

586

fun plus(duration: Duration): GMTDate

587

fun minus(duration: Duration): GMTDate

588

}

589

590

/**

591

* URL representation for cookie matching

592

*/

593

interface Url {

594

val protocol: URLProtocol

595

val host: String

596

val port: Int

597

val pathSegments: List<String>

598

val parameters: Parameters

599

val fragment: String

600

val user: String?

601

val password: String?

602

603

fun buildString(): String

604

}

605

606

/**

607

* URL protocol enumeration

608

*/

609

data class URLProtocol(

610

val name: String,

611

val defaultPort: Int

612

) {

613

companion object {

614

val HTTP: URLProtocol

615

val HTTPS: URLProtocol

616

val WS: URLProtocol

617

val WSS: URLProtocol

618

}

619

}

620

```