or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

application.mdconfig.mdengine.mdindex.mdplugins.mdrequest.mdresponse.mdrouting.md

response.mddocs/

0

# Response Processing

1

2

Response handling functionality for setting status codes, headers, cookies, and sending various types of content back to clients with full type safety and content negotiation support.

3

4

## Capabilities

5

6

### Application Response

7

8

Abstract base class for HTTP responses providing access to status, headers, cookies, and content sending pipeline.

9

10

```kotlin { .api }

11

/**

12

* Interface for HTTP responses

13

*/

14

interface ApplicationResponse {

15

/** The application call this response belongs to */

16

val call: ApplicationCall

17

/** Pipeline for processing outgoing content */

18

val pipeline: ApplicationSendPipeline

19

/** HTTP status code */

20

val status: HttpStatusCode?

21

/** Response headers */

22

val headers: ResponseHeaders

23

/** Response cookies */

24

val cookies: ResponseCookies

25

/** Whether response has been committed */

26

val isCommitted: Boolean

27

/** Whether response has been sent */

28

val isSent: Boolean

29

30

/** Set response status code */

31

fun status(value: HttpStatusCode)

32

/** Push response (HTTP/2) */

33

fun push(builder: ResponsePushBuilder)

34

}

35

```

36

37

### Content Sending

38

39

Functions for sending various types of content as HTTP responses with automatic content negotiation and serialization.

40

41

```kotlin { .api }

42

/**

43

* Sends response content with automatic serialization

44

* @param message - Content to send (any serializable object)

45

* @throws ContentTransformationException if serialization fails

46

*/

47

suspend fun ApplicationCall.respond(message: Any)

48

49

/**

50

* Sends response with specific status code

51

* @param status - HTTP status code

52

* @param message - Content to send (optional, defaults to empty)

53

*/

54

suspend fun ApplicationCall.respond(status: HttpStatusCode, message: Any = "")

55

56

/**

57

* Sends plain text response

58

* @param text - Text content to send

59

* @param contentType - Optional content type (defaults to text/plain)

60

* @param status - Optional HTTP status code

61

*/

62

suspend fun ApplicationCall.respondText(

63

text: String,

64

contentType: ContentType? = null,

65

status: HttpStatusCode? = null

66

)

67

68

/**

69

* Sends byte array response

70

* @param bytes - Binary content to send

71

* @param contentType - Optional content type

72

* @param status - Optional HTTP status code

73

*/

74

suspend fun ApplicationCall.respondBytes(

75

bytes: ByteArray,

76

contentType: ContentType? = null,

77

status: HttpStatusCode? = null

78

)

79

80

/**

81

* Sends HTTP redirect response

82

* @param url - Target URL for redirect

83

* @param permanent - Whether redirect is permanent (301) or temporary (302)

84

*/

85

suspend fun ApplicationCall.respondRedirect(url: String, permanent: Boolean = false)

86

87

/**

88

* Sends content from kotlinx-io Source

89

* @param source - Raw source to send

90

* @param contentType - Optional content type

91

* @param status - Optional HTTP status code

92

* @param contentLength - Optional content length

93

*/

94

suspend fun ApplicationCall.respondSource(

95

source: RawSource,

96

contentType: ContentType? = null,

97

status: HttpStatusCode? = null,

98

contentLength: Long? = null

99

)

100

101

/**

102

* Sends response with binary content producer

103

* @param contentType - Optional content type

104

* @param status - Optional HTTP status code

105

* @param contentLength - Optional content length

106

* @param producer - Function that writes content to ByteWriteChannel

107

*/

108

suspend fun ApplicationCall.respondBytesWriter(

109

contentType: ContentType? = null,

110

status: HttpStatusCode? = null,

111

contentLength: Long? = null,

112

producer: suspend ByteWriteChannel.() -> Unit

113

)

114

115

/**

116

* Sends output stream content

117

* @param contentType - Content type for response

118

* @param status - HTTP status code

119

* @param producer - Function that writes content to output stream

120

*/

121

suspend fun ApplicationCall.respondOutputStream(

122

contentType: ContentType? = null,

123

status: HttpStatusCode? = null,

124

producer: suspend OutputStream.() -> Unit

125

)

126

127

/**

128

* Sends response with nullable content (type-safe)

129

* @param message - Content to send (can be null)

130

*/

131

suspend inline fun <reified T> ApplicationCall.respondNullable(message: T)

132

133

/**

134

* Sends response with nullable content and status

135

* @param status - HTTP status code

136

* @param message - Content to send (can be null)

137

*/

138

suspend inline fun <reified T> ApplicationCall.respondNullable(status: HttpStatusCode, message: T)

139

140

/**

141

* Sends response with specific type information

142

* @param message - Content to send

143

* @param messageType - Type information for serialization

144

*/

145

suspend fun ApplicationCall.respond(message: Any?, messageType: TypeInfo)

146

147

/**

148

* Sends response with status and type information

149

* @param status - HTTP status code

150

* @param message - Content to send

151

* @param messageType - Type information for serialization

152

*/

153

suspend fun ApplicationCall.respond(

154

status: HttpStatusCode,

155

message: Any?,

156

messageType: TypeInfo

157

)

158

```

159

160

### Response Headers

161

162

Interface for manipulating HTTP response headers with type-safe access patterns.

163

164

```kotlin { .api }

165

/**

166

* Interface for response header manipulation

167

*/

168

abstract class ResponseHeaders {

169

/** Append header value */

170

abstract fun append(name: String, value: String)

171

/** Append header with date value */

172

abstract fun append(name: String, value: Date)

173

/** Append header with int value */

174

abstract fun append(name: String, value: Int)

175

/** Get header values */

176

abstract operator fun get(name: String): String?

177

/** Check if header exists */

178

abstract fun contains(name: String): Boolean

179

/** Get all header names */

180

abstract fun names(): Set<String>

181

/** Get all values for header */

182

abstract fun values(name: String): List<String>

183

/** Remove all values for header */

184

abstract fun remove(name: String)

185

/** Clear all headers */

186

abstract fun clear()

187

}

188

189

/** Set Content-Type header */

190

fun ResponseHeaders.contentType(contentType: ContentType) =

191

append(HttpHeaders.ContentType, contentType.toString())

192

193

/** Set Content-Length header */

194

fun ResponseHeaders.contentLength(length: Long) =

195

append(HttpHeaders.ContentLength, length.toString())

196

197

/** Set Cache-Control header */

198

fun ResponseHeaders.cacheControl(cacheControl: CacheControl) =

199

append(HttpHeaders.CacheControl, cacheControl.toString())

200

```

201

202

### Response Cookies

203

204

Interface for managing HTTP response cookies with support for various cookie attributes.

205

206

```kotlin { .api }

207

/**

208

* Interface for response cookie management

209

*/

210

interface ResponseCookies {

211

/** Append cookie to response */

212

fun append(cookie: Cookie)

213

/** Append cookie with name and value */

214

fun append(name: String, value: String, encoding: CookieEncoding = CookieEncoding.URI_ENCODING)

215

}

216

217

/**

218

* HTTP cookie representation

219

*/

220

data class Cookie(

221

val name: String,

222

val value: String,

223

val encoding: CookieEncoding = CookieEncoding.URI_ENCODING,

224

val maxAge: Int = 0,

225

val expires: Date? = null,

226

val domain: String? = null,

227

val path: String? = null,

228

val secure: Boolean = false,

229

val httpOnly: Boolean = false,

230

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

231

)

232

233

enum class CookieEncoding {

234

URI_ENCODING,

235

DQUOTES,

236

RAW

237

}

238

```

239

240

### Response Pipeline

241

242

Pipeline system for processing and transforming outgoing response content through interceptor chains.

243

244

```kotlin { .api }

245

/**

246

* Pipeline for processing outgoing response content

247

*/

248

class ApplicationSendPipeline : Pipeline<Any, ApplicationCall> {

249

companion object {

250

/** Before phase for pre-processing */

251

val Before: PipelinePhase = PipelinePhase("Before")

252

/** Transform phase for content transformation */

253

val Transform: PipelinePhase = PipelinePhase("Transform")

254

/** After phase for post-processing */

255

val After: PipelinePhase = PipelinePhase("After")

256

/** Engine phase for final processing */

257

val Engine: PipelinePhase = PipelinePhase("Engine")

258

}

259

}

260

261

/**

262

* Content converter for response serialization

263

*/

264

interface ContentConverter {

265

/** Convert content for sending */

266

suspend fun convertForSend(

267

context: PipelineContext<Any, ApplicationCall>,

268

contentType: ContentType,

269

value: Any

270

): Any?

271

}

272

```

273

274

### HTTP Status Codes

275

276

Enumeration of HTTP status codes with standard descriptions and utility functions.

277

278

```kotlin { .api }

279

/**

280

* HTTP status code enumeration

281

*/

282

enum class HttpStatusCode(val value: Int, val description: String) {

283

// 2xx Success

284

OK(200, "OK"),

285

Created(201, "Created"),

286

Accepted(202, "Accepted"),

287

NoContent(204, "No Content"),

288

289

// 3xx Redirection

290

MovedPermanently(301, "Moved Permanently"),

291

Found(302, "Found"),

292

SeeOther(303, "See Other"),

293

NotModified(304, "Not Modified"),

294

295

// 4xx Client Error

296

BadRequest(400, "Bad Request"),

297

Unauthorized(401, "Unauthorized"),

298

Forbidden(403, "Forbidden"),

299

NotFound(404, "Not Found"),

300

MethodNotAllowed(405, "Method Not Allowed"),

301

Conflict(409, "Conflict"),

302

UnprocessableEntity(422, "Unprocessable Entity"),

303

304

// 5xx Server Error

305

InternalServerError(500, "Internal Server Error"),

306

NotImplemented(501, "Not Implemented"),

307

BadGateway(502, "Bad Gateway"),

308

ServiceUnavailable(503, "Service Unavailable");

309

310

/** Check if status code indicates success (2xx) */

311

val isSuccess: Boolean get() = value in 200..299

312

/** Check if status code indicates informational (1xx) */

313

val isInformational: Boolean get() = value in 100..199

314

/** Check if status code indicates redirection (3xx) */

315

val isRedirection: Boolean get() = value in 300..399

316

/** Check if status code indicates client error (4xx) */

317

val isClientError: Boolean get() = value in 400..499

318

/** Check if status code indicates server error (5xx) */

319

val isServerError: Boolean get() = value in 500..599

320

}

321

```

322

323

### Content Types

324

325

Content type definitions and utilities for response content negotiation.

326

327

```kotlin { .api }

328

/**

329

* Content type representation

330

*/

331

data class ContentType(

332

val contentType: String,

333

val contentSubtype: String,

334

val parameters: List<HeaderValueParam> = emptyList()

335

) {

336

companion object {

337

// Text types

338

val Text = ContentType("text", "*")

339

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

340

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

341

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

342

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

343

344

// Application types

345

val Application = ContentType("application", "*")

346

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

347

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

348

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

349

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

350

351

// Multipart types

352

val MultiPart = ContentType("multipart", "*")

353

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

354

}

355

356

/** Create content type with charset parameter */

357

fun withCharset(charset: Charset): ContentType

358

/** Create content type with parameter */

359

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

360

}

361

```

362

363

**Usage Examples:**

364

365

```kotlin

366

import io.ktor.server.application.*

367

import io.ktor.server.response.*

368

import io.ktor.server.routing.*

369

import io.ktor.http.*

370

371

// Basic responses

372

routing {

373

get("/") {

374

call.respondText("Hello, World!")

375

}

376

377

get("/json") {

378

call.respond(mapOf("message" to "Hello", "timestamp" to System.currentTimeMillis()))

379

}

380

381

get("/status") {

382

call.respond(HttpStatusCode.OK, "Service is running")

383

}

384

}

385

386

// Custom content types and headers

387

routing {

388

get("/custom") {

389

call.response.headers.append(HttpHeaders.CacheControl, "no-cache")

390

call.response.headers.contentLength(12)

391

call.respondText("Custom response", ContentType.Text.Html)

392

}

393

394

get("/file") {

395

val file = File("document.pdf")

396

call.response.headers.append(

397

HttpHeaders.ContentDisposition,

398

"attachment; filename=document.pdf"

399

)

400

call.respondFile(file)

401

}

402

}

403

404

// Cookie management

405

routing {

406

post("/login") {

407

// Set authentication cookie

408

call.response.cookies.append(

409

Cookie(

410

name = "auth_token",

411

value = "abc123",

412

maxAge = 3600,

413

httpOnly = true,

414

secure = true,

415

path = "/"

416

)

417

)

418

call.respond(HttpStatusCode.OK, "Logged in")

419

}

420

421

post("/logout") {

422

// Clear authentication cookie

423

call.response.cookies.append(

424

Cookie(

425

name = "auth_token",

426

value = "",

427

maxAge = 0

428

)

429

)

430

call.respond(HttpStatusCode.OK, "Logged out")

431

}

432

}

433

434

// Redirects

435

routing {

436

get("/old-path") {

437

call.respondRedirect("/new-path", permanent = true)

438

}

439

440

post("/submit") {

441

// Process form submission

442

call.respondRedirect("/success")

443

}

444

}

445

446

// Streaming responses

447

routing {

448

get("/stream") {

449

call.respondOutputStream(ContentType.Text.Plain) {

450

for (i in 1..100) {

451

write("Line $i\n".toByteArray())

452

flush()

453

Thread.sleep(100)

454

}

455

}

456

}

457

}

458

```