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
```