or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

coroutine-integration.mdengine-implementation.mdindex.mdplatform-optimization.mdrequest-response.mdserver-configuration.mdstandalone-server.md

request-response.mddocs/

0

# Request and Response Handling

1

2

Abstract base classes for HTTP request and response processing with Netty channel integration and coroutine support.

3

4

## Capabilities

5

6

### NettyApplicationCall

7

8

Abstract base class for Netty-specific application calls that manages the complete request-response lifecycle.

9

10

```kotlin { .api }

11

/**

12

* Base class for Netty-specific application calls

13

*/

14

abstract class NettyApplicationCall(

15

application: Application,

16

public val context: ChannelHandlerContext,

17

private val requestMessage: Any,

18

) : BaseApplicationCall(application) {

19

20

/**

21

* Netty channel handler context for low-level channel operations

22

*/

23

val context: ChannelHandlerContext

24

25

/**

26

* HTTP request object (implementation-specific)

27

*/

28

abstract override val request: NettyApplicationRequest

29

30

/**

31

* HTTP response object (implementation-specific)

32

*/

33

abstract override val response: NettyApplicationResponse

34

35

/**

36

* Coroutine job for response write operations

37

*/

38

val responseWriteJob: Job

39

}

40

```

41

42

**Usage Context:**

43

44

The NettyApplicationCall is typically used within Ktor's request processing pipeline and provides access to Netty-specific functionality:

45

46

```kotlin

47

// In a Ktor route handler

48

get("/netty-info") {

49

val nettyCall = call as? NettyApplicationCall

50

if (nettyCall != null) {

51

// Access Netty channel context

52

val remoteAddress = nettyCall.context.channel().remoteAddress()

53

call.respondText("Client address: $remoteAddress")

54

}

55

}

56

```

57

58

### NettyApplicationRequest

59

60

Abstract base class for HTTP requests with Netty channel integration and coroutine-aware body processing.

61

62

```kotlin { .api }

63

/**

64

* Base class for Netty-specific HTTP requests

65

*/

66

abstract class NettyApplicationRequest(

67

call: PipelineCall,

68

override val coroutineContext: CoroutineContext,

69

public val context: ChannelHandlerContext,

70

private val requestBodyChannel: ByteReadChannel,

71

protected val uri: String,

72

internal val keepAlive: Boolean

73

) : BaseApplicationRequest(call), CoroutineScope {

74

75

/**

76

* Netty channel handler context

77

*/

78

val context: ChannelHandlerContext

79

80

/**

81

* Parsed query parameters from the request URI

82

*/

83

final override val queryParameters: Parameters

84

85

/**

86

* Raw (undecoded) query parameters

87

*/

88

override val rawQueryParameters: Parameters

89

90

/**

91

* Request cookies collection

92

*/

93

override val cookies: RequestCookies

94

95

/**

96

* Byte channel for reading request body content

97

*/

98

override val engineReceiveChannel: ByteReadChannel

99

100

/**

101

* Close the request and release associated resources

102

*/

103

fun close()

104

}

105

```

106

107

**Usage Examples:**

108

109

```kotlin

110

// Accessing request information in route handlers

111

post("/upload") {

112

val nettyRequest = call.request as? NettyApplicationRequest

113

if (nettyRequest != null) {

114

// Access raw query parameters (useful for debugging)

115

val rawParams = nettyRequest.rawQueryParameters

116

println("Raw query params: $rawParams")

117

118

// Read request body

119

val bodyText = nettyRequest.engineReceiveChannel.readUTF8Line()

120

call.respondText("Received: $bodyText")

121

}

122

}

123

124

// Working with cookies

125

get("/session") {

126

val sessionId = call.request.cookies["sessionId"]

127

if (sessionId != null) {

128

call.respondText("Session ID: ${sessionId.value}")

129

} else {

130

call.respondText("No session found")

131

}

132

}

133

```

134

135

### NettyApplicationResponse

136

137

Abstract base class for HTTP responses with Netty channel integration and asynchronous response writing.

138

139

```kotlin { .api }

140

/**

141

* Base class for Netty-specific HTTP responses

142

*/

143

abstract class NettyApplicationResponse(

144

call: NettyApplicationCall,

145

protected val context: ChannelHandlerContext,

146

protected val engineContext: CoroutineContext,

147

protected val userContext: CoroutineContext

148

) : BaseApplicationResponse(call) {

149

150

/**

151

* Response message object (protocol-specific)

152

*/

153

lateinit var responseMessage: Any

154

155

/**

156

* Cancel the response operation

157

*/

158

fun cancel()

159

160

companion object {

161

/**

162

* Cached HTTP status objects for performance optimization

163

*/

164

val responseStatusCache: Array<HttpResponseStatus?>

165

}

166

}

167

```

168

169

**Usage Examples:**

170

171

```kotlin

172

// Custom response handling

173

get("/custom-response") {

174

val nettyResponse = call.response as? NettyApplicationResponse

175

if (nettyResponse != null) {

176

// Cancel response if needed

177

if (someCondition) {

178

nettyResponse.cancel()

179

return@get

180

}

181

}

182

183

call.respondText("Normal response")

184

}

185

```

186

187

### NettyApplicationRequestHeaders

188

189

Implementation of HTTP request headers backed by Netty's HttpRequest.

190

191

```kotlin { .api }

192

/**

193

* Headers implementation for Netty HTTP requests

194

*/

195

class NettyApplicationRequestHeaders(request: HttpRequest) : Headers {

196

// Implements Headers interface methods for accessing HTTP headers

197

}

198

```

199

200

**Usage Examples:**

201

202

```kotlin

203

get("/headers") {

204

val headers = call.request.headers

205

val userAgent = headers["User-Agent"]

206

val acceptLanguage = headers["Accept-Language"]

207

208

call.respondText("""

209

User Agent: $userAgent

210

Accept Language: $acceptLanguage

211

All headers: ${headers.entries().joinToString()}

212

""".trimIndent())

213

}

214

```

215

216

### Request Body Processing

217

218

NettyApplicationRequest provides coroutine-aware body reading through ByteReadChannel:

219

220

```kotlin

221

// Reading different content types

222

post("/data") {

223

when (call.request.contentType()?.contentType) {

224

"application/json" -> {

225

val json = call.request.engineReceiveChannel.readUTF8Line()

226

// Process JSON

227

call.respondText("JSON received: $json")

228

}

229

230

"text/plain" -> {

231

val text = call.request.engineReceiveChannel.readUTF8Line()

232

call.respondText("Text received: $text")

233

}

234

235

"multipart/form-data" -> {

236

// Handle multipart data

237

val multipart = call.receiveMultipart()

238

// Process multipart content

239

}

240

}

241

}

242

```

243

244

### Connection Management

245

246

Access to connection-level information through the Netty channel context:

247

248

```kotlin

249

get("/connection-info") {

250

val nettyCall = call as? NettyApplicationCall

251

if (nettyCall != null) {

252

val channel = nettyCall.context.channel()

253

val localAddress = channel.localAddress()

254

val remoteAddress = channel.remoteAddress()

255

val isActive = channel.isActive

256

val isWritable = channel.isWritable

257

258

call.respondText("""

259

Local: $localAddress

260

Remote: $remoteAddress

261

Active: $isActive

262

Writable: $isWritable

263

""".trimIndent())

264

}

265

}

266

```

267

268

### Error Handling

269

270

The request and response classes integrate with Ktor's error handling mechanisms:

271

272

```kotlin

273

// Error handling in request processing

274

install(StatusPages) {

275

exception<Throwable> { call, cause ->

276

val nettyCall = call as? NettyApplicationCall

277

if (nettyCall != null) {

278

// Log channel information for debugging

279

logger.error("Error in channel: ${nettyCall.context.channel()}", cause)

280

}

281

282

call.respondText("Internal Server Error", status = HttpStatusCode.InternalServerError)

283

}

284

}

285

```