celeris

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Mar 12, 2026 License: Apache-2.0 Imports: 30 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.

Features

  • Tiered io_uring — auto-selects the best io_uring feature set (multishot accept, provided buffers, SQ poll) 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
  • Overload manager — 5-stage degradation ladder (expand, reap, reorder, backpressure, reject)
  • SIMD HTTP parser — SSE2 (amd64) and NEON (arm64) with generic SWAR fallback
  • HTTP/2 cleartext (h2c) — full stream multiplexing, flow control, HPACK
  • 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()

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["overload"]:1 D["observe"]:1
  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

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
Overload shedding yes yes partial

Benchmarks

Framework overhead on 8 vCPU (arm64 c6g.2xlarge, x86 c5a.2xlarge):

  • <1.5% overhead vs raw engine (balanced mode)
  • All 3 engines within 0.3% of each other (adaptive fully matches dedicated)
  • Beats Fiber by +1.4-2.1% (arm64), +0.7-1.3% (x86)
  • Beats echo/chi/gin/iris by 5-6%
  • H2 overhead: 1.5% vs Go frameworks' 16.6% (11x smaller)

Methodology: 27 server configurations (3 engines x 3 objectives x 3 protocols) tested with wrk2 at fixed request rates. Full results and reproduction scripts are in the benchmarks repo.

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)
overload/       Overload manager with 5-stage degradation
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
mage lint    # run linters
mage bench   # run benchmarks

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"

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.

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.Objective selects a tuning profile:

celeris.Latency     // Optimize for minimum response time
celeris.Throughput  // Optimize for maximum requests per second
celeris.Balanced    // Balance between latency and throughput (default)

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.

Streaming

Stream an io.Reader as the response body (capped at 100 MB):

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

All response methods currently buffer the full body before sending. True incremental streaming (e.g. Server-Sent Events) is planned for a future release. The current API is forward-compatible.

Cookies

Read and write cookies:

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

Authentication

Extract HTTP Basic Authentication credentials:

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

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() // e.g. 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 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

This section is empty.

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 HTTP1).
	Protocol Protocol
	// Engine is the I/O engine (default Std; IOUring, Epoll, Adaptive require Linux).
	Engine EngineType

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

	// ReadTimeout is the max duration for reading the entire request (zero = no timeout).
	ReadTimeout time.Duration
	// WriteTimeout is the max duration for writing the response (zero = no timeout).
	WriteTimeout time.Duration
	// IdleTimeout is the max duration a keep-alive connection may be idle (zero = 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

	// 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

	// 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) 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) 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.

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.

func (*Context) BindJSON

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

BindJSON deserializes the JSON request body into v.

func (*Context) BindXML

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

BindXML deserializes the XML request body into v.

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.

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) 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.

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).

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

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) FormFile

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

FormFile returns the first file for the named form field. Returns an error 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).

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.

func (*Context) IsAborted

func (c *Context) IsAborted() bool

IsAborted returns true if the handler chain was aborted.

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.

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 an error if the request is not multipart.

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.

func (*Context) Param

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

Param returns the value of a URL parameter by name.

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.

func (*Context) QueryDefault

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

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

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) Redirect

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

Redirect sends an HTTP redirect to the given URL with the specified 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.

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) Status

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

Status sets the response status code and returns the Context for chaining.

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.

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.

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
	// 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 (
	// IOUring uses Linux io_uring for asynchronous I/O (Linux 5.10+ required).
	IOUring EngineType = EngineType(engine.IOUring)
	// Epoll uses Linux edge-triggered epoll for I/O (Linux only).
	Epoll EngineType = EngineType(engine.Epoll)
	// Adaptive dynamically switches between IOUring and Epoll based on load (Linux only).
	Adaptive EngineType = EngineType(engine.Adaptive)
	// 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 Objective

type Objective resource.ObjectiveProfile

Objective selects a tuning profile that controls I/O and networking parameters.

const (
	// Balanced targets a balance between latency and throughput (default).
	Balanced Objective = Objective(resource.BalancedObjective)
	// Latency optimizes for minimum response latency.
	Latency Objective = Objective(resource.LatencyOptimized)
	// Throughput optimizes for maximum requests per second.
	Throughput Objective = Objective(resource.ThroughputOptimized)
)

func (Objective) String

func (o Objective) String() string

String returns the objective name.

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 (
	// HTTP1 selects HTTP/1.1 only.
	HTTP1 Protocol = Protocol(engine.HTTP1)
	// H2C selects HTTP/2 cleartext (h2c) only.
	H2C Protocol = Protocol(engine.H2C)
	// Auto enables automatic protocol detection between HTTP/1.1 and H2C.
	Auto Protocol = Protocol(engine.Auto)
)

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.

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) 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.

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.

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.

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

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 types.
Package engine defines the core Engine interface and types.
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.
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.
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 overload implements a 5-stage degradation ladder for backpressure and load shedding.
Package overload implements a 5-stage degradation ladder for backpressure and load shedding.
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 configuration presets and performance profiles.
Package resource defines configuration presets and performance profiles.
test

Jump to

Keyboard shortcuts

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