CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-io-ktor--ktor-server-netty-jvm

Netty-based HTTP server engine for Ktor framework providing high-performance asynchronous server capabilities

Pending
Overview
Eval results
Files

request-response.mddocs/

Request and Response Handling

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

Capabilities

NettyApplicationCall

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

/**
 * Base class for Netty-specific application calls
 */
abstract class NettyApplicationCall(
    application: Application,
    public val context: ChannelHandlerContext,
    private val requestMessage: Any,
) : BaseApplicationCall(application) {
    
    /**
     * Netty channel handler context for low-level channel operations
     */
    val context: ChannelHandlerContext
    
    /**
     * HTTP request object (implementation-specific)
     */
    abstract override val request: NettyApplicationRequest
    
    /**
     * HTTP response object (implementation-specific)
     */
    abstract override val response: NettyApplicationResponse
    
    /**
     * Coroutine job for response write operations
     */
    val responseWriteJob: Job
}

Usage Context:

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

// In a Ktor route handler
get("/netty-info") {
    val nettyCall = call as? NettyApplicationCall
    if (nettyCall != null) {
        // Access Netty channel context
        val remoteAddress = nettyCall.context.channel().remoteAddress()
        call.respondText("Client address: $remoteAddress")
    }
}

NettyApplicationRequest

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

/**
 * Base class for Netty-specific HTTP requests
 */
abstract class NettyApplicationRequest(
    call: PipelineCall,
    override val coroutineContext: CoroutineContext,
    public val context: ChannelHandlerContext,
    private val requestBodyChannel: ByteReadChannel,
    protected val uri: String,
    internal val keepAlive: Boolean
) : BaseApplicationRequest(call), CoroutineScope {
    
    /**
     * Netty channel handler context
     */
    val context: ChannelHandlerContext
    
    /**
     * Parsed query parameters from the request URI
     */
    final override val queryParameters: Parameters
    
    /**
     * Raw (undecoded) query parameters
     */
    override val rawQueryParameters: Parameters
    
    /**
     * Request cookies collection
     */
    override val cookies: RequestCookies
    
    /**
     * Byte channel for reading request body content
     */
    override val engineReceiveChannel: ByteReadChannel
    
    /**
     * Close the request and release associated resources
     */
    fun close()
}

Usage Examples:

// Accessing request information in route handlers
post("/upload") {
    val nettyRequest = call.request as? NettyApplicationRequest
    if (nettyRequest != null) {
        // Access raw query parameters (useful for debugging)
        val rawParams = nettyRequest.rawQueryParameters
        println("Raw query params: $rawParams")
        
        // Read request body
        val bodyText = nettyRequest.engineReceiveChannel.readUTF8Line()
        call.respondText("Received: $bodyText")
    }
}

// Working with cookies
get("/session") {
    val sessionId = call.request.cookies["sessionId"]
    if (sessionId != null) {
        call.respondText("Session ID: ${sessionId.value}")
    } else {
        call.respondText("No session found")
    }
}

NettyApplicationResponse

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

/**
 * Base class for Netty-specific HTTP responses
 */
abstract class NettyApplicationResponse(
    call: NettyApplicationCall,
    protected val context: ChannelHandlerContext,
    protected val engineContext: CoroutineContext,
    protected val userContext: CoroutineContext
) : BaseApplicationResponse(call) {
    
    /**
     * Response message object (protocol-specific)
     */
    lateinit var responseMessage: Any
    
    /**
     * Cancel the response operation
     */
    fun cancel()
    
    companion object {
        /**
         * Cached HTTP status objects for performance optimization
         */
        val responseStatusCache: Array<HttpResponseStatus?>
    }
}

Usage Examples:

// Custom response handling
get("/custom-response") {
    val nettyResponse = call.response as? NettyApplicationResponse
    if (nettyResponse != null) {
        // Cancel response if needed
        if (someCondition) {
            nettyResponse.cancel()
            return@get
        }
    }
    
    call.respondText("Normal response")
}

NettyApplicationRequestHeaders

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

/**
 * Headers implementation for Netty HTTP requests
 */
class NettyApplicationRequestHeaders(request: HttpRequest) : Headers {
    // Implements Headers interface methods for accessing HTTP headers
}

Usage Examples:

get("/headers") {
    val headers = call.request.headers
    val userAgent = headers["User-Agent"]
    val acceptLanguage = headers["Accept-Language"]
    
    call.respondText("""
        User Agent: $userAgent
        Accept Language: $acceptLanguage
        All headers: ${headers.entries().joinToString()}
    """.trimIndent())
}

Request Body Processing

NettyApplicationRequest provides coroutine-aware body reading through ByteReadChannel:

// Reading different content types
post("/data") {
    when (call.request.contentType()?.contentType) {
        "application/json" -> {
            val json = call.request.engineReceiveChannel.readUTF8Line()
            // Process JSON
            call.respondText("JSON received: $json")
        }
        
        "text/plain" -> {
            val text = call.request.engineReceiveChannel.readUTF8Line()
            call.respondText("Text received: $text")
        }
        
        "multipart/form-data" -> {
            // Handle multipart data
            val multipart = call.receiveMultipart()
            // Process multipart content
        }
    }
}

Connection Management

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

get("/connection-info") {
    val nettyCall = call as? NettyApplicationCall
    if (nettyCall != null) {
        val channel = nettyCall.context.channel()
        val localAddress = channel.localAddress()
        val remoteAddress = channel.remoteAddress()
        val isActive = channel.isActive
        val isWritable = channel.isWritable
        
        call.respondText("""
            Local: $localAddress
            Remote: $remoteAddress
            Active: $isActive
            Writable: $isWritable
        """.trimIndent())
    }
}

Error Handling

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

// Error handling in request processing
install(StatusPages) {
    exception<Throwable> { call, cause ->
        val nettyCall = call as? NettyApplicationCall
        if (nettyCall != null) {
            // Log channel information for debugging
            logger.error("Error in channel: ${nettyCall.context.channel()}", cause)
        }
        
        call.respondText("Internal Server Error", status = HttpStatusCode.InternalServerError)
    }
}

Install with Tessl CLI

npx tessl i tessl/maven-io-ktor--ktor-server-netty-jvm

docs

coroutine-integration.md

engine-implementation.md

index.md

platform-optimization.md

request-response.md

server-configuration.md

standalone-server.md

tile.json