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 in-tree middleware/ packages (e.g. middleware/logger, middleware/recovery). Use Server.Use to register middleware globally or per route group.
import (
"github.com/goceleris/celeris/middleware/logger"
"github.com/goceleris/celeris/middleware/recovery"
)
s.Use(logger.New(), recovery.New())
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 {
err := c.Next()
elapsed := time.Since(c.StartTime())
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
})
Global Error Handler ¶
Register a global error handler with Server.OnError. This is called when an unhandled error reaches the safety net after all middleware has had its chance. Use it to render structured error responses (e.g. JSON) instead of the default text/plain fallback:
s.OnError(func(c *celeris.Context, err error) {
var he *celeris.HTTPError
code := 500
msg := "internal server error"
if errors.As(err, &he) {
code = he.Code
msg = he.Message
}
c.JSON(code, map[string]string{"error": msg})
})
If the handler does not write a response, the default text/plain fallback applies. OnError must be called before Start.
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 middleware/metrics and middleware/debug packages.
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 ¶
- Constants
- Variables
- func AddTestParam(c *Context, key, value string)
- func EscapeQuotedString(s string) string
- func InheritListener(envVar string) (net.Listener, error)
- func ReleaseTestContext(c *Context)
- func SetTestFullPath(c *Context, path string)
- func SetTestHandlers(c *Context, handlers []HandlerFunc)
- func SetTestScheme(c *Context, scheme string)
- func SetTestStartTime(c *Context, t time.Time)
- func SetTestTrustedNets(c *Context, nets []*net.IPNet)
- func TestStream(c *Context) *stream.Stream
- func ToHandler(h HandlerFunc) http.Handler
- type Config
- type Context
- func (c *Context) Abort()
- func (c *Context) AbortWithStatus(code int) error
- func (c *Context) AcceptsEncodings(offers ...string) string
- func (c *Context) AcceptsLanguages(offers ...string) string
- func (c *Context) AddHeader(key, value string)
- func (c *Context) Attachment(filename string)
- func (c *Context) BasicAuth() (username, password string, ok bool)
- func (c *Context) Bind(v any) error
- func (c *Context) BindJSON(v any) error
- func (c *Context) BindXML(v any) error
- func (c *Context) Blob(code int, contentType string, data []byte) error
- func (c *Context) Body() []byte
- func (c *Context) BodyCopy() []byte
- func (c *Context) BodyReader() io.Reader
- func (c *Context) BufferResponse()
- func (c *Context) BytesWritten() int
- func (c *Context) CaptureResponse()
- func (c *Context) ClientIP() string
- func (c *Context) ContentLength() int64
- func (c *Context) Context() context.Context
- func (c *Context) Cookie(name string) (string, error)
- func (c *Context) DeleteCookie(name, path string)
- func (c *Context) Detach() (done func())
- func (c *Context) DiscardBufferedResponse()
- func (c *Context) File(filePath string) error
- func (c *Context) FileFromDir(baseDir, userPath string) error
- func (c *Context) FileFromFS(name string, fsys fs.FS) error
- func (c *Context) FlushResponse() error
- func (c *Context) FormFile(name string) (multipart.File, *multipart.FileHeader, error)
- func (c *Context) FormValue(name string) string
- func (c *Context) FormValueOK(name string) (string, bool)
- func (c *Context) FormValueOk(name string) (string, bool)deprecated
- func (c *Context) FormValues(name string) []string
- func (c *Context) FullPath() string
- func (c *Context) Get(key string) (any, bool)
- func (c *Context) HTML(code int, html string) error
- func (c *Context) Header(key string) string
- func (c *Context) Hijack() (net.Conn, error)
- func (c *Context) Host() string
- func (c *Context) Inline(filename string)
- func (c *Context) IsAborted() bool
- func (c *Context) IsTLS() bool
- func (c *Context) IsWebSocket() bool
- func (c *Context) IsWritten() bool
- func (c *Context) JSON(code int, v any) error
- func (c *Context) Keys() map[string]any
- func (c *Context) Method() string
- func (c *Context) MultipartForm() (*multipart.Form, error)
- func (c *Context) Negotiate(offers ...string) string
- func (c *Context) Next() error
- func (c *Context) NoContent(code int) error
- func (c *Context) OnRelease(fn func())
- func (c *Context) Param(key string) string
- func (c *Context) ParamDefault(key, defaultValue string) string
- func (c *Context) ParamInt(key string) (int, error)
- func (c *Context) ParamInt64(key string) (int64, error)
- func (c *Context) Path() string
- func (c *Context) Protocol() string
- func (c *Context) Query(key string) string
- func (c *Context) QueryBool(key string, defaultValue bool) bool
- func (c *Context) QueryDefault(key, defaultValue string) string
- func (c *Context) QueryInt(key string, defaultValue int) int
- func (c *Context) QueryInt64(key string, defaultValue int64) int64
- func (c *Context) QueryParams() url.Values
- func (c *Context) QueryValues(key string) []string
- func (c *Context) RawQuery() string
- func (c *Context) Redirect(code int, url string) error
- func (c *Context) RemoteAddr() string
- func (c *Context) RequestHeaders() [][2]string
- func (c *Context) Respond(code int, v any) error
- func (c *Context) ResponseBody() []byte
- func (c *Context) ResponseContentType() string
- func (c *Context) ResponseHeaders() [][2]string
- func (c *Context) ResponseStatus() int
- func (c *Context) Scheme() string
- func (c *Context) Set(key string, value any)
- func (c *Context) SetClientIP(ip string)
- func (c *Context) SetContext(ctx context.Context)
- func (c *Context) SetCookie(cookie *Cookie)
- func (c *Context) SetHeader(key, value string)
- func (c *Context) SetHost(host string)
- func (c *Context) SetMethod(m string)
- func (c *Context) SetPath(p string)
- func (c *Context) SetRawQuery(q string)
- func (c *Context) SetResponseBody(body []byte)
- func (c *Context) SetResponseHeaders(headers [][2]string)
- func (c *Context) SetScheme(scheme string)
- func (c *Context) StartTime() time.Time
- func (c *Context) Status(code int) *Context
- func (c *Context) StatusBlob(contentType string, data []byte) error
- func (c *Context) StatusCode() int
- func (c *Context) StatusJSON(v any) error
- func (c *Context) StatusString(s string) error
- func (c *Context) StatusXML(v any) error
- func (c *Context) Stream(code int, contentType string, r io.Reader) error
- func (c *Context) StreamWriter() *StreamWriter
- func (c *Context) String(code int, format string, args ...any) error
- func (c *Context) XML(code int, v any) error
- type Cookie
- type EngineInfo
- type EngineMetrics
- type EngineType
- type HTTPError
- type HandlerFunc
- type Param
- type Params
- type Protocol
- type Route
- type RouteGroup
- func (g *RouteGroup) Any(path string, handlers ...HandlerFunc) []*Route
- func (g *RouteGroup) DELETE(path string, handlers ...HandlerFunc) *Route
- func (g *RouteGroup) GET(path string, handlers ...HandlerFunc) *Route
- func (g *RouteGroup) Group(prefix string, middleware ...HandlerFunc) *RouteGroup
- func (g *RouteGroup) HEAD(path string, handlers ...HandlerFunc) *Route
- func (g *RouteGroup) Handle(method, path string, handlers ...HandlerFunc) *Route
- func (g *RouteGroup) OPTIONS(path string, handlers ...HandlerFunc) *Route
- func (g *RouteGroup) PATCH(path string, handlers ...HandlerFunc) *Route
- func (g *RouteGroup) POST(path string, handlers ...HandlerFunc) *Route
- func (g *RouteGroup) PUT(path string, handlers ...HandlerFunc) *Route
- func (g *RouteGroup) Static(prefix, root string) *Route
- func (g *RouteGroup) Use(middleware ...HandlerFunc) *RouteGroup
- type RouteInfo
- type SameSite
- type Server
- func (s *Server) Addr() net.Addr
- func (s *Server) Any(path string, handlers ...HandlerFunc) []*Route
- func (s *Server) Collector() *observe.Collector
- func (s *Server) DELETE(path string, handlers ...HandlerFunc) *Route
- func (s *Server) EngineInfo() *EngineInfo
- func (s *Server) GET(path string, handlers ...HandlerFunc) *Route
- func (s *Server) Group(prefix string, middleware ...HandlerFunc) *RouteGroup
- func (s *Server) HEAD(path string, handlers ...HandlerFunc) *Route
- func (s *Server) Handle(method, path string, handlers ...HandlerFunc) *Route
- func (s *Server) MethodNotAllowed(handler HandlerFunc) *Server
- func (s *Server) NotFound(handler HandlerFunc) *Server
- func (s *Server) OPTIONS(path string, handlers ...HandlerFunc) *Route
- func (s *Server) OnError(handler func(c *Context, err error)) *Server
- func (s *Server) OnShutdown(fn func(ctx context.Context)) *Server
- func (s *Server) PATCH(path string, handlers ...HandlerFunc) *Route
- func (s *Server) POST(path string, handlers ...HandlerFunc) *Route
- func (s *Server) PUT(path string, handlers ...HandlerFunc) *Route
- func (s *Server) PauseAccept() error
- func (s *Server) Pre(middleware ...HandlerFunc) *Server
- func (s *Server) ResumeAccept() error
- func (s *Server) Routes() []RouteInfo
- func (s *Server) Shutdown(ctx context.Context) error
- func (s *Server) Start() error
- func (s *Server) StartWithContext(ctx context.Context) error
- func (s *Server) StartWithListener(ln net.Listener) error
- func (s *Server) StartWithListenerAndContext(ctx context.Context, ln net.Listener) error
- func (s *Server) Static(prefix, root string) *Route
- func (s *Server) URL(name string, params ...string) (string, error)
- func (s *Server) URLMap(name string, params map[string]string) (string, error)
- func (s *Server) Use(middleware ...HandlerFunc) *Server
- type SkipHelper
- type StreamWriter
Examples ¶
- Package
- Adapt
- Context.AcceptsEncodings
- Context.Attachment
- Context.BasicAuth
- Context.Bind
- Context.BufferResponse
- Context.Cookie
- Context.File
- Context.FormValue
- Context.Hijack
- Context.IsWebSocket
- Context.JSON
- Context.Negotiate
- Context.Param
- Context.Query
- Context.Redirect
- Context.RemoteAddr
- Context.Respond
- Context.StreamWriter
- Context.XML
- NewHTTPError
- Server.Group
- Server.NotFound
- Server.Routes
- Server.StartWithContext
- Server.Static
- Server.URL
- Server.Use
Constants ¶
const DefaultMaxFormSize int64 = 32 << 20
DefaultMaxFormSize is the default maximum memory used for multipart form parsing (32 MB), matching net/http.
const RequestIDKey = "request_id"
RequestIDKey is the canonical context store key for the request ID. Middleware that generates or reads request IDs should use this key with Context.Set and Context.Get for interoperability.
const Version = "1.2.0"
Version is the semantic version of the celeris module.
Variables ¶
var ErrAcceptControlNotSupported = errors.New("celeris: engine does not support accept control")
ErrAcceptControlNotSupported is returned by PauseAccept/ResumeAccept when the active engine does not implement accept control (e.g. std engine).
var ErrAlreadyStarted = errors.New("celeris: server already started")
ErrAlreadyStarted is returned when Start or StartWithContext is called on a server that is already running.
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.
var ErrEmptyBody = errors.New("celeris: empty request body")
ErrEmptyBody is returned by Bind, BindJSON, and BindXML when the request body is empty.
var ErrHijackNotSupported = stream.ErrHijackNotSupported
ErrHijackNotSupported is returned by Hijack when the connection does not support takeover (e.g. HTTP/2 multiplexed streams).
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.
var ErrNoCookie = errors.New("celeris: named cookie not present")
ErrNoCookie is returned by Context.Cookie when the named cookie is not present.
var ErrResponseWritten = errors.New("celeris: response already written")
ErrResponseWritten is returned when a response method is called after a response has already been written.
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 AddTestParam ¶ added in v1.3.0
AddTestParam appends a route parameter to a test context.
func EscapeQuotedString ¶ added in v1.2.4
EscapeQuotedString escapes backslash and double-quote characters for use in RFC 7230 quoted-string header values.
func InheritListener ¶ added in v1.1.0
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 ReleaseTestContext ¶ added in v1.3.0
func ReleaseTestContext(c *Context)
ReleaseTestContext returns a Context to the pool, firing OnRelease callbacks. This is intended for test helpers only; production code uses releaseContext.
func SetTestFullPath ¶ added in v1.3.0
SetTestFullPath sets the full path on a test context.
func SetTestHandlers ¶ added in v1.3.0
func SetTestHandlers(c *Context, handlers []HandlerFunc)
SetTestHandlers installs a handler chain on a test context, using the inline handlerBuf when the chain is small enough.
func SetTestScheme ¶ added in v1.3.1
SetTestScheme sets the scheme override on a test context.
func SetTestStartTime ¶ added in v1.3.0
SetTestStartTime sets the start time on a test context.
func SetTestTrustedNets ¶ added in v1.3.0
SetTestTrustedNets sets the trusted proxy networks on a test context.
func TestStream ¶ added in v1.3.0
TestStream returns the underlying stream, or nil. Test helpers only.
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
// MaxRequestBodySize is the maximum allowed request body size in bytes
// across all protocols (H1, H2, bridge). 0 uses the default (100 MB).
// Set to -1 to disable the limit (unlimited).
MaxRequestBodySize 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
// OnExpectContinue is called when an H1 request contains "Expect: 100-continue".
// If the callback returns false, the server responds with 417 Expectation Failed
// and skips reading the body. If nil, the server always sends 100 Continue.
OnExpectContinue func(method, path string, headers [][2]string) 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)
// TrustedProxies is a list of trusted proxy CIDR ranges (e.g., "10.0.0.0/8",
// "172.16.0.0/12", "192.168.0.0/16"). When set, ClientIP() only trusts
// X-Forwarded-For hops from these networks. When empty, ClientIP() trusts
// all proxy headers (legacy behavior).
TrustedProxies []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 AcquireTestContext ¶ added in v1.3.0
AcquireTestContext returns a Context from the pool, bound to the given Stream. This is intended for test helpers only; production code uses HandleStream.
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 ¶
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
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
AcceptsLanguages returns the best matching language from the Accept-Language header, or empty string if none match.
func (*Context) AddHeader ¶
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
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 ¶
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 ¶
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 ¶
BindJSON deserializes the JSON request body into v. Returns ErrEmptyBody if the body is empty.
func (*Context) BindXML ¶
BindXML deserializes the XML request body into v. Returns ErrEmptyBody if the body is empty.
func (*Context) Blob ¶
Blob writes a response with the given content type and data. Returns ErrResponseWritten if a response has already been sent.
func (*Context) Body ¶
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
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
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
BytesWritten returns the response body size in bytes, or 0 if no response was written. For NoContent responses, returns 0. For streamed responses (via StreamWriter), returns the total bytes written so far (may increase while streaming is in progress).
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 ¶
ClientIP extracts the client IP. If SetClientIP has been called, the override value is returned. When [Config.TrustedProxies] is configured, the X-Forwarded-For chain is walked right-to-left and entries from trusted networks are skipped; the first untrusted IP is returned. When TrustedProxies is empty (default), the leftmost XFF entry is returned (legacy behavior). Falls back to X-Real-Ip, then empty string.
func (*Context) ContentLength ¶ added in v1.2.0
ContentLength returns the value of the Content-Length request header parsed as int64. Returns -1 if the header is absent or invalid.
func (*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 ¶
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) DeleteCookie ¶ added in v1.2.0
DeleteCookie appends a Set-Cookie header that instructs the client to delete the named cookie. The path must match the original cookie's path.
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) DiscardBufferedResponse ¶ added in v1.2.3
func (c *Context) DiscardBufferedResponse()
DiscardBufferedResponse decrements the buffer depth and clears any captured response data without writing to the wire. Used by timeout middleware to discard a stale buffered response before writing an error response.
func (*Context) File ¶
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 ¶
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. Symlinks are resolved and rechecked to prevent a symlink under baseDir from escaping the directory boundary.
func (*Context) FileFromFS ¶ added in v1.3.0
FileFromFS serves a named file from an fs.FS (e.g. embed.FS). The content type is detected from the file extension. The entire file is loaded into memory (capped at 100 MB). Returns HTTPError with status 413 if the file exceeds this limit.
Security: name is passed directly to fsys.Open — callers MUST sanitize user-supplied paths to prevent directory traversal. For untrusted input, use Context.FileFromDir instead.
func (*Context) FlushResponse ¶ added in v1.1.0
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 ¶
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 ¶
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 ¶ added in v1.2.2
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) FormValueOk
deprecated
FormValueOk is a deprecated alias for Context.FormValueOK.
Deprecated: Use Context.FormValueOK instead.
func (*Context) FormValues ¶
FormValues returns all values for the named form field.
func (*Context) FullPath ¶
FullPath returns the matched route pattern (e.g. "/users/:id"). Returns empty string if no route was matched.
func (*Context) HTML ¶
HTML writes an HTML response with the given status code. Returns ErrResponseWritten if a response has already been sent.
func (*Context) Header ¶
Header returns the value of the named request header. Keys are normalized to lowercase automatically (HTTP/2 mandates lowercase; the H1 parser normalizes to lowercase).
func (*Context) Hijack ¶ added in v1.1.0
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
Host returns the request host from the :authority pseudo-header (HTTP/2) or the Host header (HTTP/1.1). If SetHost has been called, the override value is returned instead.
func (*Context) Inline ¶ added in v1.1.0
Inline sets the Content-Disposition header to "inline" with the given filename, suggesting the client display the content in-browser.
func (*Context) IsWebSocket ¶ added in v1.1.0
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
IsWritten returns true if a response has been written to the wire.
func (*Context) JSON ¶
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 ¶
Keys returns a copy of all key-value pairs stored on this context. Returns nil if no values have been set.
func (*Context) MultipartForm ¶
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
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 ¶
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 ¶
NoContent writes a response with no body. Returns ErrResponseWritten if a response has already been sent.
func (*Context) OnRelease ¶ added in v1.2.3
func (c *Context) OnRelease(fn func())
OnRelease registers a function to be called when this Context is released back to the pool. Callbacks fire in LIFO order (like defer), before fields are cleared, so context state is still accessible. Panics in callbacks are recovered and silently discarded.
func (*Context) Param ¶
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) ParamDefault ¶ added in v1.2.2
ParamDefault returns the value of a URL parameter, or the default if absent or empty.
func (*Context) ParamInt ¶
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 ¶
ParamInt64 returns a URL parameter parsed as an int64. Returns an error if the parameter is missing or not a valid integer.
func (*Context) Protocol ¶ added in v1.2.3
Protocol returns the HTTP protocol version: "1.1" for HTTP/1.1 or "2" for HTTP/2. Values match the OTel network.protocol.version convention.
func (*Context) Query ¶
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) QueryBool ¶ added in v1.2.2
QueryBool returns a query parameter parsed as a bool. Returns the provided default value if the key is absent or not a valid bool. Recognizes "true", "1", "yes" as true and "false", "0", "no" as false.
func (*Context) QueryDefault ¶
QueryDefault returns the value of a query parameter, or the default if absent or empty.
func (*Context) QueryInt ¶
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) QueryInt64 ¶ added in v1.2.2
QueryInt64 returns a query parameter parsed as an int64. Returns the provided default value if the key is absent or not a valid integer.
func (*Context) QueryParams ¶
QueryParams returns all query parameters as url.Values.
func (*Context) QueryValues ¶
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
RawQuery returns the raw query string without the leading '?'. Returns empty string if the URL has no query component.
func (*Context) Redirect ¶
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
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
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
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
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
ResponseContentType returns the captured Content-Type, or "" if not captured.
func (*Context) ResponseHeaders ¶ added in v1.2.0
ResponseHeaders returns the response headers that have been set so far. The returned slice must not be modified. Use SetHeader or AddHeader to change response headers.
func (*Context) ResponseStatus ¶ added in v1.1.0
ResponseStatus returns the captured response status code.
func (*Context) Scheme ¶
Scheme returns the request scheme ("http" or "https"). If Context.SetScheme has been called (typically by the proxy middleware), the override value is returned. Otherwise it checks the :scheme pseudo-header from the original request. Returns "http" if neither source provides a value.
To trust X-Forwarded-Proto from reverse proxies, use the proxy middleware which validates the header against trusted proxy networks before calling SetScheme.
func (*Context) SetClientIP ¶ added in v1.2.0
SetClientIP overrides the value returned by ClientIP. This is useful in middleware that validates and extracts the real client IP from trusted proxy headers, so downstream handlers see the canonical IP.
func (*Context) SetContext ¶
SetContext sets the request's context. The provided ctx must be non-nil.
func (*Context) SetCookie ¶
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. Semicolons in Name, Value, Path, and Domain are stripped to prevent cookie attribute injection.
func (*Context) SetHeader ¶
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) SetHost ¶ added in v1.2.0
SetHost overrides the value returned by Host. This is useful in middleware that normalizes the host (e.g., stripping port, applying X-Forwarded-Host).
func (*Context) SetMethod ¶ added in v1.3.0
SetMethod overrides the HTTP method. Used by method-override middleware running in Server.Pre().
func (*Context) SetPath ¶ added in v1.1.0
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) SetRawQuery ¶ added in v1.2.0
SetRawQuery overrides the raw query string. Any cached query parameters from a previous call to Query/QueryValues/QueryParams are invalidated.
func (*Context) SetResponseBody ¶ added in v1.1.0
SetResponseBody replaces the buffered response body. Only valid after BufferResponse + c.Next(). Used by transform middleware (compress, etc.).
func (*Context) SetResponseHeaders ¶ added in v1.3.0
SetResponseHeaders replaces all response headers. Used by caching middleware to replay stored responses. The provided headers are copied; the caller retains ownership of the slice.
func (*Context) SetScheme ¶ added in v1.2.0
SetScheme overrides the value returned by Scheme. This is useful in middleware that determines the actual scheme from trusted proxy headers (e.g., X-Forwarded-Proto) and wants downstream handlers to see the canonical value without re-parsing headers.
func (*Context) StartTime ¶ added in v1.2.3
StartTime returns the time at which request processing began. Set once by the framework before the handler chain runs, so all middleware share the same timestamp without calling time.Now() independently.
func (*Context) Status ¶
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) StatusBlob ¶ added in v1.3.0
StatusBlob writes a response using the status code set by [Status]. Equivalent to c.Blob(c.statusCode, contentType, data).
func (*Context) StatusCode ¶
StatusCode returns the response status code set by the handler.
func (*Context) StatusJSON ¶ added in v1.3.0
StatusJSON serializes v as JSON using the status code set by [Status]. Equivalent to c.JSON(c.statusCode, v).
func (*Context) StatusString ¶ added in v1.3.0
StatusString writes a plain-text response using the status code set by [Status]. Equivalent to c.Blob(c.statusCode, "text/plain", []byte(s)).
func (*Context) StatusXML ¶ added in v1.3.0
StatusXML serializes v as XML using the status code set by [Status]. Equivalent to c.XML(c.statusCode, v).
func (*Context) Stream ¶
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 or if buffering is active (see below).
StreamWriter is incompatible with Context.BufferResponse -- if buffering is active, StreamWriter returns nil. Streaming writes data incrementally to the wire, which cannot be deferred or replayed by a buffer layer. Context.CaptureResponse does not capture streamed bytes. Context.IsWritten returns true and Context.BytesWritten tracks bytes after StreamWriter is used.
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 ¶
String writes a formatted string response. Returns ErrResponseWritten if a response has already been sent.
func (*Context) XML ¶
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 ¶
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) )
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 ¶
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 ¶
Error returns a string representation including the status code and message.
type HandlerFunc ¶
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 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 ¶
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 ¶
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) []*Route
Any registers a handler for all HTTP methods, returning the Route for each.
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 )
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 ¶
New creates a Server with the given configuration. The metrics observe.Collector is created eagerly so that Server.Collector returns non-nil before Start is called (unless Config.DisableMetrics is set).
func (*Server) 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) []*Route
Any registers a handler for all HTTP methods, returning the Route for each.
func (*Server) 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) OnError ¶ added in v1.2.3
OnError registers a global error handler called when an unhandled error reaches the safety net after all middleware has had its chance. The handler should write a response. If it does not write, the default text/plain fallback applies. Must be called before Start.
func (*Server) OnShutdown ¶ added in v1.2.4
OnShutdown registers a function to be called during Server.Shutdown. Hooks fire in registration order with the shutdown context. Must be called before Start.
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) PauseAccept ¶ added in v1.2.0
PauseAccept stops accepting new connections. Existing connections continue to be served. Returns ErrAcceptControlNotSupported if the engine does not support accept control (e.g. std engine).
func (*Server) Pre ¶ added in v1.3.0
func (s *Server) Pre(middleware ...HandlerFunc) *Server
Pre registers pre-routing middleware that executes before route lookup. Pre-middleware may modify the request method or path (e.g. for rewriting or stripping a prefix) before the router resolves the handler chain. If a pre-middleware handler aborts, no routing occurs and the request is considered handled. Must be called before Start.
func (*Server) ResumeAccept ¶ added in v1.2.0
ResumeAccept resumes accepting new connections after PauseAccept. Returns ErrAcceptControlNotSupported if the engine does not support accept control.
func (*Server) Routes ¶
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 ¶
Shutdown gracefully shuts down the server. Returns nil if the server has not been started. After the engine stops accepting new connections and drains in-flight requests, any hooks registered via Server.OnShutdown fire in registration order with the provided context.
func (*Server) Start ¶
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 ¶
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
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
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
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 ¶
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 ¶
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 SkipHelper ¶ added in v1.3.0
type SkipHelper struct {
// contains filtered or unexported fields
}
SkipHelper encapsulates the common middleware skip logic (path map + callback). Middleware authors embed SkipHelper to gain standard Skip/SkipPaths support without reimplementing the pattern.
func (*SkipHelper) Init ¶ added in v1.3.0
func (s *SkipHelper) Init(paths []string, fn func(*Context) bool)
Init builds the skip map and stores the skip function.
func (*SkipHelper) ShouldSkip ¶ added in v1.3.0
func (s *SkipHelper) ShouldSkip(c *Context) bool
ShouldSkip returns true if the request should bypass the middleware.
type StreamWriter ¶ added in v1.1.0
type StreamWriter struct {
// contains filtered or unexported fields
}
StreamWriter provides incremental response writing. Obtained via Context.StreamWriter. Bytes written through the StreamWriter are tracked and reflected in Context.BytesWritten. The counter uses atomic operations and is safe for use from a detached goroutine.
func (*StreamWriter) BytesWritten ¶ added in v1.2.4
func (sw *StreamWriter) BytesWritten() int64
BytesWritten returns the total bytes written through this StreamWriter. Safe for concurrent use.
func (*StreamWriter) Close ¶ added in v1.1.0
func (sw *StreamWriter) Close() error
Close signals end of the response body and syncs the byte count back to the owning Context so that Context.BytesWritten reflects the total.
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.
Source Files
¶
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 a single internal hook for releasing celeris contexts from packages that cannot import the root celeris package (e.g.
|
Package ctxkit provides a single internal hook for releasing celeris contexts from packages that cannot import the root celeris package (e.g. |
|
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. |
|
Package middleware provides production-ready middleware for celeris.
|
Package middleware provides production-ready middleware for celeris. |
|
basicauth
Package basicauth provides HTTP Basic Authentication middleware for celeris.
|
Package basicauth provides HTTP Basic Authentication middleware for celeris. |
|
bodylimit
Package bodylimit provides request body size limiting middleware for celeris.
|
Package bodylimit provides request body size limiting middleware for celeris. |
|
circuitbreaker
Package circuitbreaker provides circuit breaker middleware for celeris.
|
Package circuitbreaker provides circuit breaker middleware for celeris. |
|
cors
Package cors provides Cross-Origin Resource Sharing (CORS) middleware for celeris.
|
Package cors provides Cross-Origin Resource Sharing (CORS) middleware for celeris. |
|
csrf
Package csrf provides Cross-Site Request Forgery protection middleware for celeris using the double-submit cookie pattern, with optional server-side token storage for enhanced security.
|
Package csrf provides Cross-Site Request Forgery protection middleware for celeris using the double-submit cookie pattern, with optional server-side token storage for enhanced security. |
|
debug
Package debug provides a debug/introspection middleware for celeris.
|
Package debug provides a debug/introspection middleware for celeris. |
|
etag
Package etag provides automatic ETag generation and conditional response middleware for celeris.
|
Package etag provides automatic ETag generation and conditional response middleware for celeris. |
|
healthcheck
Package healthcheck provides Kubernetes-style health probe middleware for celeris.
|
Package healthcheck provides Kubernetes-style health probe middleware for celeris. |
|
internal/extract
Package extract provides a shared token/value extractor for middleware that reads values from request headers, query parameters, cookies, form fields, or path parameters using a "source:name[:prefix]" lookup string format.
|
Package extract provides a shared token/value extractor for middleware that reads values from request headers, query parameters, cookies, form fields, or path parameters using a "source:name[:prefix]" lookup string format. |
|
internal/fnv1a
Package fnv1a provides a fast, allocation-free FNV-1a string hash and power-of-two rounding for sharded data structures.
|
Package fnv1a provides a fast, allocation-free FNV-1a string hash and power-of-two rounding for sharded data structures. |
|
internal/randutil
Package randutil provides a shared, buffered cryptographic random token generator that amortizes crypto/rand syscalls across middleware packages.
|
Package randutil provides a shared, buffered cryptographic random token generator that amortizes crypto/rand syscalls across middleware packages. |
|
internal/testutil
Package testutil provides test helpers and assertions for middleware tests.
|
Package testutil provides test helpers and assertions for middleware tests. |
|
jwt
Package jwt provides JSON Web Token authentication middleware for celeris.
|
Package jwt provides JSON Web Token authentication middleware for celeris. |
|
jwt/internal/jwtparse
Package jwtparse implements a zero-allocation JWT parser and signer.
|
Package jwtparse implements a zero-allocation JWT parser and signer. |
|
keyauth
Package keyauth provides API key authentication middleware for celeris.
|
Package keyauth provides API key authentication middleware for celeris. |
|
logger
Package logger provides HTTP request logging middleware for celeris.
|
Package logger provides HTTP request logging middleware for celeris. |
|
methodoverride
Package methodoverride provides HTTP method override middleware for celeris.
|
Package methodoverride provides HTTP method override middleware for celeris. |
|
proxy
Package proxy extracts real client IP, scheme, and host from trusted reverse proxy headers.
|
Package proxy extracts real client IP, scheme, and host from trusted reverse proxy headers. |
|
ratelimit
Package ratelimit provides token-bucket rate limiting middleware for celeris.
|
Package ratelimit provides token-bucket rate limiting middleware for celeris. |
|
recovery
Package recovery provides panic recovery middleware for celeris.
|
Package recovery provides panic recovery middleware for celeris. |
|
redirect
Package redirect provides HTTP redirect middleware for common URL normalization patterns in celeris.
|
Package redirect provides HTTP redirect middleware for common URL normalization patterns in celeris. |
|
requestid
Package requestid provides request ID middleware for celeris.
|
Package requestid provides request ID middleware for celeris. |
|
secure
Package secure provides OWASP security headers middleware for celeris.
|
Package secure provides OWASP security headers middleware for celeris. |
|
session
Package session provides server-side session management middleware for celeris.
|
Package session provides server-side session management middleware for celeris. |
|
singleflight
Package singleflight provides request deduplication middleware for celeris.
|
Package singleflight provides request deduplication middleware for celeris. |
|
timeout
Package timeout provides request timeout middleware for celeris.
|
Package timeout provides request timeout middleware for celeris. |
|
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. |
|
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. |