http_server

Generated by tinox doc

tinox.core.http_server, split out of the bundled stdlib as a standalone tinox-central package.

ModuleVersionGroup
json (no local docs)1.1.5tinox.core

Hello server

import tinox.core.http_server

class Main
{
    fnc main() -> Int32
    {
        const server: HttpServer = HttpServer::new(8080)
        server.get("/hello", ctx => {
            ctx.response.text("Hello, World!")
        })
        server.get("/users/:id", ctx => {
            const id: String = ctx.request.getParam("id")
            ctx.response.json("{\"id\": \"" + id + "\"}")
        })
        server.listen()
        return 0
    }
}

class HttpContext

* Request context passed to route handlers and middleware * * Contains both the incoming request and the outgoing response, * enabling handlers to read request data and modify the response.

Fields

requestHttpRequest The incoming HTTP request
responseHttpResponse The outgoing HTTP response

Methods

fn new(request: HttpRequest, response: HttpResponse) → HttpContext
* Creates a new HttpContext * * @param request the incoming request * @param response the outgoing response (defaults to new 200 response) * @return a new HttpContext instance
fn fromRequest(request: HttpRequest) → HttpContext
* Creates a context with a new default response * * @param request the incoming request * @return a new HttpContext with a fresh 200 response

class HttpRequest

* Represents an incoming HTTP request * * Provides access to the method, path, headers, query parameters, * body, and path parameters.

Fields

methodString The HTTP method (GET, POST, PUT, PATCH, DELETE)
pathString The request path (e.g., "/users/42")
bodyString The raw request body
headersMap<String, String> Request headers as key-value pairs
queryStringString The raw query string (e.g., "page=1&limit=10")
paramsMap<String, String> Path parameters extracted from route patterns
wasEarlyDataBool * True if this request arrived as TLS 1.3 0-RTT early data * (tinox.core.http3_server's Http3Server, when enableEarlyData() * is opted into) -- always false for HttpServer/Http2Server, * since neither supports 0-RTT. Early data is replayable by a * network attacker (no round trip to prove the client isn't * replaying a captured ClientHello+request), so handlers that * check this should avoid non-idempotent side effects when true.

Methods

fn new(method: String, path: String, queryString: String, headers: Map<String, String>, body: String) → HttpRequest
* Creates a new HttpRequest * * @param method the HTTP method * @param path the request path * @param queryString the query string * @param headers the request headers * @param body the request body * @return a new HttpRequest instance
fn getHeader(name: String) → String
* Returns the value of a request header * * @param name the header name (case-insensitive lookup) * @return the header value, or empty string if not found * Use findHeader() to distinguish absent from present-empty.
fn findHeader(name: String) → Option<String>
* Finds a header using case-insensitive lookup. Some("") means * present but empty; None means absent. Exact spelling wins when * the map contains multiple spellings, as with getHeader().
fn getParam(name: String) → String
* Returns the value of a path parameter * * @param name the parameter name * @return the parameter value, or empty string if not found * Use the corresponding find method to preserve absence.
fn findParam(name: String) → Option<String>
Finds a case-sensitive path parameter, preserving empty values.
fn getQuery(name: String) → String
* Returns the value of a query parameter * * @param name the query parameter name * @return the parameter value, or empty string if not found * Use the corresponding find method to preserve absence.
fn findQuery(name: String) → Option<String>
* Finds a query parameter, preserving present-empty values. * Uses QueryString::parse semantics (raw keys/values, last duplicate * wins, a bare key is empty, empty keys are ignored).
fn json() → JsonValue
* Parses the request body as JSON * * @return a JsonValue representing the parsed body
fn bodyAs() → T
* Deserializes the request body into an object of type T. * T must be annotated with @JsonSerializable. * * Usage: * const user: CreateUserRequest = ctx.request.bodyAs<CreateUserRequest>(); * * @return the deserialized object
fn text() → String
* Returns the raw request body as a string * * @return the request body
fn setParams(params: Map<String, String>) → Nothing
* Sets path parameters (internal use by route matching) * * @param params the extracted path parameters
fn isContentType(contentType: String) → Bool
* Checks the Content-Type header * * @param contentType the content type to check for * @return true if the request Content-Type matches

class HttpResponse

* Represents an outgoing HTTP response * * Provides a fluent API for building responses with * status codes, headers, and body content.

Fields

statusCodeInt64 The HTTP status code
headersMap<String, String> Response headers
bodyString The response body

Methods

fn new() → HttpResponse
* Creates a new HttpResponse with default status 200 * * @return a new HttpResponse instance
fn status(code: Int64) → HttpResponse
* Sets the HTTP status code * * @param code the status code (e.g., 200, 404) * @return this response for chaining
fn header(name: String, value: String) → HttpResponse
* Sets a response header, REPLACING every earlier value of that name * (including values added with addHeader). * * @param name the header name * @param value the header value * @return this response for chaining
@Throwsfn addHeader(name: String, value: String) → HttpResponse
* APPENDS a value to a header that may legally repeat (e.g. Set-Cookie). * The first value lives under the plain name, later ones under * "<name> <n>" (a space cannot occur in a header name); every transport * writes them as separate header lines of the same name. Reading * `headers[name]` still yields the first value. Throws on a name that is * not an HTTP token, on CR/LF/NUL in name or value, and after 64 values. * * @param name the header name * @param value the header value * @return this response for chaining
@Throwsfn checkHeader(name: String, value: String) → Nothing
@Throwsfn setCookie(cookie: Cookie) → HttpResponse
* Appends a Set-Cookie header built from a Cookie (see Cookie.toHeaderValue * for the validation it applies). Several cookies produce several * Set-Cookie lines.
@Throwsfn removeCookie(name: String, path: String, domain: String) → HttpResponse
* Expires a cookie in the client: empty value, Max-Age=0 and a past Expires. * path/domain must match the attributes the cookie was set with.
fn text(text: String) → HttpResponse
* Sets the response body as plain text with Content-Type: text/plain * * @param text the response text * @return this response for chaining
fn json(json: String) → HttpResponse
* Sets the response body as JSON with Content-Type: application/json * * @param json the JSON string * @return this response for chaining
fn jsonObject(obj: T) → HttpResponse
* Serializes a @JsonSerializable object and sets it as the JSON response body. * * Usage: * ctx.response.json(user); * ctx.response.json(userList); * * @param obj any object annotated with @JsonSerializable * @return this response for chaining
fn html(html: String) → HttpResponse
* Sets the response body as HTML with Content-Type: text/html * * @param html the HTML string * @return this response for chaining
fn content(content: String, contentType: String) → HttpResponse
* Sets the response body with a custom Content-Type * * @param content the response body * @param contentType the MIME type * @return this response for chaining
fn notFound(message: String) → HttpResponse
* Sets the response to a 404 Not Found with a message * * @param message the error message * @return this response for chaining
fn badRequest(message: String) → HttpResponse
* Sets the response to a 400 Bad Request with a message * * @param message the error message * @return this response for chaining
fn internalError(message: String) → HttpResponse
* Sets the response to a 500 Internal Server Error with a message * * @param message the error message * @return this response for chaining
fn created(json: String) → HttpResponse
* Sets the response to a 201 Created with a JSON body * * @param json the JSON response body * @return this response for chaining
fn noContent() → HttpResponse
* Sets the response to a 204 No Content (empty body) * * @return this response for chaining
fn redirect(url: String) → HttpResponse
* Sets the response to a redirect (302 Found) * * @param url the URL to redirect to * @return this response for chaining
fn cors(origin: String) → HttpResponse
* Sets CORS headers to allow cross-origin requests * * @param origin the allowed origin (defaults to "*") * @return this response for chaining

fn tinoxSecurityGuard(ctx: HttpContext, routeExists: Int64) → Int64

class HttpServer

* HTTP server for handling incoming HTTP requests * * Supports route registration for GET, POST, PUT, PATCH, DELETE, * middleware chains, and automatic request parsing. * * Example usage: * const server: HttpServer = HttpServer::new(8080); * server.get("/hello", ctx => { * ctx.response.text("Hello, World!"); * }); * server.post("/users", ctx => { * const data: JsonValue = ctx.request.json(); * ctx.response.status(201).json("{\"id\": 1}"); * }); * server.listen();

Fields

portInt64 The port to listen on
routesList<Route> Registered routes
middlewareList<fnc(HttpContext) -> Bool> Registered middleware functions
socketHandleInt64 The underlying socket handle
runningBool Whether the server is running

Methods

fn new(port: Int64) → HttpServer
* Creates a new HttpServer listening on the given port * * @param port the port number to bind to * @return a new HttpServer instance
fn get(path: String, handler: fnc(HttpContext) -> Nothing) → HttpServer
* Registers a GET route handler * * @param path the URL path pattern (e.g., "/users/:id") * @param handler the function to handle matching requests * @return this server for chaining
fn post(path: String, handler: fnc(HttpContext) -> Nothing) → HttpServer
* Registers a POST route handler * * @param path the URL path pattern * @param handler the function to handle matching requests * @return this server for chaining
fn put(path: String, handler: fnc(HttpContext) -> Nothing) → HttpServer
* Registers a PUT route handler * * @param path the URL path pattern * @param handler the function to handle matching requests * @return this server for chaining
fn patch(path: String, handler: fnc(HttpContext) -> Nothing) → HttpServer
* Registers a PATCH route handler * * @param path the URL path pattern * @param handler the function to handle matching requests * @return this server for chaining
fn delete(path: String, handler: fnc(HttpContext) -> Nothing) → HttpServer
* Registers a DELETE route handler * * @param path the URL path pattern * @param handler the function to handle matching requests * @return this server for chaining
fn options(path: String, handler: fnc(HttpContext) -> Nothing) → HttpServer
* Registers an OPTIONS route handler. * * Needed to answer a browser's CORS preflight for any cross-origin * request the Fetch/XHR spec disqualifies from "simple" status -- * notably a request with an XMLHttpRequestUpload listener attached * (e.g. upload.onprogress), which forces a preflight regardless of * headers/body size/method. Without a matching OPTIONS route, that * preflight 404s and the browser blocks the real request even * though the real handler's own response would have carried valid * CORS headers (HttpResponse::cors()) -- register one that does * the same .cors(...) call and nothing else. * * @param path the URL path pattern * @param handler the function to handle matching requests * @return this server for chaining
fn use(mware: fnc(HttpContext) -> Bool) → HttpServer
* Registers a middleware function * * Middleware is executed in the order it is registered. * If a middleware returns false, the request chain is interrupted. * * @param mware the middleware function * @return this server for chaining
@Throwsfn listen() → Nothing
* Starts the server and begins listening for connections * * This is a blocking call that enters the server event loop. * Use stop() to shut down the server.
@Throwsfn listenTls(certPath: String, keyPath: String) → Nothing
* Starts the server with TLS/HTTPS enabled. * * OpenSSL is linked by default (opt-out via TINOX_TLS=0 at build * time). Without it, httpServerCreateTls returns -1 and this call * throws. * * Certificate and key must both be PEM files. certPath may contain the * full certificate chain (leaf first). * * Example: * server.listenTls("cert.pem", "key.pem"); * * @param certPath path to the PEM certificate (chain) file * @param keyPath path to the PEM private key file
fn parseRawRequest(raw: String) → HttpContext
* Parses a raw HTTP/1.1 request string into an HttpContext
fn formatResponse(response: HttpResponse) → String
* Formats an HttpResponse into a raw HTTP/1.1 response string
fn statusText(code: Int64) → String
* Returns the HTTP status text for a given status code
fn stop() → Nothing
* Stops the running server
fn routeExistsFor(ctx: HttpContext) → Int64
* Processes an incoming request through middleware and route matching, * then sends the response and closes the connection. * * @param ctx the request context * @param conn the client connection handle (plaintext or TLS)
fn handleRequest(ctx: HttpContext, conn: Int64) → Nothing
fn runMiddleware(ctx: HttpContext) → Bool
* Runs all registered middleware functions * * @param ctx the request context * @return true if all middleware passed, false if any rejected
fn matchRoute(ctx: HttpContext) → Bool
* Matches an incoming request against registered routes * * Supports path parameters via :param syntax. * For example, "/users/:id" matches "/users/42" with params { id: "42" } * * @param ctx the request context (modified in place with params) * @return true if a matching route was found and executed

@Errorclass HttpServerError

* Invalid HTTP server input or the server could not start.

Fields

messageString

class QueryString

* Utility for parsing and working with query strings

Methods

fn parse(qs: String) → Map<String, String>
* Parses a query string into a map of key-value pairs * * @param qs the raw query string (e.g., "page=1&limit=10") * @return a map of parameter names to values
fn get(qs: String, name: String) → String
* Gets a single value from a query string by parameter name * * @param qs the raw query string * @param name the parameter name * @return the parameter value, or empty string if not found
fn find(qs: String, name: String) → Option<String>
* Finds a raw, case-sensitive query parameter. Some("") represents * a bare key or key=; None represents absence. Like parse(), the * last duplicate wins, empty keys are ignored, and no URL decoding * is performed.

class Response<T>

* A typed JSON response for annotation-driven REST handlers. * T has the same supported types as an auto-serialized route return. * The compiler serializes the body; applications never build JSON here. * The field order is part of the shared HTTP/HTTP3 route-shim ABI.

Fields

statusCodeInt64
headersMap<String, String>
valuesList<T>
errorMessageString
kindInt64

Methods

fnc ok(value: T) → Response<T>
Uses @StatusCode, or 200, as the success status.
fnc error(code: Int64, message: String) → Response<T>
Returns the centrally escaped JSON object {"error": message}.
fnc noContent() → Response<T>
fn withStatus(code: Int64) → Response<T>
Overrides the default success status (200-299, except 204/205).
@Throwsfn header(name: String, value: String) → Response<T>
JSON content type and transport framing are owned by the server.

class Route

* A route definition mapping an HTTP method and path pattern to a handler

Fields

methodString The HTTP method (GET, POST, etc.)
pathString The path pattern (e.g., "/users/:id")
handlerfnc(HttpContext) -> Nothing The handler function to execute

class RouteMatcher

* Utility for matching URL paths against route patterns * with support for path parameters (:param syntax)

Methods

fn matches(pattern: String, path: String) → Bool
* Checks if a request path matches a route pattern * * Pattern syntax: * "/users" - exact match * "/users/:id" - match with path parameter * "/static/*" - wildcard match for remaining path * * @param pattern the route pattern * @param path the actual request path * @return true if the path matches the pattern
fn extractParams(pattern: String, path: String) → Map<String, String>
* Extracts path parameters from a request path based on a route pattern * * @param pattern the route pattern with :param placeholders * @param path the actual request path * @return a map of parameter names to their values
fn param(pattern: String, path: String, name: String) → String
* Convenience wrapper around extractParams() for callers that only * need a single named parameter's value (e.g. tinox.core.ui's * @Route dispatch, which injects one class field per :param at a * time) rather than the whole Map -- avoids every such caller * re-deriving the same Map just to immediately throw the rest away. * * @param pattern the route pattern with :param placeholders * @param path the actual request path * @param name the parameter name to look up (without the leading ':') * @return the matched segment's value, or "" if pattern/path don't * actually share a :name segment by that name
fn splitPath(path: String) → List<String>
* Splits a path into segments, filtering empty segments * * @param path the path to split * @return a list of non-empty path segments