or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

authentication.mdcontent-handling.mdcontent-types.mdcookie-management.mdheaders-parameters.mdhttp-core-types.mdindex.mdmessage-properties.mdmultipart-data.mdurl-encoding.mdurl-handling.md

message-properties.mddocs/

0

# Message Properties

1

2

HTTP message property extraction and manipulation with JVM-specific Date support, providing convenient access to common HTTP headers with proper type conversion.

3

4

## Capabilities

5

6

### HttpMessage Interface

7

8

Base interface for HTTP messages (requests and responses) providing header access.

9

10

```kotlin { .api }

11

/**

12

* Base interface for HTTP messages

13

*/

14

interface HttpMessage {

15

/**

16

* HTTP headers for this message

17

*/

18

val headers: Headers

19

}

20

21

/**

22

* Base interface for HTTP message builders

23

*/

24

interface HttpMessageBuilder {

25

/**

26

* Mutable HTTP headers for this message

27

*/

28

val headers: HeadersBuilder

29

}

30

```

31

32

### Common Message Properties

33

34

Functions for extracting common HTTP message properties with proper type conversion.

35

36

```kotlin { .api }

37

/**

38

* Get Content-Type header value

39

* @return ContentType instance or null if not present

40

*/

41

fun HttpMessage.contentType(): ContentType?

42

43

/**

44

* Get Content-Type header value from builder

45

* @return ContentType instance or null if not present

46

*/

47

fun HttpMessageBuilder.contentType(): ContentType?

48

49

/**

50

* Set Content-Type header

51

* @param contentType content type to set

52

*/

53

fun HttpMessageBuilder.contentType(contentType: ContentType)

54

55

/**

56

* Get Content-Length header value

57

* @return content length as Long or null if not present

58

*/

59

fun HttpMessage.contentLength(): Long?

60

61

/**

62

* Get Content-Length header value from builder

63

* @return content length as Long or null if not present

64

*/

65

fun HttpMessageBuilder.contentLength(): Long?

66

67

/**

68

* Get charset from Content-Type header

69

* @return Charset instance or null if not specified

70

*/

71

fun HttpMessage.charset(): Charset?

72

73

/**

74

* Get charset from Content-Type header in builder

75

* @return Charset instance or null if not specified

76

*/

77

fun HttpMessageBuilder.charset(): Charset?

78

79

/**

80

* Get ETag header value

81

* @return ETag value or null if not present

82

*/

83

fun HttpMessage.etag(): String?

84

85

/**

86

* Get ETag header value from builder

87

* @return ETag value or null if not present

88

*/

89

fun HttpMessageBuilder.etag(): String?

90

91

/**

92

* Set If-None-Match header

93

* @param etag ETag value to set

94

*/

95

fun HttpMessageBuilder.ifNoneMatch(etag: String)

96

97

/**

98

* Set max age cache control

99

* @param seconds max age in seconds

100

*/

101

fun HttpMessageBuilder.maxAge(seconds: Int)

102

103

/**

104

* Set User-Agent header

105

* @param userAgent user agent string

106

*/

107

fun HttpMessageBuilder.userAgent(userAgent: String)

108

```

109

110

### Cache Control Properties

111

112

Functions for working with Cache-Control headers and caching directives.

113

114

```kotlin { .api }

115

/**

116

* Get Cache-Control directives

117

* @return List of CacheControl instances

118

*/

119

fun HttpMessage.cacheControl(): List<CacheControl>

120

121

/**

122

* Get Vary header values

123

* @return List of header names that affect caching

124

*/

125

fun HttpMessage.vary(): List<String>

126

127

/**

128

* Get Vary header values from builder

129

* @return List of header names that affect caching

130

*/

131

fun HttpMessageBuilder.vary(): List<String>

132

```

133

134

### Cookie Properties

135

136

Functions for accessing cookies in HTTP messages.

137

138

```kotlin { .api }

139

/**

140

* Get Set-Cookie header values (response)

141

* @return List of Cookie instances from Set-Cookie headers

142

*/

143

fun HttpMessage.setCookie(): List<Cookie>

144

145

/**

146

* Get cookies from Cookie header (request)

147

* @return List of Cookie instances from Cookie header

148

*/

149

fun HttpMessageBuilder.cookies(): List<Cookie>

150

```

151

152

### JVM-specific Date Properties

153

154

JVM-specific functions using java.util.Date for date-related HTTP headers.

155

156

```kotlin { .api }

157

/**

158

* Get Date header value (JVM-specific)

159

* @return Date instance or null if not present

160

*/

161

fun HttpMessage.date(): Date?

162

163

/**

164

* Get Last-Modified header value (JVM-specific)

165

* @return Date instance or null if not present

166

*/

167

fun HttpMessage.lastModified(): Date?

168

169

/**

170

* Get Last-Modified header value from builder (JVM-specific)

171

* @return Date instance or null if not present

172

*/

173

fun HttpMessageBuilder.lastModified(): Date?

174

175

/**

176

* Get Expires header value (JVM-specific)

177

* @return Date instance or null if not present

178

*/

179

fun HttpMessage.expires(): Date?

180

181

/**

182

* Get Expires header value from builder (JVM-specific)

183

* @return Date instance or null if not present

184

*/

185

fun HttpMessageBuilder.expires(): Date?

186

187

/**

188

* Set If-Modified-Since header (JVM-specific)

189

* @param date date to set

190

*/

191

fun HttpMessageBuilder.ifModifiedSince(date: Date)

192

```

193

194

### Application Response Properties

195

196

Utility functions for common response properties.

197

198

```kotlin { .api }

199

/**

200

* Set ETag header in response

201

* @param value ETag value to set

202

*/

203

fun HeadersBuilder.etag(value: String)

204

```

205

206

**Usage Examples:**

207

208

```kotlin

209

import io.ktor.http.*

210

import java.util.*

211

import java.nio.charset.Charset

212

213

// Working with HttpMessage (typically from request/response)

214

class ExampleHttpMessage(override val headers: Headers) : HttpMessage

215

216

val headers = headers {

217

append(HttpHeaders.ContentType, "application/json; charset=utf-8")

218

append(HttpHeaders.ContentLength, "1024")

219

append(HttpHeaders.ETag, "\"12345\"")

220

append(HttpHeaders.CacheControl, "max-age=3600, public")

221

append(HttpHeaders.LastModified, "Wed, 21 Oct 2015 07:28:00 GMT")

222

}

223

224

val message = ExampleHttpMessage(headers)

225

226

// Extract common properties

227

val contentType = message.contentType()

228

println("Content-Type: $contentType") // application/json

229

230

val contentLength = message.contentLength()

231

println("Content-Length: $contentLength") // 1024

232

233

val charset = message.charset()

234

println("Charset: $charset") // UTF-8

235

236

val etag = message.etag()

237

println("ETag: $etag") // "12345"

238

239

// JVM-specific date properties

240

val lastModified = message.lastModified()

241

println("Last-Modified: $lastModified") // Wed Oct 21 07:28:00 GMT 2015

242

243

val date = message.date() // null if not present

244

val expires = message.expires() // null if not present

245

246

// Cache control

247

val cacheDirectives = message.cacheControl()

248

cacheDirectives.forEach { directive ->

249

when (directive) {

250

is CacheControl.MaxAge -> println("Max-Age: ${directive.maxAgeSeconds}")

251

is CacheControl.NoCache -> println("No-Cache")

252

is CacheControl.NoStore -> println("No-Store")

253

}

254

}

255

256

// Working with HttpMessageBuilder (typically when building requests/responses)

257

class ExampleMessageBuilder(override val headers: HeadersBuilder) : HttpMessageBuilder

258

259

val builder = ExampleMessageBuilder(HeadersBuilder())

260

261

// Set properties using builder functions

262

builder.contentType(ContentType.Application.Json.withCharset(Charsets.UTF_8))

263

builder.userAgent("MyApp/1.0")

264

builder.maxAge(3600)

265

builder.ifNoneMatch("\"etag-value\"")

266

267

// JVM-specific date setting

268

val now = Date()

269

builder.ifModifiedSince(now)

270

271

// Access properties from builder

272

val builderContentType = builder.contentType()

273

val builderCharset = builder.charset()

274

275

// Cookie handling in messages

276

val cookieHeaders = headers {

277

append(HttpHeaders.SetCookie, "sessionId=abc123; HttpOnly; Secure")

278

append(HttpHeaders.SetCookie, "theme=dark; Path=/; Max-Age=86400")

279

}

280

281

val messageWithCookies = ExampleHttpMessage(cookieHeaders)

282

val cookies = messageWithCookies.setCookie()

283

cookies.forEach { cookie ->

284

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

285

if (cookie.httpOnly) println(" HttpOnly")

286

if (cookie.secure) println(" Secure")

287

}

288

289

// Vary header handling

290

val varyHeaders = headers {

291

append(HttpHeaders.Vary, "Accept-Encoding, User-Agent")

292

}

293

val varyMessage = ExampleHttpMessage(varyHeaders)

294

val varyValues = varyMessage.vary()

295

println("Varies on: ${varyValues.joinToString()}") // Accept-Encoding, User-Agent

296

297

// Utility functions for response building

298

val responseHeaders = HeadersBuilder()

299

responseHeaders.etag("\"resource-version-123\"")

300

responseHeaders.append(HttpHeaders.CacheControl, "private, max-age=300")

301

302

// Common patterns for request processing

303

fun processRequest(request: HttpMessage): String {

304

val acceptedType = request.contentType()

305

val contentLength = request.contentLength()

306

val userCharset = request.charset()

307

308

return when {

309

acceptedType?.match(ContentType.Application.Json) == true -> "Processing JSON"

310

acceptedType?.match(ContentType.Application.FormUrlEncoded) == true -> "Processing form data"

311

contentLength != null && contentLength > 1_000_000 -> "Content too large"

312

else -> "Processing generic content"

313

}

314

}

315

316

// Common patterns for response building

317

fun buildCacheableResponse(builder: HttpMessageBuilder, content: String, etag: String) {

318

builder.contentType(ContentType.Text.Html.withCharset(Charsets.UTF_8))

319

builder.ifNoneMatch(etag)

320

builder.maxAge(3600) // 1 hour

321

322

// Set response headers

323

builder.headers.apply {

324

etag(etag)

325

append(HttpHeaders.Vary, "Accept-Encoding")

326

}

327

}

328

329

// Conditional request handling

330

fun handleConditionalRequest(request: HttpMessage, resourceETag: String, lastModified: Date): Boolean {

331

val requestETag = request.etag()

332

val ifModifiedSince = request.lastModified()

333

334

// Check if resource has been modified

335

val etagMatches = requestETag == resourceETag

336

val notModifiedSince = ifModifiedSince?.let { it >= lastModified } ?: false

337

338

return etagMatches || notModifiedSince

339

}

340

341

// Content negotiation

342

fun negotiateContentType(request: HttpMessage): ContentType {

343

val acceptHeader = request.headers[HttpHeaders.Accept]

344

return when {

345

acceptHeader?.contains("application/json") == true -> ContentType.Application.Json

346

acceptHeader?.contains("text/html") == true -> ContentType.Text.Html

347

acceptHeader?.contains("application/xml") == true -> ContentType.Application.Xml

348

else -> ContentType.Text.Plain

349

}

350

}

351

```

352

353

## Types

354

355

All types are defined above in their respective capability sections.