celeris

package module
v1.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 30, 2026 License: Apache-2.0 Imports: 35 Imported by: 8

README

celeris

CI Go Reference Go Report Card License

Ultra-low latency Go HTTP engine with a protocol-aware dual-architecture (io_uring & epoll) designed for high-throughput infrastructure and zero-allocation microservices. It provides a familiar route-group and middleware API similar to Gin and Echo, so teams can adopt it without learning a new programming model.

Highlights

  • 3.3M+ HTTP/2 requests/sec on a single 8-vCPU machine (arm64 Graviton3)
  • 590K+ HTTP/1.1 requests/sec — 81% syscall-bound, zero allocations on the hot path
  • io_uring and epoll at parity — both engines hit the same throughput
  • H2 is 5.7x faster than H1 thanks to stream multiplexing and inline handler execution
  • Zero hot-path allocations for both H1 and H2

Features

  • Tiered io_uring — auto-selects the best io_uring feature set (multishot accept/recv, provided buffers, SQ poll, fixed files) for your kernel
  • Edge-triggered epoll — per-core event loops with CPU pinning
  • Adaptive meta-engine — dynamically switches between io_uring and epoll based on runtime telemetry
  • SIMD HTTP parser — SSE2 (amd64) and NEON (arm64) with generic SWAR fallback
  • HTTP/2 cleartext (h2c) — full stream multiplexing, flow control, HPACK, inline handler execution, zero-alloc HEADERS fast path
  • Auto-detect — protocol negotiation from the first bytes on the wire
  • Error-returning handlersHandlerFunc returns error; structured HTTPError for status codes
  • Serialization — JSON and XML response methods (JSON, XML); Protocol Buffers available via github.com/goceleris/middlewares; Bind auto-detects request format from Content-Type
  • net/http compatibility — wrap existing http.Handler via celeris.Adapt()
  • Built-in metrics collector — atomic counters, always-on Server.Collector().Snapshot()

Quick Start

go get github.com/goceleris/celeris@latest

Requires Go 1.26+. Linux for io_uring/epoll engines; any OS for the std engine.

Hello World

package main

import (
	"log"

	"github.com/goceleris/celeris"
)

func main() {
	s := celeris.New(celeris.Config{Addr: ":8080"})
	s.GET("/hello", func(c *celeris.Context) error {
		return c.String(200, "Hello, World!")
	})
	log.Fatal(s.Start())
}

Routing

s := celeris.New(celeris.Config{Addr: ":8080"})

// Static routes
s.GET("/health", healthHandler)

// Named parameters
s.GET("/users/:id", func(c *celeris.Context) error {
	id := c.Param("id")
	return c.JSON(200, map[string]string{"id": id})
})

// Catch-all wildcards
s.GET("/files/*path", staticFileHandler)

// Route groups
api := s.Group("/api")
api.GET("/items", listItems)
api.POST("/items", createItem)

// Nested groups
v2 := api.Group("/v2")
v2.GET("/items", listItemsV2)

Middleware

Middleware is provided by the goceleris/middlewares module — one subpackage per middleware, individually importable.

import (
	"github.com/goceleris/middlewares/logger"
	"github.com/goceleris/middlewares/recovery"
	"github.com/goceleris/middlewares/cors"
	"github.com/goceleris/middlewares/ratelimit"
)

s := celeris.New(celeris.Config{Addr: ":8080"})
s.Use(recovery.New())
s.Use(logger.New(slog.Default()))

api := s.Group("/api")
api.Use(ratelimit.New(1000))
api.Use(cors.New(cors.Config{
	AllowOrigins: []string{"https://example.com"},
}))

See the middlewares repo for the full list: Logger, Recovery, CORS, RateLimit, RequestID, Timeout, BodyLimit, BasicAuth, JWT, CSRF, Session, Metrics, Debug, Compress, and more.

Writing Custom Middleware

Middleware is just a HandlerFunc that calls c.Next():

func Timing() celeris.HandlerFunc {
	return func(c *celeris.Context) error {
		start := time.Now()
		err := c.Next()
		dur := time.Since(start)
		slog.Info("request", "path", c.Path(), "duration", dur, "error", err)
		return err
	}
}

s.Use(Timing())

The error returned by c.Next() is the first non-nil error from any downstream handler. Middleware can inspect, wrap, or swallow the error before returning.

Error Handling

HandlerFunc has the signature func(*Context) error. Returning a non-nil error propagates it up through the middleware chain. If no middleware handles the error, the router's safety net converts it to an HTTP response:

  • *HTTPError — responds with Code and Message from the error.
  • Any other error — responds with 500 Internal Server Error.
// Return a structured HTTP error
s.GET("/item/:id", func(c *celeris.Context) error {
	item, err := store.Find(c.Param("id"))
	if err != nil {
		return celeris.NewHTTPError(404, "item not found").WithError(err)
	}
	return c.JSON(200, item)
})

// Middleware can intercept errors from downstream handlers
func ErrorLogger() celeris.HandlerFunc {
	return func(c *celeris.Context) error {
		err := c.Next()
		if err != nil {
			slog.Error("handler error", "path", c.Path(), "error", err)
		}
		return err
	}
}

Configuration

s := celeris.New(celeris.Config{
	Addr:            ":8080",
	Protocol:        celeris.Auto,       // HTTP1, H2C, or Auto
	Engine:          celeris.Adaptive,    // IOUring, Epoll, Adaptive, or Std
	Workers:         8,
	Objective:       celeris.Latency,    // Latency, Throughput, or Balanced
	ReadTimeout:     30 * time.Second,
	WriteTimeout:    30 * time.Second,
	IdleTimeout:     120 * time.Second,
	ShutdownTimeout: 10 * time.Second,   // max wait for in-flight requests (default 30s)
	Logger:          slog.Default(),
})

net/http Compatibility

Wrap existing net/http handlers and middleware:

// Wrap http.Handler
s.GET("/legacy", celeris.Adapt(legacyHandler))

// Wrap http.HandlerFunc
s.GET("/func", celeris.AdaptFunc(func(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("from stdlib"))
}))

The bridge buffers the adapted handler's response in memory, capped at 100 MB. Responses exceeding this limit return an error.

Engine Selection

Engine Platform Use Case
IOUring Linux 5.10+ Lowest latency, highest throughput
Epoll Linux Broad kernel support, proven stability
Adaptive Linux Auto-switch based on telemetry
Std Any OS Development, compatibility, non-Linux deploys

Use Adaptive (the default on Linux) unless you have a specific reason to pin an engine. On non-Linux platforms, only Std is available.

Performance Profiles

Profile Optimizes For Key Tuning
celeris.Latency P99 tail latency TCP_NODELAY, small batches, SO_BUSY_POLL
celeris.Throughput Max RPS Large CQ batches, write batching
celeris.Balanced Mixed workloads Default settings

Graceful Shutdown

Use StartWithContext for production deployments. When the context is canceled, the server drains in-flight requests up to ShutdownTimeout (default 30s).

ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()

s := celeris.New(celeris.Config{
	Addr:            ":8080",
	ShutdownTimeout: 15 * time.Second,
})
s.GET("/hello", helloHandler)

if err := s.StartWithContext(ctx); err != nil {
	log.Fatal(err)
}

Observability

The core provides a lightweight metrics collector accessible via Server.Collector():

snap := server.Collector().Snapshot()
fmt.Println(snap.RequestsTotal, snap.ErrorsTotal, snap.ActiveConns)

For Prometheus exposition and debug endpoints, use the middlewares/metrics and middlewares/debug packages.

Feature Matrix

Feature io_uring epoll std
HTTP/1.1 yes yes yes
H2C yes yes yes
Auto-detect yes yes yes
CPU pinning yes yes no
Provided buffers yes (5.19+) no no
Multishot accept yes (5.19+) no no
Multishot recv yes (6.0+) no no
Zero-alloc HEADERS yes yes no
Inline H2 handlers yes yes no

Benchmarks

Cloud benchmarks on arm64 c7g.2xlarge (8 vCPU Graviton3), separate server and client machines:

Protocol Engine Throughput
HTTP/2 epoll 3.33M rps
HTTP/2 io_uring 3.30M rps
HTTP/1.1 epoll 590K rps
HTTP/1.1 io_uring 590K rps
  • io_uring and epoll within 1% of each other on both protocols
  • H2 is 5.7x faster than H1 (stream multiplexing + inline handlers)
  • Zero allocations on the hot path for both H1 and H2
  • All 3 engines within 0.3% of each other in adaptive mode

Methodology: 14 server configurations (io_uring/epoll/std x latency/throughput/balanced x H1/H2) tested with wrk (H1, 16384 connections) and h2load (H2, 128 connections x 128 streams) in 9-pass interleaved runs. Full results and reproduction scripts are in the benchmarks repo.

API Overview

Type Package Description
Server celeris Top-level entry point; owns config, router, engine
Config celeris Server configuration (addr, engine, protocol, timeouts)
Context celeris Per-request context with params, headers, body, response methods
HandlerFunc celeris func(*Context) error — handler/middleware signature
HTTPError celeris Structured error carrying HTTP status code and message
RouteGroup celeris Group of routes sharing a prefix and middleware
Route celeris Opaque handle to a registered route
Collector observe Lock-free request metrics aggregator
Snapshot observe Point-in-time copy of all collected metrics

Architecture

block-beta
  columns 3
  A["celeris (public API)"]:3
  B["adaptive"]:1 C["observe"]:2
  E["engine/iouring"]:1 F["engine/epoll"]:1 G["engine/std"]:1
  H["protocol/h1"]:1 I["protocol/h2"]:1 J["protocol/detect"]:1
  K["probe"]:1 L["resource"]:1 M["internal"]:1

Requirements

  • Go 1.26+
  • Linux for io_uring and epoll engines
  • Any OS for the std engine
  • Dependencies: golang.org/x/sys, golang.org/x/net

Project Structure

adaptive/       Adaptive meta-engine (Linux)
engine/         Engine interface + implementations (iouring, epoll, std)
internal/       Shared internals (conn, cpumon, platform, sockopts)
observe/        Lightweight metrics collector (atomic counters, Snapshot)
probe/          System capability detection
protocol/       Protocol parsers (h1, h2, detect)
resource/       Configuration, presets, objectives
test/           Conformance, spec compliance, integration, benchmarks

Contributing

go install github.com/magefile/mage@latest  # one-time setup
mage build   # build all targets
mage test    # run tests with race detector
mage lint    # run linters
mage check   # full verification: lint + test + spec + build

Pull requests should target main.

License

Apache License 2.0

Documentation

Overview

Package celeris provides an ultra-low latency HTTP server with dual-architecture I/O (io_uring + epoll) and a high-level API for routing and request handling.

Quick Start

s := celeris.New(celeris.Config{Addr: ":8080"})
s.GET("/hello", func(c *celeris.Context) error {
    return c.String(200, "Hello, World!")
})
log.Fatal(s.Start())

Routing

Routes support static paths, named parameters, and catch-all wildcards:

s.GET("/users/:id", handler)     // /users/42 → Param("id") = "42"
s.GET("/files/*path", handler)   // /files/a/b → Param("path") = "/a/b"

URL Parameters

Access matched parameters by name. Type-safe parsing methods are available:

id := c.Param("id")                 // string
n, err := c.ParamInt("id")          // int
n64, err := c.ParamInt64("id")      // int64

Query parameters support defaults and multi-values:

page := c.Query("page")                      // string
page := c.QueryDefault("page", "1")           // with default
limit := c.QueryInt("limit", 10)              // int with default
tags := c.QueryValues("tag")                  // []string
all := c.QueryParams()                        // url.Values
raw := c.RawQuery()                           // raw query string

Route Groups

api := s.Group("/api")
api.GET("/items", listItems)

Middleware

Middleware is provided by the github.com/goceleris/middlewares module. Use Server.Use to register middleware globally or per route group.

s.Use(middlewares.Logger(), middlewares.Recovery())

To write custom middleware, use the HandlerFunc signature and call Context.Next to invoke downstream handlers. Next returns the first error from downstream, which middleware can handle or propagate:

func timing() celeris.HandlerFunc {
    return func(c *celeris.Context) error {
        start := time.Now()
        err := c.Next()
        elapsed := time.Since(start)
        c.SetHeader("x-response-time", elapsed.String())
        return err
    }
}

Error Handling

Handlers return errors. Unhandled errors are caught by the routerAdapter safety net: *HTTPError writes its Code+Message; bare errors write 500.

s.GET("/data", func(c *celeris.Context) error {
    data, err := fetchData()
    if err != nil {
        return celeris.NewHTTPError(500, "fetch failed")
    }
    return c.JSON(200, data)
})

Middleware can intercept errors from downstream handlers:

s.Use(func(c *celeris.Context) error {
    err := c.Next()
    if err != nil {
        log.Println("error:", err)
        return c.JSON(500, map[string]string{"error": "internal"})
    }
    return nil
})

Custom 404 / 405 Handlers

s.NotFound(func(c *celeris.Context) error {
    return c.JSON(404, map[string]string{"error": "not found"})
})
s.MethodNotAllowed(func(c *celeris.Context) error {
    return c.JSON(405, map[string]string{"error": "method not allowed"})
})

Graceful Shutdown

ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
defer stop()

s := celeris.New(celeris.Config{
    Addr:            ":8080",
    ShutdownTimeout: 10 * time.Second,
})
s.GET("/ping", func(c *celeris.Context) error {
    return c.String(200, "pong")
})
if err := s.StartWithContext(ctx); err != nil {
    log.Fatal(err)
}

Engine Selection

On Linux, choose between IOUring, Epoll, Adaptive, or Std engines. On other platforms, only Std is available.

s := celeris.New(celeris.Config{
    Addr:   ":8080",
    Engine: celeris.Adaptive,
})

Protocol Selection

The Protocol field controls HTTP version negotiation:

celeris.HTTP1    // HTTP/1.1 only (default)
celeris.H2C      // HTTP/2 cleartext (h2c) only
celeris.Auto     // Auto-detect: serves both HTTP/1.1 and H2C

Example:

s := celeris.New(celeris.Config{
    Addr:     ":8080",
    Protocol: celeris.Auto,
})

net/http Compatibility

Wrap existing net/http handlers. Response bodies from adapted handlers are buffered in memory (capped at 100 MB).

s.GET("/legacy", celeris.Adapt(legacyHandler))

Context Lifecycle

Context objects are pooled and recycled between requests. Do not retain references to a *Context after the handler returns. Copy any needed values before returning. For the request body specifically, use Context.BodyCopy to obtain a copy that outlives the handler:

safe := c.BodyCopy() // safe to pass to a goroutine

When using Detach, the returned done function MUST be called — failure to do so permanently leaks the Context from the pool.

Observability

The Server.Collector method returns an observe.Collector that records per-request metrics (throughput, latency histogram, error rate, active connections). Use Collector.Snapshot to retrieve a point-in-time copy:

snap := s.Collector().Snapshot()
fmt.Println(snap.RequestsTotal, snap.ErrorsTotal)

For Prometheus or debug endpoint integration, see the github.com/goceleris/middlewares module.

Configuration

Config.Workers controls the number of I/O workers (default: GOMAXPROCS). Config.ShutdownTimeout sets the graceful shutdown deadline for StartWithContext (default: 30s).

Named Routes & Reverse URLs

Assign names to routes with Route.Name, then generate URLs via Server.URL:

s.GET("/users/:id", handler).Name("user")
url, _ := s.URL("user", "42") // "/users/42"

For catch-all routes the value replaces the wildcard segment:

s.GET("/files/*filepath", handler).Name("files")
url, _ := s.URL("files", "/css/style.css") // "/files/css/style.css"

Use Server.Routes to list all registered routes.

Form Handling

Parse url-encoded and multipart form bodies:

name := c.FormValue("name")
all  := c.FormValues("tags")

For file uploads, use FormFile or MultipartForm:

file, header, err := c.FormFile("avatar")
defer file.Close()

File Serving

Serve static files with automatic content-type detection and Range support:

s.GET("/download", func(c *celeris.Context) error {
    return c.File("/var/data/report.pdf")
})

Callers must sanitize user-supplied paths to prevent directory traversal.

Static File Serving

Serve an entire directory under a URL prefix:

s.Static("/assets", "./public")

This is equivalent to:

s.GET("/assets/*filepath", func(c *celeris.Context) error {
    return c.FileFromDir("./public", c.Param("filepath"))
})

Streaming

For simple cases, stream an io.Reader as a buffered response (capped at 100 MB):

return c.Stream(200, "text/plain", reader)

For true incremental streaming (SSE, chunked responses), use StreamWriter with the Detach pattern:

s.GET("/events", func(c *celeris.Context) error {
    sw := c.StreamWriter()
    if sw == nil {
        return c.String(200, "streaming not supported")
    }
    done := c.Detach()
    sw.WriteHeader(200, [][2]string{{"content-type", "text/event-stream"}})
    go func() {
        defer done()
        defer sw.Close()
        for event := range events {
            sw.Write([]byte("data: " + event + "\n\n"))
            sw.Flush()
        }
    }()
    return nil
})

StreamWriter returns nil if the engine does not support streaming. The std engine supports streaming; native engines (io_uring, epoll) will support it in a future release.

Cookies

Read and write cookies:

val, err := c.Cookie("session")
c.SetCookie(&celeris.Cookie{Name: "session", Value: token, HTTPOnly: true})

Authentication

Extract HTTP Basic Authentication credentials:

user, pass, ok := c.BasicAuth()

Request Body Parsing

Bind auto-detects the format from Content-Type:

var user User
if err := c.Bind(&user); err != nil {
    return err
}

Or use format-specific methods:

c.BindJSON(&user)  // application/json
c.BindXML(&user)   // application/xml

For raw body access:

body := c.Body()         // []byte, valid only during handler
safe := c.BodyCopy()     // []byte, safe to retain after handler
r := c.BodyReader()      // io.Reader wrapper

Response Methods

Context provides typed response methods:

c.JSON(200, data)                      // application/json
c.XML(200, data)                       // application/xml
c.HTML(200, "<h1>Hello</h1>")          // text/html
c.String(200, "Hello, %s", name)       // text/plain (fmt.Sprintf)
c.Blob(200, "image/png", pngBytes)     // arbitrary content type
c.NoContent(204)                       // status only, no body
c.Redirect(302, "/new-location")       // redirect with Location header
c.File("/path/to/report.pdf")          // file with MIME detection + Range
c.FileFromDir(baseDir, userPath)       // safe file serving (traversal-safe)
c.Stream(200, "text/plain", reader)    // io.Reader → response (100 MB cap)
c.Respond(200, data)                   // auto-format based on Accept header

All response methods return ErrResponseWritten if called after a response has already been sent.

Content Negotiation

Inspect the Accept header and auto-select the response format:

best := c.Negotiate("application/json", "application/xml", "text/plain")

Or use Respond to auto-format based on Accept:

return c.Respond(200, myStruct) // JSON, XML, or text based on Accept

Accept Negotiation

Beyond content type, negotiate encodings and languages:

enc := c.AcceptsEncodings("gzip", "br", "identity")
lang := c.AcceptsLanguages("en", "fr", "de")

Route-Level Middleware

Attach middleware to individual routes without creating a group:

s.GET("/admin", adminHandler).Use(authMiddleware)

Route.Use inserts middleware before the final handler, after server/group middleware. Must be called before Server.Start.

Response Capture

Middleware can inspect the response body after c.Next() by opting in:

func logger() celeris.HandlerFunc {
    return func(c *celeris.Context) error {
        c.CaptureResponse()
        err := c.Next()
        body := c.ResponseBody()       // captured response body
        ct := c.ResponseContentType()  // captured Content-Type
        // ... log body, ct ...
        return err
    }
}

Response Buffering

Middleware that needs to transform response bodies (compress, ETag, cache) uses BufferResponse to intercept and modify the response before it is sent:

func compress() celeris.HandlerFunc {
    return func(c *celeris.Context) error {
        c.BufferResponse()
        err := c.Next()
        if err != nil {
            return err
        }
        body := c.ResponseBody()
        compressed := gzip(body)
        c.SetResponseBody(compressed)
        c.SetHeader("content-encoding", "gzip")
        return c.FlushResponse()
    }
}

BufferResponse is depth-tracked: multiple middleware layers can each call BufferResponse, and the response is only sent when the outermost layer calls FlushResponse. If middleware forgets to flush, a safety net in the handler adapter auto-flushes the response.

CaptureResponse and BufferResponse serve different purposes. CaptureResponse is read-only: the response is written to the wire AND a copy is captured for inspection (ideal for loggers). BufferResponse defers the wire write entirely, allowing middleware to transform the body before sending (ideal for compress, ETag, cache). If both are active, BufferResponse takes precedence.

Response Inspection

Check response state from middleware after calling c.Next():

written := c.IsWritten()         // true after response sent to wire
size := c.BytesWritten()         // response body size in bytes
status := c.StatusCode()         // status code set by handler
status := c.ResponseStatus()     // captured status (with BufferResponse)
hdrs := c.RequestHeaders()       // all request headers as [][2]string

Error Types

Handlers signal HTTP errors via HTTPError:

return celeris.NewHTTPError(404, "user not found")
return celeris.NewHTTPError(500, "db error").WithError(err)  // wrap cause

Sentinel errors for common conditions:

celeris.ErrResponseWritten   // response already sent
celeris.ErrEmptyBody         // Bind called with empty body
celeris.ErrNoCookie          // Cookie() with missing cookie
celeris.ErrHijackNotSupported // Hijack on unsupported connection

Flow Control

Middleware calls Next to invoke downstream handlers. Abort stops the chain:

err := c.Next()              // call next handler; returns first error
c.Abort()                    // stop chain (does not write response)
c.AbortWithStatus(403)       // stop chain and send status code
c.IsAborted()                // true if Abort was called

Key-Value Storage

Store request-scoped data for sharing between middleware and handlers:

c.Set("userID", 42)
id, ok := c.Get("userID")
all := c.Keys()              // copy of all stored pairs

Content-Disposition

Set Content-Disposition headers for file downloads or inline display:

c.Attachment("report.pdf")   // prompts download
c.Inline("image.png")       // suggests inline display

Request Detection

Detect request characteristics:

c.IsWebSocket()              // true if Upgrade: websocket
c.IsTLS()                    // true if X-Forwarded-Proto is "https"

Form Presence

FormValueOk distinguishes a missing field from an empty value:

val, ok := c.FormValueOk("name")
if !ok {
    // field was not submitted
}

Request Inspection

Additional request accessors:

scheme := c.Scheme()         // "http" or "https" (checks X-Forwarded-Proto)
ip := c.ClientIP()           // from X-Forwarded-For or X-Real-Ip
method := c.Method()         // HTTP method
path := c.Path()             // path without query string
full := c.FullPath()         // matched route pattern (e.g. "/users/:id")
raw := c.RawQuery()          // raw query string without leading '?'

Remote Address

Context.RemoteAddr returns the TCP peer address. On native engines (epoll, io_uring), the address is captured from accept(2) or getpeername(2). On the std engine, it comes from http.Request.RemoteAddr.

addr := c.RemoteAddr() // e.g. "192.168.1.1:54321"

Host

Context.Host returns the request host, checking the :authority pseudo-header first (HTTP/2) then falling back to the Host header (HTTP/1.1):

host := c.Host() // e.g. "example.com"

Connection Hijacking

HTTP/1.1 connections can be hijacked on all engines for WebSocket or other protocols that require raw TCP access:

conn, err := c.Hijack()
if err != nil {
    return err
}
defer conn.Close()
// conn is a net.Conn — caller owns the connection

HTTP/2 connections cannot be hijacked because multiplexed streams share a single TCP connection.

Graceful Restart

Start the server with a pre-existing listener for zero-downtime deploys:

ln, _ := celeris.InheritListener("LISTEN_FD")
if ln != nil {
    log.Fatal(s.StartWithListener(ln))
} else {
    log.Fatal(s.Start())
}

Config Surface Area

In addition to the basic config fields, the following tuning fields are available:

celeris.Config{
    // Basic
    Addr:     ":8080",
    Protocol: celeris.Auto,        // HTTP1, H2C, or Auto
    Engine:   celeris.Adaptive,    // IOUring, Epoll, Adaptive, Std

    // Workers
    Workers:   0,                  // I/O workers (default GOMAXPROCS)

    // Timeouts (0 = default: 300s read/write, 600s idle; -1 = no timeout)
    ReadTimeout:     0,
    WriteTimeout:    0,
    IdleTimeout:     0,
    ShutdownTimeout: 30*time.Second,

    // Limits
    MaxFormSize: 0,                // multipart form memory (0 = 32 MB; -1 = unlimited)
    MaxConns:    0,                // max connections per worker (0 = unlimited)

    // H2 Tuning
    MaxConcurrentStreams: 100,     // H2 streams per connection
    MaxFrameSize:        16384,   // H2 frame payload size
    InitialWindowSize:   65535,   // H2 stream flow-control window
    MaxHeaderBytes:      0,       // header block size (0 = 16 MB)

    // I/O
    DisableKeepAlive: false,       // disable HTTP keep-alive
    BufferSize:       0,           // per-connection I/O buffer (0 = engine default)
    SocketRecvBuf:    0,           // SO_RCVBUF (0 = OS default)
    SocketSendBuf:    0,           // SO_SNDBUF (0 = OS default)

    // Observability
    DisableMetrics: false,         // skip per-request metric recording
    Logger: nil,                   // *slog.Logger for engine diagnostics

    // Connection callbacks (must be fast — blocks the event loop)
    OnConnect:    func(addr string) { ... },
    OnDisconnect: func(addr string) { ... },
}

Listener Address

After Start or StartWithContext, Server.Addr returns the bound address. This is useful when listening on ":0" to discover the OS-assigned port:

addr := s.Addr() // net.Addr; use addr.String() for "127.0.0.1:49152"

Testing

The github.com/goceleris/celeris/celeristest package provides test helpers:

ctx, rec := celeristest.NewContext("GET", "/hello")
defer celeristest.ReleaseContext(ctx)
handler(ctx)
// inspect rec.StatusCode, rec.Headers, rec.Body
Example
package main

import (
	"fmt"

	"github.com/goceleris/celeris"
)

func main() {
	s := celeris.New(celeris.Config{Addr: ":8080"})
	s.GET("/hello", func(c *celeris.Context) error {
		return c.String(200, "Hello, World!")
	})
	// s.Start() blocks until shutdown
	_ = s // prevent unused error in example
	fmt.Println("server configured")
}
Output:
server configured

Index

Examples

Constants

View Source
const DefaultMaxFormSize int64 = 32 << 20

DefaultMaxFormSize is the default maximum memory used for multipart form parsing (32 MB), matching net/http.

View Source
const Version = "1.0.0"

Version is the semantic version of the celeris module.

Variables

View Source
var ErrAlreadyStarted = errors.New("celeris: server already started")

ErrAlreadyStarted is returned when Start or StartWithContext is called on a server that is already running.

View Source
var ErrDuplicateRouteName = errors.New("celeris: duplicate route name")

ErrDuplicateRouteName is returned by Route.TryName when a route with the given name has already been registered.

View Source
var ErrEmptyBody = errors.New("celeris: empty request body")

ErrEmptyBody is returned by Bind, BindJSON, and BindXML when the request body is empty.

View Source
var ErrHijackNotSupported = stream.ErrHijackNotSupported

ErrHijackNotSupported is returned by Hijack when the connection does not support takeover (e.g. HTTP/2 multiplexed streams).

View Source
var ErrInvalidRedirectCode = errors.New("celeris: redirect status code must be 3xx")

ErrInvalidRedirectCode is returned by Context.Redirect when the status code is not in the range 300–308.

View Source
var ErrNoCookie = errors.New("celeris: named cookie not present")

ErrNoCookie is returned by Context.Cookie when the named cookie is not present.

View Source
var ErrResponseWritten = errors.New("celeris: response already written")

ErrResponseWritten is returned when a response method is called after a response has already been written.

View Source
var ErrRouteNotFound = errors.New("celeris: named route not found")

ErrRouteNotFound is returned by Server.URL when no route with the given name has been registered.

Functions

func InheritListener added in v1.1.0

func InheritListener(envVar string) (net.Listener, error)

InheritListener returns a net.Listener from the file descriptor in the named environment variable. Returns nil, nil if the variable is not set. Used for zero-downtime restart patterns.

func ToHandler added in v1.1.0

func ToHandler(h HandlerFunc) http.Handler

ToHandler wraps a celeris HandlerFunc as an http.Handler for use with net/http routers, middleware, or test infrastructure. The returned handler converts the *http.Request into a stream.Stream, invokes the celeris handler, and writes the response back via http.ResponseWriter.

This is the reverse of Adapt / AdaptFunc which wrap net/http handlers for use inside celeris.

Types

type Config

type Config struct {
	// Addr is the TCP address to listen on (e.g. ":8080").
	Addr string
	// Protocol is the HTTP protocol version (default Auto — auto-detect H1/H2).
	Protocol Protocol
	// Engine is the I/O engine (default Adaptive on Linux, Std elsewhere).
	Engine EngineType

	// Workers is the number of I/O worker goroutines (default GOMAXPROCS).
	Workers int

	// ReadTimeout is the max duration for reading the entire request.
	// Zero uses the default (300s). Set to -1 for no timeout.
	ReadTimeout time.Duration
	// WriteTimeout is the max duration for writing the response.
	// Zero uses the default (300s). Set to -1 for no timeout.
	WriteTimeout time.Duration
	// IdleTimeout is the max duration a keep-alive connection may be idle.
	// Zero uses the default (600s). Set to -1 for no timeout.
	IdleTimeout time.Duration
	// ShutdownTimeout is the max duration to wait for in-flight requests during
	// graceful shutdown via StartWithContext (default 30s).
	ShutdownTimeout time.Duration

	// MaxFormSize is the maximum memory used for multipart form parsing
	// (default 32 MB). Set to -1 to disable the limit.
	MaxFormSize int64

	// MaxConcurrentStreams limits simultaneous H2 streams per connection (default 100).
	MaxConcurrentStreams uint32
	// MaxFrameSize is the max H2 frame payload size (default 16384, range 16384-16777215).
	MaxFrameSize uint32
	// InitialWindowSize is the H2 initial stream window size (default 65535).
	InitialWindowSize uint32
	// MaxHeaderBytes is the max header block size (default 16 MB, min 4096).
	MaxHeaderBytes int

	// DisableKeepAlive disables HTTP keep-alive; each request gets its own connection.
	DisableKeepAlive bool
	// BufferSize is the per-connection I/O buffer size in bytes (0 = engine default).
	BufferSize int
	// SocketRecvBuf sets SO_RCVBUF for accepted connections (0 = OS default).
	SocketRecvBuf int
	// SocketSendBuf sets SO_SNDBUF for accepted connections (0 = OS default).
	SocketSendBuf int
	// MaxConns is the max simultaneous connections per worker (0 = unlimited).
	MaxConns int

	// DisableMetrics disables the built-in metrics collector. When true,
	// [Server.Collector] returns nil and per-request metric recording is skipped.
	// Default false (metrics enabled).
	DisableMetrics bool

	// OnConnect is called when a new connection is accepted. The addr is the
	// remote peer address. Must be fast — blocks the event loop.
	OnConnect func(addr string)
	// OnDisconnect is called when a connection is closed. The addr is the
	// remote peer address. Must be fast — blocks the event loop.
	OnDisconnect func(addr string)

	// Logger is the structured logger (default slog.Default()).
	Logger *slog.Logger
}

Config holds the public server configuration.

type Context

type Context struct {
	// contains filtered or unexported fields
}

Context is the request context passed to handlers. It is pooled via sync.Pool. A Context is obtained from the pool and must not be retained after the handler returns.

func (*Context) Abort

func (c *Context) Abort()

Abort prevents pending handlers from being called. Does not write a response. Use AbortWithStatus to abort and send a status code.

func (*Context) AbortWithStatus

func (c *Context) AbortWithStatus(code int) error

AbortWithStatus calls Abort and writes a status code with no body. It returns the error from NoContent for propagation.

func (*Context) AcceptsEncodings added in v1.1.0

func (c *Context) AcceptsEncodings(offers ...string) string

AcceptsEncodings returns the best matching encoding from the Accept-Encoding header, or empty string if none match.

Example
package main

import (
	"fmt"

	"github.com/goceleris/celeris/celeristest"
)

func main() {
	ctx, _ := celeristest.NewContext("GET", "/data",
		celeristest.WithHeader("accept-encoding", "gzip, br;q=0.8"),
	)
	defer celeristest.ReleaseContext(ctx)

	fmt.Println(ctx.AcceptsEncodings("br", "gzip"))
}
Output:
gzip

func (*Context) AcceptsLanguages added in v1.1.0

func (c *Context) AcceptsLanguages(offers ...string) string

AcceptsLanguages returns the best matching language from the Accept-Language header, or empty string if none match.

func (*Context) AddHeader

func (c *Context) AddHeader(key, value string)

AddHeader appends a response header value. Unlike SetHeader, it does not replace existing values — use this for headers that allow multiple values (e.g. set-cookie).

func (*Context) Attachment added in v1.1.0

func (c *Context) Attachment(filename string)

Attachment sets the Content-Disposition header to "attachment" with the given filename, prompting the client to download the response.

Example
package main

import (
	"fmt"

	"github.com/goceleris/celeris/celeristest"
)

func main() {
	ctx, rec := celeristest.NewContext("GET", "/download")
	defer celeristest.ReleaseContext(ctx)

	ctx.Attachment("report.pdf")
	_ = ctx.Blob(200, "application/pdf", []byte("content"))
	fmt.Println(rec.Header("content-disposition"))
}
Output:
attachment; filename="report.pdf"

func (*Context) BasicAuth

func (c *Context) BasicAuth() (username, password string, ok bool)

BasicAuth extracts HTTP Basic Authentication credentials from the Authorization header. Returns the username, password, and true if valid credentials are present; otherwise returns zero values and false.

Example
package main

import (
	"fmt"

	"github.com/goceleris/celeris/celeristest"
)

func main() {
	ctx, _ := celeristest.NewContext("GET", "/admin",
		celeristest.WithBasicAuth("alice", "secret"),
	)
	defer celeristest.ReleaseContext(ctx)

	user, _, ok := ctx.BasicAuth()
	fmt.Println(ok, user)
}
Output:
true alice

func (*Context) Bind

func (c *Context) Bind(v any) error

Bind auto-detects the request body format from the Content-Type header and deserializes into v. Supports application/json (default) and application/xml. Returns ErrEmptyBody if the body is empty, or the underlying encoding/json or encoding/xml error if deserialization fails.

Example
package main

import (
	"fmt"

	"github.com/goceleris/celeris/celeristest"
)

func main() {
	type User struct {
		Name string `json:"name"`
	}
	body := []byte(`{"name":"bob"}`)
	ctx, _ := celeristest.NewContext("POST", "/users",
		celeristest.WithBody(body),
		celeristest.WithContentType("application/json"),
	)
	defer celeristest.ReleaseContext(ctx)

	var u User
	err := ctx.Bind(&u)
	fmt.Println(err)
	fmt.Println(u.Name)
}
Output:
<nil>
bob

func (*Context) BindJSON

func (c *Context) BindJSON(v any) error

BindJSON deserializes the JSON request body into v. Returns ErrEmptyBody if the body is empty.

func (*Context) BindXML

func (c *Context) BindXML(v any) error

BindXML deserializes the XML request body into v. Returns ErrEmptyBody if the body is empty.

func (*Context) Blob

func (c *Context) Blob(code int, contentType string, data []byte) error

Blob writes a response with the given content type and data. Returns ErrResponseWritten if a response has already been sent.

func (*Context) Body

func (c *Context) Body() []byte

Body returns the raw request body. The returned slice must not be modified or retained after the handler returns.

func (*Context) BodyCopy added in v1.1.0

func (c *Context) BodyCopy() []byte

BodyCopy returns a copy of the request body that is safe to retain after the handler returns. Use this instead of Body() when the body must outlive the request lifecycle (e.g., for async processing or logging).

func (*Context) BodyReader added in v1.1.0

func (c *Context) BodyReader() io.Reader

BodyReader returns an io.Reader for the request body. This wraps the already-received body bytes.

func (*Context) BufferResponse added in v1.1.0

func (c *Context) BufferResponse()

BufferResponse instructs response methods (JSON, XML, Blob, NoContent, etc.) to capture the response instead of writing to the wire. Multiple middleware layers can call BufferResponse — responses are depth-tracked and only sent when the outermost layer calls FlushResponse.

Example
package main

import (
	"fmt"
	"strings"

	"github.com/goceleris/celeris/celeristest"
)

func main() {
	ctx, rec := celeristest.NewContext("GET", "/data")
	defer celeristest.ReleaseContext(ctx)

	ctx.BufferResponse()
	_ = ctx.String(200, "original")

	// Transform the buffered body before sending.
	body := ctx.ResponseBody()
	ctx.SetResponseBody([]byte(strings.ToUpper(string(body))))
	_ = ctx.FlushResponse()

	fmt.Println(rec.StatusCode)
	fmt.Println(rec.BodyString())
}
Output:
200
ORIGINAL

func (*Context) BytesWritten added in v1.1.0

func (c *Context) BytesWritten() int

BytesWritten returns the response body size in bytes, or 0 if no response was written. For NoContent responses, returns 0.

func (*Context) CaptureResponse added in v1.1.0

func (c *Context) CaptureResponse()

CaptureResponse enables response body capture for this request. After calling Next(), use ResponseBody() and ResponseContentType() to inspect. The response is written to the wire AND a copy is captured for inspection (ideal for loggers). Use BufferResponse to defer the wire write entirely.

func (*Context) ClientIP

func (c *Context) ClientIP() string

ClientIP extracts the client IP from X-Forwarded-For or X-Real-Ip headers. Returns empty string if neither header is present. These headers can be spoofed by clients. In production behind a reverse proxy, ensure only trusted proxies set these headers.

func (*Context) Context

func (c *Context) Context() context.Context

Context returns the request's context.Context. The returned context is always non-nil; it defaults to the stream's context.

func (*Context) Cookie

func (c *Context) Cookie(name string) (string, error)

Cookie returns the value of the named cookie from the request, or ErrNoCookie if not found. Values are returned as-is without decoding.

Example
package main

import (
	"fmt"

	"github.com/goceleris/celeris"
	"github.com/goceleris/celeris/celeristest"
)

func main() {
	ctx, rec := celeristest.NewContext("GET", "/test",
		celeristest.WithCookie("session", "abc123"),
	)
	defer celeristest.ReleaseContext(ctx)

	val, err := ctx.Cookie("session")
	fmt.Println(val, err)

	ctx.SetCookie(&celeris.Cookie{Name: "token", Value: "xyz", HTTPOnly: true})
	_ = ctx.NoContent(200)
	fmt.Println(rec.Header("set-cookie"))
}
Output:
abc123 <nil>
token=xyz; HttpOnly

func (*Context) Detach added in v1.1.0

func (c *Context) Detach() (done func())

Detach removes the Context from the handler chain's lifecycle. After Detach, the Context will not be released when the handler returns. The caller MUST call the returned done function when finished with the Context — failure to do so permanently leaks the Context from the pool. This is required for streaming responses on native engines where the handler must return to free the event loop thread.

func (*Context) File

func (c *Context) File(filePath string) error

File serves the named file. The content type is detected from the file extension. Supports Range requests for partial content (HTTP 206).

The entire file is loaded into memory (capped at 100 MB). Returns HTTPError with status 413 if the file exceeds this limit. For large files, consider using StreamWriter instead.

Security: filePath is opened directly — callers MUST sanitize user-supplied paths (e.g. filepath.Clean + prefix check) to prevent directory traversal.

Example
package main

import (
	"fmt"
	"os"

	"github.com/goceleris/celeris/celeristest"
)

func main() {
	dir, _ := os.MkdirTemp("", "celeris-example-*")
	defer func() { _ = os.RemoveAll(dir) }()
	_ = os.WriteFile(dir+"/hello.txt", []byte("hello"), 0644)

	ctx, rec := celeristest.NewContext("GET", "/download")
	defer celeristest.ReleaseContext(ctx)

	_ = ctx.File(dir + "/hello.txt")
	fmt.Println(rec.StatusCode)
	fmt.Println(rec.BodyString())
}
Output:
200
hello

func (*Context) FileFromDir

func (c *Context) FileFromDir(baseDir, userPath string) error

FileFromDir safely serves a file from within baseDir. The userPath is cleaned and joined with baseDir; if the result escapes baseDir, a 400 error is returned. This prevents directory traversal when serving user-supplied paths.

func (*Context) FlushResponse added in v1.1.0

func (c *Context) FlushResponse() error

FlushResponse sends the buffered response to the wire. Each call decrements the buffer depth; the actual write happens when depth reaches zero. Returns nil if nothing was buffered. Returns ErrResponseWritten if already sent. Calling FlushResponse without a prior BufferResponse is a safe no-op.

func (*Context) FormFile

func (c *Context) FormFile(name string) (multipart.File, *multipart.FileHeader, error)

FormFile returns the first file for the named form field. Returns HTTPError with status 400 if the request is not multipart or the field is missing.

func (*Context) FormValue

func (c *Context) FormValue(name string) string

FormValue returns the first value for the named form field. Parses the request body on first call (url-encoded or multipart).

Example
package main

import (
	"fmt"

	"github.com/goceleris/celeris/celeristest"
)

func main() {
	ctx, _ := celeristest.NewContext("POST", "/submit",
		celeristest.WithBody([]byte("name=alice&color=blue")),
		celeristest.WithContentType("application/x-www-form-urlencoded"),
	)
	defer celeristest.ReleaseContext(ctx)

	fmt.Println(ctx.FormValue("name"))
	fmt.Println(ctx.FormValue("color"))
}
Output:
alice
blue

func (*Context) FormValueOk

func (c *Context) FormValueOk(name string) (string, bool)

FormValueOk returns the first value for the named form field plus a boolean indicating whether the field was present. Unlike FormValue, callers can distinguish a missing field from an empty value.

func (*Context) FormValues

func (c *Context) FormValues(name string) []string

FormValues returns all values for the named form field.

func (*Context) FullPath

func (c *Context) FullPath() string

FullPath returns the matched route pattern (e.g. "/users/:id"). Returns empty string if no route was matched.

func (*Context) Get

func (c *Context) Get(key string) (any, bool)

Get returns the value for a key.

func (*Context) HTML

func (c *Context) HTML(code int, html string) error

HTML writes an HTML response with the given status code. Returns ErrResponseWritten if a response has already been sent.

func (*Context) Header

func (c *Context) Header(key string) string

Header returns the value of the named request header. Keys must be lowercase (HTTP/2 mandates lowercase; the H1 parser normalizes to lowercase).

func (*Context) Hijack added in v1.1.0

func (c *Context) Hijack() (net.Conn, error)

Hijack takes over the underlying TCP connection. After Hijack, the caller owns the connection and is responsible for closing it. Supported on all engines for HTTP/1.1 connections. HTTP/2 connections cannot be hijacked (multiplexed streams share a single TCP connection).

Example
package main

import (
	"fmt"

	"github.com/goceleris/celeris/celeristest"
)

func main() {
	ctx, _ := celeristest.NewContext("GET", "/ws")
	defer celeristest.ReleaseContext(ctx)

	// celeristest uses a mock writer that does not implement Hijacker,
	// so Hijack returns ErrHijackNotSupported.
	_, err := ctx.Hijack()
	fmt.Println(err)
}
Output:
celeris: hijack not supported by this engine

func (*Context) Host added in v1.1.0

func (c *Context) Host() string

Host returns the request host from the :authority pseudo-header (HTTP/2) or the Host header (HTTP/1.1).

func (*Context) Inline added in v1.1.0

func (c *Context) Inline(filename string)

Inline sets the Content-Disposition header to "inline" with the given filename, suggesting the client display the content in-browser.

func (*Context) IsAborted

func (c *Context) IsAborted() bool

IsAborted returns true if the handler chain was aborted.

func (*Context) IsTLS added in v1.1.0

func (c *Context) IsTLS() bool

IsTLS returns true if the request was made over TLS.

func (*Context) IsWebSocket added in v1.1.0

func (c *Context) IsWebSocket() bool

IsWebSocket returns true if the request is a WebSocket upgrade.

Example
package main

import (
	"fmt"

	"github.com/goceleris/celeris/celeristest"
)

func main() {
	ctx, _ := celeristest.NewContext("GET", "/ws",
		celeristest.WithHeader("upgrade", "websocket"),
	)
	defer celeristest.ReleaseContext(ctx)

	fmt.Println(ctx.IsWebSocket())
}
Output:
true

func (*Context) IsWritten added in v1.1.0

func (c *Context) IsWritten() bool

IsWritten returns true if a response has been written to the wire.

func (*Context) JSON

func (c *Context) JSON(code int, v any) error

JSON serializes v as JSON and writes it with the given status code. Returns ErrResponseWritten if a response has already been sent.

Example
package main

import (
	"encoding/json"
	"fmt"

	"github.com/goceleris/celeris/celeristest"
)

func main() {
	ctx, rec := celeristest.NewContext("GET", "/api/user")
	defer celeristest.ReleaseContext(ctx)

	_ = ctx.JSON(200, map[string]string{"name": "alice"})
	fmt.Println(rec.StatusCode)
	fmt.Println(rec.Header("content-type"))
	var m map[string]string
	_ = json.Unmarshal(rec.Body, &m)
	fmt.Println(m["name"])
}
Output:
200
application/json
alice

func (*Context) Keys

func (c *Context) Keys() map[string]any

Keys returns a copy of all key-value pairs stored on this context. Returns nil if no values have been set.

func (*Context) Method

func (c *Context) Method() string

Method returns the HTTP method.

func (*Context) MultipartForm

func (c *Context) MultipartForm() (*multipart.Form, error)

MultipartForm returns the parsed multipart form, including file uploads. Returns HTTPError with status 400 if the request is not multipart.

func (*Context) Negotiate added in v1.1.0

func (c *Context) Negotiate(offers ...string) string

Negotiate inspects the Accept header and returns the best matching content type from the provided offers. Returns "" if no match. Supports quality values (q=).

Example
package main

import (
	"fmt"

	"github.com/goceleris/celeris/celeristest"
)

func main() {
	ctx, _ := celeristest.NewContext("GET", "/data",
		celeristest.WithHeader("accept", "application/xml, application/json;q=0.9"),
	)
	defer celeristest.ReleaseContext(ctx)

	best := ctx.Negotiate("application/json", "application/xml")
	fmt.Println(best)
}
Output:
application/xml

func (*Context) Next

func (c *Context) Next() error

Next executes the next handler in the chain. It returns the first non-nil error from a downstream handler, short-circuiting the remaining chain. Middleware can inspect or swallow errors by checking the return value.

func (*Context) NoContent

func (c *Context) NoContent(code int) error

NoContent writes a response with no body. Returns ErrResponseWritten if a response has already been sent.

func (*Context) Param

func (c *Context) Param(key string) string

Param returns the value of a URL parameter by name.

Example
package main

import (
	"fmt"

	"github.com/goceleris/celeris/celeristest"
)

func main() {
	ctx, _ := celeristest.NewContext("GET", "/users/42",
		celeristest.WithParam("id", "42"),
	)
	defer celeristest.ReleaseContext(ctx)

	fmt.Println(ctx.Param("id"))
}
Output:
42

func (*Context) ParamInt

func (c *Context) ParamInt(key string) (int, error)

ParamInt returns a URL parameter parsed as an int. Returns an error if the parameter is missing or not a valid integer.

func (*Context) ParamInt64

func (c *Context) ParamInt64(key string) (int64, error)

ParamInt64 returns a URL parameter parsed as an int64. Returns an error if the parameter is missing or not a valid integer.

func (*Context) Path

func (c *Context) Path() string

Path returns the request path without query string.

func (*Context) Query

func (c *Context) Query(key string) string

Query returns the value of a query parameter by name. Results are cached so repeated calls for different keys do not re-parse the query string.

Example
package main

import (
	"fmt"

	"github.com/goceleris/celeris/celeristest"
)

func main() {
	ctx, _ := celeristest.NewContext("GET", "/search",
		celeristest.WithQuery("q", "celeris"),
		celeristest.WithQuery("page", "2"),
	)
	defer celeristest.ReleaseContext(ctx)

	fmt.Println(ctx.Query("q"))
	fmt.Println(ctx.QueryDefault("limit", "10"))
}
Output:
celeris
10

func (*Context) QueryDefault

func (c *Context) QueryDefault(key, defaultValue string) string

QueryDefault returns the value of a query parameter, or the default if absent or empty.

func (*Context) QueryInt

func (c *Context) QueryInt(key string, defaultValue int) int

QueryInt returns a query parameter parsed as an int. Returns the provided default value if the key is absent or not a valid integer.

func (*Context) QueryParams

func (c *Context) QueryParams() url.Values

QueryParams returns all query parameters as url.Values.

func (*Context) QueryValues

func (c *Context) QueryValues(key string) []string

QueryValues returns all values for the given query parameter key. Returns nil if the key is not present.

func (*Context) RawQuery added in v1.1.0

func (c *Context) RawQuery() string

RawQuery returns the raw query string without the leading '?'. Returns empty string if the URL has no query component.

func (*Context) Redirect

func (c *Context) Redirect(code int, url string) error

Redirect sends an HTTP redirect to the given URL with the specified status code. Returns ErrInvalidRedirectCode if code is not in the range 300–308. Returns ErrResponseWritten if a response has already been sent.

Example
package main

import (
	"fmt"

	"github.com/goceleris/celeris/celeristest"
)

func main() {
	ctx, rec := celeristest.NewContext("GET", "/old")
	defer celeristest.ReleaseContext(ctx)

	_ = ctx.Redirect(301, "/new")
	fmt.Println(rec.StatusCode)
	fmt.Println(rec.Header("location"))
}
Output:
301
/new

func (*Context) RemoteAddr added in v1.1.0

func (c *Context) RemoteAddr() string

RemoteAddr returns the TCP peer address (e.g. "192.168.1.1:54321"). Returns empty string if unavailable.

Example
package main

import (
	"fmt"

	"github.com/goceleris/celeris/celeristest"
)

func main() {
	// RemoteAddr returns empty from celeristest by default.
	ctx, _ := celeristest.NewContext("GET", "/info")
	defer celeristest.ReleaseContext(ctx)
	fmt.Printf("addr=%q\n", ctx.RemoteAddr())
}
Output:
addr=""

func (*Context) RequestHeaders added in v1.1.0

func (c *Context) RequestHeaders() [][2]string

RequestHeaders returns all request headers as key-value pairs. The returned slice is a copy safe for concurrent use.

func (*Context) Respond added in v1.1.0

func (c *Context) Respond(code int, v any) error

Respond writes the response in the format that best matches the Accept header. Supported types: application/json, application/xml, text/plain. Falls back to JSON if no match.

Example
package main

import (
	"encoding/json"
	"fmt"

	"github.com/goceleris/celeris/celeristest"
)

func main() {
	ctx, rec := celeristest.NewContext("GET", "/data",
		celeristest.WithHeader("accept", "application/json"),
	)
	defer celeristest.ReleaseContext(ctx)

	_ = ctx.Respond(200, map[string]string{"key": "value"})
	fmt.Println(rec.Header("content-type"))
	var m map[string]string
	_ = json.Unmarshal(rec.Body, &m)
	fmt.Println(m["key"])
}
Output:
application/json
value

func (*Context) ResponseBody added in v1.1.0

func (c *Context) ResponseBody() []byte

ResponseBody returns the captured response body, or nil if capture was not enabled. Available after Context.CaptureResponse + c.Next(), or after Context.BufferResponse + a response method (JSON, Blob, etc.).

func (*Context) ResponseContentType added in v1.1.0

func (c *Context) ResponseContentType() string

ResponseContentType returns the captured Content-Type, or "" if not captured.

func (*Context) ResponseStatus added in v1.1.0

func (c *Context) ResponseStatus() int

ResponseStatus returns the captured response status code.

func (*Context) Scheme

func (c *Context) Scheme() string

Scheme returns the request scheme ("http" or "https"). It checks the X-Forwarded-Proto header first (set by reverse proxies), then falls back to the :scheme pseudo-header from the original request. Returns "http" if neither source provides a value.

func (*Context) Set

func (c *Context) Set(key string, value any)

Set stores a key-value pair for this request.

func (*Context) SetContext

func (c *Context) SetContext(ctx context.Context)

SetContext sets the request's context. The provided ctx must be non-nil.

func (*Context) SetCookie

func (c *Context) SetCookie(cookie *Cookie)

SetCookie appends a Set-Cookie header to the response. Cookie values are sent as-is without encoding (per RFC 6265). Callers are responsible for encoding values if needed.

func (*Context) SetHeader

func (c *Context) SetHeader(key, value string)

SetHeader sets a response header, replacing any existing value for the key. Keys are lowercased for HTTP/2 compliance (RFC 7540 §8.1.2). CRLF characters are stripped to prevent header injection.

func (*Context) SetPath added in v1.1.0

func (c *Context) SetPath(p string)

SetPath overrides the request path. This is useful in middleware that rewrites URLs (e.g. prefix stripping) before downstream handlers see the path.

func (*Context) SetResponseBody added in v1.1.0

func (c *Context) SetResponseBody(body []byte)

SetResponseBody replaces the buffered response body. Only valid after BufferResponse + c.Next(). Used by transform middleware (compress, etc.).

func (*Context) Status

func (c *Context) Status(code int) *Context

Status sets the response status code and returns the Context for chaining. Note: response methods (JSON, Blob, etc.) take their own status code parameter and do not read the value set by Status.

func (*Context) StatusCode

func (c *Context) StatusCode() int

StatusCode returns the response status code set by the handler.

func (*Context) Stream

func (c *Context) Stream(code int, contentType string, r io.Reader) error

Stream reads all data from r (capped at 100 MB) and writes it as the response with the given status code and content type. Returns HTTPError with status 413 if the data exceeds 100 MB.

func (*Context) StreamWriter added in v1.1.0

func (c *Context) StreamWriter() *StreamWriter

StreamWriter returns a StreamWriter for incremental response writing. Returns nil if the engine does not support streaming. On native engines (epoll, io_uring), the caller must call Context.Detach before spawning a goroutine that uses the StreamWriter. Call Close() when done.

Example
package main

import (
	"fmt"

	"github.com/goceleris/celeris/celeristest"
)

func main() {
	ctx, _ := celeristest.NewContext("GET", "/events")
	defer celeristest.ReleaseContext(ctx)

	// celeristest mock does not implement Streamer, so StreamWriter is nil.
	sw := ctx.StreamWriter()
	fmt.Println(sw == nil)
}
Output:
true

func (*Context) String

func (c *Context) String(code int, format string, args ...any) error

String writes a formatted string response. Returns ErrResponseWritten if a response has already been sent.

func (*Context) XML

func (c *Context) XML(code int, v any) error

XML serializes v as XML and writes it with the given status code. Returns ErrResponseWritten if a response has already been sent.

Example
package main

import (
	"fmt"

	"github.com/goceleris/celeris/celeristest"
)

func main() {
	type Item struct {
		Name string
	}
	ctx, rec := celeristest.NewContext("GET", "/item")
	defer celeristest.ReleaseContext(ctx)

	_ = ctx.XML(200, Item{Name: "widget"})
	fmt.Println(rec.StatusCode)
	fmt.Println(rec.Header("content-type"))
}
Output:
200
application/xml
type Cookie struct {
	// Name is the cookie name.
	Name string
	// Value is the cookie value.
	Value string
	// Path limits the scope of the cookie to the given URL path.
	Path string
	// Domain limits the scope of the cookie to the given domain.
	Domain string
	// MaxAge=0 means no Max-Age attribute is sent. Negative value means
	// delete the cookie (Max-Age=0 in the header).
	MaxAge int
	// Expires sets the Expires attribute for legacy client compatibility
	// (e.g. IE11). Zero value means no Expires is sent. Prefer MaxAge
	// for modern clients.
	Expires time.Time
	// Secure flags the cookie for HTTPS-only transmission.
	Secure bool
	// HTTPOnly prevents client-side scripts from accessing the cookie.
	HTTPOnly bool
	// SameSite controls cross-site request cookie behavior.
	SameSite SameSite
}

Cookie represents an HTTP cookie for use with Context.SetCookie.

type EngineInfo

type EngineInfo struct {
	// Type identifies the active I/O engine (IOUring, Epoll, Adaptive, or Std).
	Type EngineType
	// Metrics is a point-in-time snapshot of engine-level performance counters.
	Metrics EngineMetrics
}

EngineInfo provides read-only information about the running engine.

type EngineMetrics

type EngineMetrics = engine.EngineMetrics

EngineMetrics is a point-in-time snapshot of engine-level performance counters.

type EngineType

type EngineType engine.EngineType

EngineType identifies which I/O engine implementation is in use.

const (
	// Adaptive dynamically switches between Epoll and IOUring based on load (default on Linux).
	Adaptive EngineType = EngineType(engine.Adaptive)
	// Epoll uses Linux edge-triggered epoll for I/O (Linux only).
	Epoll EngineType = EngineType(engine.Epoll)
	// IOUring uses Linux io_uring for asynchronous I/O (Linux 5.10+ required).
	IOUring EngineType = EngineType(engine.IOUring)
	// Std uses Go's net/http standard library server (all platforms).
	Std EngineType = EngineType(engine.Std)
)

func (EngineType) String

func (t EngineType) String() string

String returns the engine type name.

type HTTPError

type HTTPError struct {
	// Code is the HTTP status code (e.g. 400, 404, 500).
	Code int
	// Message is a human-readable error description sent in the response body.
	Message string
	// Err is an optional wrapped error for use with errors.Is / errors.As.
	Err error
}

HTTPError is a structured error that carries an HTTP status code. Handlers return HTTPError to signal a specific status code to the routerAdapter safety net. Use NewHTTPError to create one.

func NewHTTPError

func NewHTTPError(code int, message string) *HTTPError

NewHTTPError creates an HTTPError with the given status code and message. To wrap an existing error, use the WithError method on the returned HTTPError.

Example
package main

import (
	"fmt"

	"github.com/goceleris/celeris"
)

func main() {
	err := celeris.NewHTTPError(404, "user not found")
	fmt.Println(err.Error())
}
Output:
code=404, message=user not found

func (*HTTPError) Error

func (e *HTTPError) Error() string

Error returns a string representation including the status code and message.

func (*HTTPError) Unwrap

func (e *HTTPError) Unwrap() error

Unwrap returns the wrapped error for use with errors.Is and errors.As.

func (*HTTPError) WithError

func (e *HTTPError) WithError(err error) *HTTPError

WithError sets the wrapped error and returns the HTTPError for chaining.

type HandlerFunc

type HandlerFunc func(*Context) error

HandlerFunc defines the handler used by middleware and routes. Returning a non-nil error propagates it up through the middleware chain. The routerAdapter safety net writes an appropriate response for unhandled errors.

func Adapt

func Adapt(h http.Handler) HandlerFunc

Adapt wraps a standard net/http Handler so it can be used as a celeris HandlerFunc. The adapted handler receives a reconstructed *http.Request with headers, body, and context from the celeris Context. Response body is buffered in memory, capped at 100MB.

Example
package main

import (
	"fmt"

	"github.com/goceleris/celeris"
)

func main() {
	_ = celeris.Adapt(nil) // wraps any net/http Handler
	fmt.Println("adapter created")
}
Output:
adapter created

func AdaptFunc

func AdaptFunc(h http.HandlerFunc) HandlerFunc

AdaptFunc wraps a standard net/http handler function. It is a convenience wrapper equivalent to Adapt(http.HandlerFunc(h)).

type Param

type Param struct {
	// Key is the parameter name from the route pattern (e.g. "id" from ":id").
	Key string
	// Value is the matched segment from the request path (e.g. "42").
	Value string
}

Param is a single URL parameter consisting of a key and a value.

type Params

type Params []Param

Params is a slice of Param.

func (Params) Get

func (ps Params) Get(key string) (string, bool)

Get returns the value of the first Param matching the given key. Returns empty string and false if the key is not found.

type Protocol

type Protocol engine.Protocol

Protocol represents the HTTP protocol version.

const (
	// Auto enables automatic protocol detection between HTTP/1.1 and H2C (default).
	Auto Protocol = Protocol(engine.Auto)
	// HTTP1 selects HTTP/1.1 only.
	HTTP1 Protocol = Protocol(engine.HTTP1)
	// H2C selects HTTP/2 cleartext (h2c) only.
	H2C Protocol = Protocol(engine.H2C)
)

func (Protocol) String

func (p Protocol) String() string

String returns the protocol name.

type Route

type Route struct {
	// contains filtered or unexported fields
}

Route is an opaque handle to a registered route. Use the Name method to assign a name for reverse lookup via Server.URL.

func (*Route) Name

func (r *Route) Name(name string) *Route

Name sets a name for this route, enabling reverse URL generation via Server.URL. Panics if a route with the same name is already registered.

func (*Route) TryName

func (r *Route) TryName(name string) error

TryName is like Route.Name but returns an error instead of panicking when a route with the same name already exists.

func (*Route) Use added in v1.1.0

func (r *Route) Use(middleware ...HandlerFunc) *Route

Use prepends middleware to this specific route's handler chain. Must be called before Server.Start. Panics if the route has no handlers.

type RouteGroup

type RouteGroup struct {
	// contains filtered or unexported fields
}

RouteGroup is a collection of routes that share a common path prefix and middleware. Use Server.Group to create one. A RouteGroup must not be used after Server.Start is called.

func (*RouteGroup) Any

func (g *RouteGroup) Any(path string, handlers ...HandlerFunc) *RouteGroup

Any registers a handler for all HTTP methods.

func (*RouteGroup) DELETE

func (g *RouteGroup) DELETE(path string, handlers ...HandlerFunc) *Route

DELETE registers a handler for DELETE requests.

func (*RouteGroup) GET

func (g *RouteGroup) GET(path string, handlers ...HandlerFunc) *Route

GET registers a handler for GET requests.

func (*RouteGroup) Group

func (g *RouteGroup) Group(prefix string, middleware ...HandlerFunc) *RouteGroup

Group creates a sub-group with the given path prefix. The sub-group inherits middleware from the parent group.

func (*RouteGroup) HEAD

func (g *RouteGroup) HEAD(path string, handlers ...HandlerFunc) *Route

HEAD registers a handler for HEAD requests.

func (*RouteGroup) Handle

func (g *RouteGroup) Handle(method, path string, handlers ...HandlerFunc) *Route

Handle registers a handler for the given HTTP method and path pattern.

func (*RouteGroup) OPTIONS

func (g *RouteGroup) OPTIONS(path string, handlers ...HandlerFunc) *Route

OPTIONS registers a handler for OPTIONS requests.

func (*RouteGroup) PATCH

func (g *RouteGroup) PATCH(path string, handlers ...HandlerFunc) *Route

PATCH registers a handler for PATCH requests.

func (*RouteGroup) POST

func (g *RouteGroup) POST(path string, handlers ...HandlerFunc) *Route

POST registers a handler for POST requests.

func (*RouteGroup) PUT

func (g *RouteGroup) PUT(path string, handlers ...HandlerFunc) *Route

PUT registers a handler for PUT requests.

func (*RouteGroup) Static added in v1.1.0

func (g *RouteGroup) Static(prefix, root string) *Route

Static registers a GET handler that serves files from root under the given prefix. Uses FileFromDir for path traversal protection.

func (*RouteGroup) Use

func (g *RouteGroup) Use(middleware ...HandlerFunc) *RouteGroup

Use adds middleware to this group. Group middleware runs after server-level middleware but before route handlers within this group. Middleware chains are composed at route registration time, so Use must be called before registering routes on this group.

type RouteInfo

type RouteInfo struct {
	// Method is the HTTP method (e.g. "GET", "POST").
	Method string
	// Path is the route pattern (e.g. "/users/:id").
	Path string
	// HandlerCount is the total number of handlers (middleware + handler) in the chain.
	HandlerCount int
}

RouteInfo describes a registered route. Returned by Server.Routes.

type SameSite

type SameSite int

SameSite controls the SameSite attribute of a cookie.

const (
	// SameSiteDefaultMode leaves the SameSite attribute unset (browser default).
	SameSiteDefaultMode SameSite = iota
	// SameSiteLaxMode sets SameSite=Lax (cookies sent with top-level navigations).
	SameSiteLaxMode
	// SameSiteStrictMode sets SameSite=Strict (cookies sent only in first-party context).
	SameSiteStrictMode
	// SameSiteNoneMode sets SameSite=None (requires Secure; cookies sent in all contexts).
	SameSiteNoneMode
)

func (SameSite) String

func (s SameSite) String() string

String returns the SameSite attribute value ("Lax", "Strict", "None", or "").

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server is the top-level entry point for a celeris HTTP server. A Server is safe for concurrent use after Start is called. Route registration methods (GET, POST, Use, Group, etc.) must be called before Start.

func New

func New(cfg Config) *Server

New creates a Server with the given configuration.

func (*Server) Addr

func (s *Server) Addr() net.Addr

Addr returns the listener's bound address, or nil if the server has not been started. Useful when listening on ":0" to discover the OS-assigned port.

func (*Server) Any

func (s *Server) Any(path string, handlers ...HandlerFunc) *Server

Any registers a handler for all HTTP methods.

func (*Server) Collector

func (s *Server) Collector() *observe.Collector

Collector returns the metrics collector, or nil if the server has not been started or if Config.DisableMetrics is true.

func (*Server) DELETE

func (s *Server) DELETE(path string, handlers ...HandlerFunc) *Route

DELETE registers a handler for DELETE requests.

func (*Server) EngineInfo

func (s *Server) EngineInfo() *EngineInfo

EngineInfo returns information about the running engine, or nil if not started.

func (*Server) GET

func (s *Server) GET(path string, handlers ...HandlerFunc) *Route

GET registers a handler for GET requests.

func (*Server) Group

func (s *Server) Group(prefix string, middleware ...HandlerFunc) *RouteGroup

Group creates a new route group with the given prefix and middleware. Middleware provided here runs after server-level middleware but before route handlers.

Example
package main

import (
	"fmt"

	"github.com/goceleris/celeris"
)

func main() {
	s := celeris.New(celeris.Config{Addr: ":8080"})
	api := s.Group("/api")
	api.GET("/users", func(_ *celeris.Context) error { return nil })
	api.GET("/posts", func(_ *celeris.Context) error { return nil })
	fmt.Println("group registered")
}
Output:
group registered

func (*Server) HEAD

func (s *Server) HEAD(path string, handlers ...HandlerFunc) *Route

HEAD registers a handler for HEAD requests.

func (*Server) Handle

func (s *Server) Handle(method, path string, handlers ...HandlerFunc) *Route

Handle registers a handler for the given HTTP method and path pattern. Use this for non-standard methods (e.g., WebDAV PROPFIND) or when the method is determined at runtime.

func (*Server) MethodNotAllowed

func (s *Server) MethodNotAllowed(handler HandlerFunc) *Server

MethodNotAllowed registers a custom handler for requests where the path matches but the HTTP method does not. The Allow header is set automatically.

func (*Server) NotFound

func (s *Server) NotFound(handler HandlerFunc) *Server

NotFound registers a custom handler for requests that do not match any route.

Example
package main

import (
	"fmt"

	"github.com/goceleris/celeris"
)

func main() {
	s := celeris.New(celeris.Config{Addr: ":8080"})
	s.NotFound(func(c *celeris.Context) error {
		return c.JSON(404, map[string]string{"error": "not found"})
	})
	fmt.Println("custom 404 set")
}
Output:
custom 404 set

func (*Server) OPTIONS

func (s *Server) OPTIONS(path string, handlers ...HandlerFunc) *Route

OPTIONS registers a handler for OPTIONS requests.

func (*Server) PATCH

func (s *Server) PATCH(path string, handlers ...HandlerFunc) *Route

PATCH registers a handler for PATCH requests.

func (*Server) POST

func (s *Server) POST(path string, handlers ...HandlerFunc) *Route

POST registers a handler for POST requests.

func (*Server) PUT

func (s *Server) PUT(path string, handlers ...HandlerFunc) *Route

PUT registers a handler for PUT requests.

func (*Server) Routes

func (s *Server) Routes() []RouteInfo

Routes returns information about all registered routes. Output is sorted by method, then path for deterministic results.

Example
package main

import (
	"fmt"

	"github.com/goceleris/celeris"
)

func main() {
	s := celeris.New(celeris.Config{Addr: ":8080"})
	s.GET("/a", func(_ *celeris.Context) error { return nil })
	s.POST("/b", func(_ *celeris.Context) error { return nil })
	routes := s.Routes()
	fmt.Println(len(routes))
}
Output:
2

func (*Server) Shutdown

func (s *Server) Shutdown(ctx context.Context) error

Shutdown gracefully shuts down the server. Returns nil if the server has not been started.

func (*Server) Start

func (s *Server) Start() error

Start initializes and starts the server, blocking until Shutdown is called or the engine returns an error. Use StartWithContext for context-based lifecycle management.

Returns ErrAlreadyStarted if called more than once. May also return configuration validation errors or engine initialization errors.

func (*Server) StartWithContext

func (s *Server) StartWithContext(ctx context.Context) error

StartWithContext starts the server with the given context for lifecycle management. When the context is canceled, the server shuts down gracefully using Config.ShutdownTimeout (default 30s).

Returns ErrAlreadyStarted if called more than once. May also return configuration validation errors or engine initialization errors.

Example
package main

import (
	"context"
	"fmt"
	"os"
	"os/signal"

	"github.com/goceleris/celeris"
)

func main() {
	ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
	defer stop()

	_ = ctx // prevent unused error
	s := celeris.New(celeris.Config{Addr: ":8080"})
	s.GET("/ping", func(c *celeris.Context) error {
		return c.String(200, "pong")
	})
	// In a real app: log.Fatal(s.StartWithContext(ctx))
	fmt.Println("configured")
}
Output:
configured

func (*Server) StartWithListener added in v1.1.0

func (s *Server) StartWithListener(ln net.Listener) error

StartWithListener starts the server using an existing net.Listener. This enables zero-downtime restarts via socket inheritance (e.g., passing the listener FD to a child process via environment variable).

Returns ErrAlreadyStarted if called more than once.

func (*Server) StartWithListenerAndContext added in v1.1.0

func (s *Server) StartWithListenerAndContext(ctx context.Context, ln net.Listener) error

StartWithListenerAndContext combines Server.StartWithListener and Server.StartWithContext. When the context is canceled, the server shuts down gracefully using [Config.ShutdownTimeout].

func (*Server) Static added in v1.1.0

func (s *Server) Static(prefix, root string) *Route

Static registers a GET handler that serves files from root under the given prefix. Uses FileFromDir for path traversal protection.

s.Static("/assets", "./public")
Example
package main

import (
	"fmt"

	"github.com/goceleris/celeris"
)

func main() {
	s := celeris.New(celeris.Config{Addr: ":8080"})
	s.Static("/assets", "./public")
	routes := s.Routes()
	fmt.Println(routes[0].Method, routes[0].Path)
}
Output:
GET /assets/*filepath

func (*Server) URL

func (s *Server) URL(name string, params ...string) (string, error)

URL generates a URL for the named route by substituting positional parameters. Parameter values are substituted in order for :param segments. For *catchAll segments, the value replaces the wildcard (a leading "/" is de-duplicated). Values are inserted as-is without URL encoding — callers should encode if needed. Returns ErrRouteNotFound if no route with the given name exists.

Example
package main

import (
	"fmt"

	"github.com/goceleris/celeris"
)

func main() {
	s := celeris.New(celeris.Config{Addr: ":8080"})
	s.GET("/users/:id", func(_ *celeris.Context) error { return nil }).Name("user")
	url, err := s.URL("user", "42")
	fmt.Println(url, err)
}
Output:
/users/42 <nil>

func (*Server) URLMap

func (s *Server) URLMap(name string, params map[string]string) (string, error)

URLMap generates a URL for the named route by substituting named parameters from a map. This is an alternative to Server.URL that avoids positional ordering errors. Returns ErrRouteNotFound if no route with the given name has been registered.

func (*Server) Use

func (s *Server) Use(middleware ...HandlerFunc) *Server

Use registers global middleware that runs before every route handler. Middleware executes in registration order. Middleware chains are composed at route registration time, so Use must be called before registering routes.

Example
package main

import (
	"fmt"

	"github.com/goceleris/celeris"
)

func main() {
	s := celeris.New(celeris.Config{Addr: ":8080"})
	s.Use(func(c *celeris.Context) error {
		fmt.Println("middleware executed")
		return c.Next()
	})
	s.GET("/", func(c *celeris.Context) error {
		return c.String(200, "ok")
	})
	fmt.Println("middleware registered")
}
Output:
middleware registered

type StreamWriter added in v1.1.0

type StreamWriter struct {
	// contains filtered or unexported fields
}

StreamWriter provides incremental response writing. Obtained via Context.StreamWriter.

func (*StreamWriter) Close added in v1.1.0

func (sw *StreamWriter) Close() error

Close signals end of the response body.

func (*StreamWriter) Flush added in v1.1.0

func (sw *StreamWriter) Flush() error

Flush ensures buffered data is sent to the network.

func (*StreamWriter) Write added in v1.1.0

func (sw *StreamWriter) Write(data []byte) (int, error)

Write sends a chunk of the response body. May be called multiple times.

func (*StreamWriter) WriteHeader added in v1.1.0

func (sw *StreamWriter) WriteHeader(status int, headers [][2]string) error

WriteHeader sends the status line and headers. Must be called once before Write.

Directories

Path Synopsis
Package adaptive implements a dual-engine controller that dynamically switches between io_uring and epoll based on runtime telemetry.
Package adaptive implements a dual-engine controller that dynamically switches between io_uring and epoll based on runtime telemetry.
Package celeristest provides test utilities for celeris handlers.
Package celeristest provides test utilities for celeris handlers.
Package engine defines the core Engine interface and associated types used by all I/O engine implementations (io_uring, epoll, adaptive, std).
Package engine defines the core Engine interface and associated types used by all I/O engine implementations (io_uring, epoll, adaptive, std).
epoll
Package epoll implements the epoll-based I/O engine for Linux.
Package epoll implements the epoll-based I/O engine for Linux.
iouring
Package iouring implements an engine backed by Linux io_uring.
Package iouring implements an engine backed by Linux io_uring.
std
Package std provides an engine implementation backed by net/http.
Package std provides an engine implementation backed by net/http.
Package internal contains shared utilities.
Package internal contains shared utilities.
conn
Package conn provides shared HTTP/1.1 and HTTP/2 connection handling.
Package conn provides shared HTTP/1.1 and HTTP/2 connection handling.
cpumon
Package cpumon provides CPU utilization monitoring with platform-specific implementations.
Package cpumon provides CPU utilization monitoring with platform-specific implementations.
ctxkit
Package ctxkit provides internal hooks for creating and releasing celeris contexts from the celeristest package without exposing implementation types in the public API.
Package ctxkit provides internal hooks for creating and releasing celeris contexts from the celeristest package without exposing implementation types in the public API.
negotiate
Package negotiate provides HTTP content negotiation utilities.
Package negotiate provides HTTP content negotiation utilities.
platform
Package platform provides OS-level helpers for CPU pinning and NUMA distribution.
Package platform provides OS-level helpers for CPU pinning and NUMA distribution.
sockopts
Package sockopts provides socket option helpers for TCP tuning across platforms.
Package sockopts provides socket option helpers for TCP tuning across platforms.
timer
Package timer implements a hierarchical timer wheel for efficient timeout management in event-driven I/O engines.
Package timer implements a hierarchical timer wheel for efficient timeout management in event-driven I/O engines.
middleware
compress module
metrics module
otel module
Package observe provides lightweight, lock-free metrics collection for celeris servers.
Package observe provides lightweight, lock-free metrics collection for celeris servers.
Package probe provides capability detection for io_uring and epoll.
Package probe provides capability detection for io_uring and epoll.
protocol
detect
Package detect provides HTTP protocol detection from initial connection bytes.
Package detect provides HTTP protocol detection from initial connection bytes.
h1
Package h1 implements a zero-copy HTTP/1.1 parser.
Package h1 implements a zero-copy HTTP/1.1 parser.
h2
Package h2 provides HTTP/2 frame handling and stream management.
Package h2 provides HTTP/2 frame handling and stream management.
h2/frame
Package frame provides HTTP/2 frame type definitions, parsing, writing, and HPACK integration.
Package frame provides HTTP/2 frame type definitions, parsing, writing, and HPACK integration.
h2/stream
Package stream manages HTTP/2 stream lifecycle, state transitions, flow control, and frame processing.
Package stream manages HTTP/2 stream lifecycle, state transitions, flow control, and frame processing.
Package resource defines server configuration, resource limits, and default presets.
Package resource defines server configuration, resource limits, and default presets.
test
benchmark/framework command
Package main runs a standalone celeris.Server for external benchmarking with wrk, hey, or other load generators.
Package main runs a standalone celeris.Server for external benchmarking with wrk, hey, or other load generators.
benchmark/profiled command
Package main runs a celeris framework server with pprof profiling enabled.
Package main runs a celeris framework server with pprof profiling enabled.
benchmark/server command
Package main runs a standalone celeris server for external benchmarking with wrk, hey, or other load generators.
Package main runs a standalone celeris server for external benchmarking with wrk, hey, or other load generators.
iouring-probe command
Minimal io_uring probe that tests every flag combination to find what works.
Minimal io_uring probe that tests every flag combination to find what works.
loadtest command
Package main runs load tests against all celeris engine configurations.
Package main runs load tests against all celeris engine configurations.
loadtest/fullstack command
Package main runs full-stack load tests through the celeris.Server application layer (router, Context, JSON encoding, response writing) across all engine configs.
Package main runs full-stack load tests through the celeris.Server application layer (router, Context, JSON encoding, response writing) across all engine configs.
loadtest/rawtcp command
Package main runs a raw TCP load test against celeris.Server to measure server-side performance without Go HTTP client overhead.
Package main runs a raw TCP load test against celeris.Server to measure server-side performance without Go HTTP client overhead.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL