http

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Jul 3, 2026 License: MIT Imports: 23 Imported by: 0

Documentation

Overview

Package http provides the HTTP kernel, context, request, and response abstractions.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ReleaseContext

func ReleaseContext(c *Context)

ReleaseContext returns a pooled Context to the pool. It is a no-op for Contexts that did not come from the pool (e.g. WithContext copies) or that were Detach()ed because something may still reference them.

func SetTrustedProxies

func SetTrustedProxies(cidrs ...string) error

SetTrustedProxies configures which upstream proxy addresses are allowed to set X-Forwarded-For / X-Real-IP. Accepts individual IPs ("10.0.0.1") or CIDR ranges ("10.0.0.0/8"). Pass the single value "*" to trust all proxies — only safe when the app is never directly reachable by clients.

Call once at startup. With no trusted proxies configured, forwarding headers are ignored and Request.IP() returns the direct peer address.

Types

type Context

type Context struct {
	Request  *Request
	Response *Response
	// contains filtered or unexported fields
}

Context holds the request, response writer, URL params, and a per-request store. It is the single argument to every handler and middleware.

A Context is only valid for the duration of the request that produced it. The router recycles Contexts through a sync.Pool, so handlers MUST NOT retain a *Context (or its Request/Response) past the point where they return. Use WithContext if you need a derived Context to carry into a goroutine that outlives the request — it returns an independent copy that is never pooled.

func AcquireContext

func AcquireContext(w http.ResponseWriter, r *http.Request) *Context

AcquireContext returns a pooled Context bound to w and r. The caller must return it with ReleaseContext once the request completes. Intended for the router; application code receives its Context as a handler argument.

func NewContext

func NewContext(w http.ResponseWriter, r *http.Request, params map[string]string) *Context

NewContext creates a standalone (non-pooled) Context from a raw http.Request and ResponseWriter. Used by tests and callers that construct a Context directly; the router uses AcquireContext for the pooled hot path.

func (*Context) Abort

func (c *Context) Abort(status int, message string) error

Abort returns an HTTPError with the given status and message. Returning it from a handler or middleware stops the chain and renders the error.

func (*Context) Bind

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

Bind decodes the request body (JSON, XML, or form) into dest.

func (*Context) Cookie

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

Cookie returns the value of the named request cookie, or an error if absent.

func (*Context) Ctx

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

Ctx returns the request's context.Context.

func (*Context) Data

func (c *Context) Data(status int, contentType string, b []byte) error

Data writes a raw byte body with an explicit content type.

func (*Context) DefaultQuery

func (c *Context) DefaultQuery(name, def string) string

DefaultQuery returns a URL query parameter, or def if absent/empty.

func (*Context) Detach

func (c *Context) Detach()

Detach permanently excludes this Context (and everything sharing its Request/Response/store, i.e. WithContext copies) from pool recycling. Call it when a reference may outlive the request — e.g. the Timeout middleware detaches when it abandons a still-running handler goroutine, so the goroutine can never race a recycled Context belonging to a later request. The objects are then reclaimed by the GC instead of the pool.

func (*Context) File

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

File serves a file from the local filesystem.

func (*Context) FormFile

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

FormFile returns the first file uploaded under the given field name.

func (*Context) FormValue

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

FormValue returns a form field value.

func (*Context) Get

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

Get retrieves a value from the per-request store.

func (*Context) HTML

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

HTML writes an HTML body.

func (*Context) Header

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

Header returns a request header by name.

func (*Context) IP

func (c *Context) IP() string

IP returns the client's real IP address, respecting X-Forwarded-For only from trusted proxies (see SetTrustedProxies).

func (*Context) IsAJAX

func (c *Context) IsAJAX() bool

IsAJAX reports whether the request was made via XMLHttpRequest.

func (*Context) IsJSON

func (c *Context) IsJSON() bool

IsJSON reports whether the request content type is application/json.

func (*Context) JSON

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

JSON writes a JSON-encoded body with the given status code.

func (*Context) Method

func (c *Context) Method() string

Method returns the HTTP method in uppercase.

func (*Context) MustGet

func (c *Context) MustGet(key string) any

MustGet retrieves a value and panics if the key is absent.

func (*Context) NoContent

func (c *Context) NoContent() error

NoContent sends a 204 No Content response.

func (*Context) Param

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

Param returns a URL path parameter by name (e.g. ":id").

func (*Context) ParamInt

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

ParamInt returns a URL path parameter parsed as an int.

func (*Context) ParseUpload

func (c *Context) ParseUpload(field string, cfg ...UploadConfig) (*UploadedFile, error)

ParseUpload parses a single file upload from the request field `name`.

func (*Context) ParseUploads

func (c *Context) ParseUploads(field string, cfg ...UploadConfig) ([]*UploadedFile, error)

ParseUploads parses all files uploaded under a multi-value field name.

func (*Context) Path

func (c *Context) Path() string

Path returns the request URL path.

func (*Context) PushParam

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

PushParam appends a URL path parameter. Called by the router as it matches; it writes into the Request's reused backing array (zero allocation on the hot path). Not intended for application code.

func (*Context) Query

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

Query returns a URL query parameter by name.

func (*Context) QueryBool

func (c *Context) QueryBool(name string) bool

QueryBool returns a URL query parameter parsed as a bool (false if absent/unparseable).

func (*Context) QueryD

func (c *Context) QueryD(name, def string) string

QueryD returns a URL query parameter, or def if absent.

func (*Context) QueryInt

func (c *Context) QueryInt(name string, def int) int

QueryInt returns a URL query parameter parsed as an int, or def if absent/unparseable.

func (*Context) Redirect

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

Redirect sends a redirect response.

func (*Context) Set

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

Set stores a value in the per-request key-value store.

func (*Context) SetCookie

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

SetCookie writes a Set-Cookie header on the response.

func (*Context) String

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

String writes a plain-text body.

func (*Context) Validate

func (c *Context) Validate(dest any) error

Validate binds the request body into dest and then validates it against `validate` struct tags. On validation failure it returns a *ValidationError, which the router's error handler renders as a 422 with the field-level error map. Validate does NOT write to the response itself — returning the error is what triggers the single, correctly-formed response.

var req struct {
    Email    string `json:"email"    validate:"required,email"`
    Password string `json:"password" validate:"required,min=8"`
}
if err := c.Validate(&req); err != nil {
    return err // automatic 422 with {"errors":{"email":["..."]}}
}

func (*Context) WithContext

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

WithContext returns a shallow copy of the Context with a new context.Context. The copy shares the underlying store and lock with the original but is never returned to the pool, so it is safe to carry beyond the request lifecycle.

func (*Context) XML

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

XML writes an XML-encoded body with the given status code.

type HTTPError

type HTTPError struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
}

HTTPError represents an HTTP error with a status code and message.

func NewHTTPError

func NewHTTPError(code int, message string) *HTTPError

NewHTTPError creates an HTTPError.

func (*HTTPError) Error

func (e *HTTPError) Error() string

type HandlerFunc

type HandlerFunc func(*Context) error

HandlerFunc is an OniWorks HTTP handler. Handlers return an error to signal failure; the error is dispatched to the registered error handler automatically.

type Kernel

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

Kernel is the HTTP server kernel. It wraps the standard library's http.Server and adds graceful shutdown, TLS support, and signal handling.

func NewKernel

func NewKernel(cfg ServerConfig, handler http.Handler) *Kernel

NewKernel creates a Kernel with the given config and handler.

func (*Kernel) Addr

func (k *Kernel) Addr() string

Addr returns the listening address (useful for tests that pick a random port).

func (*Kernel) ListenAndServeBackground

func (k *Kernel) ListenAndServeBackground() (string, error)

ListenAndServeBackground starts the server in a goroutine and returns the bound address. Useful for integration tests.

func (*Kernel) Serve

func (k *Kernel) Serve() error

Serve starts the HTTP server and blocks until a shutdown signal is received. It handles SIGINT and SIGTERM for graceful shutdown.

func (*Kernel) Shutdown

func (k *Kernel) Shutdown() error

Shutdown performs a graceful shutdown with the configured timeout.

func (*Kernel) WithLogger

func (k *Kernel) WithLogger(l *slog.Logger) *Kernel

WithLogger sets a custom slog.Logger on the kernel.

type Map

type Map = map[string]any

Map is a convenience alias for map[string]any used in JSON/template responses.

type MiddlewareFunc

type MiddlewareFunc func(HandlerFunc) HandlerFunc

MiddlewareFunc wraps a HandlerFunc, returning a new HandlerFunc.

type Request

type Request struct {
	*http.Request
	// contains filtered or unexported fields
}

Request wraps *http.Request with additional helpers.

func (*Request) BearerToken

func (r *Request) BearerToken() string

BearerToken extracts the Bearer token from the Authorization header.

func (*Request) Bind

func (r *Request) Bind(dest any) error

Bind decodes the request body based on the Content-Type header. Supports application/json, application/xml, application/x-www-form-urlencoded, multipart/form-data.

func (*Request) BodyBytes

func (r *Request) BodyBytes() ([]byte, error)

BodyBytes reads and returns the request body as raw bytes. The body is restored afterward so a later Bind (or re-read) still sees the full payload.

func (*Request) IP

func (r *Request) IP() string

IP returns the client IP address.

X-Forwarded-For / X-Real-IP are only honored when the direct peer (RemoteAddr) is a configured trusted proxy — see SetTrustedProxies. By default no proxies are trusted, so these client-controllable headers are ignored and the direct peer address is returned. This prevents a client from spoofing its IP to bypass IP-based rate limiting or forge audit logs.

func (*Request) IsSecure

func (r *Request) IsSecure() bool

IsSecure reports whether the request was made over HTTPS.

The X-Forwarded-Proto header is only believed when the direct peer is a configured trusted proxy (see SetTrustedProxies); otherwise a client could spoof the scheme, influencing secure-cookie or HTTPS-redirect decisions.

func (*Request) Param

func (r *Request) Param(name string) string

Param returns a path parameter value (e.g. for route "/users/:id", Param("id")).

func (*Request) Params

func (r *Request) Params() map[string]string

Params returns all path parameters as a map (allocates; prefer Param for hot paths).

func (*Request) WantsJSON

func (r *Request) WantsJSON() bool

WantsJSON reports whether the client prefers a JSON response (via Accept header). An explicit text/html preference wins over a wildcard */*, so browsers (which send "*/*") are not treated as JSON clients.

type Response

type Response struct {
	http.ResponseWriter
	// contains filtered or unexported fields
}

Response wraps http.ResponseWriter with status tracking and body size counting.

func (*Response) Committed

func (r *Response) Committed() bool

Committed reports whether the response headers have been sent.

func (*Response) Flush

func (r *Response) Flush()

Flush implements http.Flusher if the underlying writer supports it.

func (*Response) Hijack

func (r *Response) Hijack() (net.Conn, *bufio.ReadWriter, error)

Hijack implements http.Hijacker if the underlying writer supports it (needed for WebSocket upgrades).

func (*Response) Size

func (r *Response) Size() int64

Size returns the number of bytes written to the response body.

func (*Response) Status

func (r *Response) Status() int

Status returns the HTTP status code sent (or 200 if WriteHeader was never called).

func (*Response) Unwrap

func (r *Response) Unwrap() http.ResponseWriter

Unwrap returns the underlying http.ResponseWriter for type-assertion chains.

func (*Response) Wrap

func (r *Response) Wrap(w http.ResponseWriter)

Wrap replaces the underlying http.ResponseWriter. Used by middleware like Compress that need to intercept writes. The status/size counters are reset.

func (*Response) Write

func (r *Response) Write(b []byte) (int, error)

Write sends bytes to the client.

func (*Response) WriteHeader

func (r *Response) WriteHeader(code int)

WriteHeader captures the status code and delegates to the underlying writer. Calling this more than once is a no-op (the header is sent only once).

type ServerConfig

type ServerConfig struct {
	Host            string
	Port            int
	TLSCertFile     string
	TLSKeyFile      string
	ReadTimeout     time.Duration
	WriteTimeout    time.Duration
	IdleTimeout     time.Duration
	ShutdownTimeout time.Duration
}

ServerConfig holds configuration for the HTTP server.

func DefaultServerConfig

func DefaultServerConfig() ServerConfig

DefaultServerConfig returns production-ready defaults.

type UploadConfig

type UploadConfig struct {
	MaxSize      int64    // bytes; default 10 MB
	AllowedTypes []string // e.g. ["image/jpeg","image/png"]; nil = all allowed
}

UploadConfig controls max file size and allowed MIME types.

func DefaultUploadConfig

func DefaultUploadConfig() UploadConfig

DefaultUploadConfig returns sensible upload defaults.

type UploadedFile

type UploadedFile struct {
	Header   *multipart.FileHeader
	Original string // original filename from client
	Size     int64  // bytes
	MIMEType string
}

UploadedFile wraps a *multipart.FileHeader with helpers for inspection and saving.

func (*UploadedFile) Ext

func (uf *UploadedFile) Ext() string

Ext returns the lowercase file extension including the dot (e.g. ".jpg").

func (*UploadedFile) IsImage

func (uf *UploadedFile) IsImage() bool

IsImage reports whether the MIME type indicates an image.

func (*UploadedFile) Open

func (uf *UploadedFile) Open() (multipart.File, error)

Open returns a ReadCloser for the uploaded file content.

func (*UploadedFile) Store

func (uf *UploadedFile) Store(dir string, filename ...string) (string, error)

Store saves the uploaded file to the given destination directory. Returns the full path to the saved file.

type ValidationError

type ValidationError struct {
	Fields validation.Errors
}

ValidationError carries field-level validation failures. The router's error handler renders it as a 422 Unprocessable Entity with the errors map.

func (*ValidationError) Error

func (e *ValidationError) Error() string

Jump to

Keyboard shortcuts

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