Documentation
¶
Overview ¶
Package cf_http provides Caerus lifecycle and middleware support for net/http-compatible application handlers.
Index ¶
- Constants
- Variables
- func DefaultErrorWriter(w http.ResponseWriter, r *http.Request, failure Failure)
- func Record(server *Server, route string, status int, duration time.Duration)
- func RequestIDFrom(r *http.Request) string
- type CORSConfig
- type CSRFConfig
- type CompressionConfig
- type ErrorWriter
- type Failure
- func BadRequest(code, message string) Failure
- func Conflict(code, message string) Failure
- func Forbidden(code, message string) Failure
- func InternalError(code, message string) Failure
- func NewFailure(status int, code, message string) Failure
- func NotFound(code, message string) Failure
- func Unauthorized(code, message string) Failure
- func ValidationError(code, message string) Failure
- type Middleware
- func CORS(cfg CORSConfig) Middleware
- func CSRF(cfg CSRFConfig) Middleware
- func Chain(mw ...Middleware) Middleware
- func Compression(cfg CompressionConfig) Middleware
- func Metrics(server *Server) Middleware
- func Recover(get func() *slog.Logger, write ErrorWriter) Middleware
- func RequestID() Middleware
- func RequestLog(logger func() *slog.Logger) Middleware
- type Option
- func WithAddress(address string) Option
- func WithConfig(cfg ServerConfig) Option
- func WithConfigSource(name, path string, opts ...SourceOption) Option
- func WithIdleTimeout(d time.Duration) Option
- func WithLogger(logger *slog.Logger) Option
- func WithMaxHeaderBytes(n int) Option
- func WithMetricsEnabled(enabled bool) Option
- func WithName(name string) Option
- func WithReadHeaderTimeout(d time.Duration) Option
- func WithReadTimeout(d time.Duration) Option
- func WithRestartPolicy(policy string) Option
- func WithShutdownTimeout(d time.Duration) Option
- func WithWriteTimeout(d time.Duration) Option
- type RestartPolicy
- type Server
- func (c *Server) Addr() string
- func (c *Server) GetDependencies() []string
- func (c *Server) GetInitOrderStage() cf.Stage
- func (c *Server) Handler() http.Handler
- func (c *Server) Health(ctx context.Context) error
- func (c *Server) Init(ctx context.Context, fw *cf.CaerusFramework) error
- func (c *Server) Logger() *slog.Logger
- func (c *Server) Metrics() []cf_observability.Metric
- func (c *Server) Name() string
- func (c *Server) OnConfigReload(source string, cfg any)
- func (c *Server) RecordGraphQLMetric(operation string, status int, duration time.Duration)
- func (c *Server) RecordGraphQLMetricFromHTTPPeek(operation string, status int, duration time.Duration)
- func (c *Server) RecordGraphQLResolverMetric(operation, resolver string, status int, duration time.Duration)
- func (c *Server) RegisterConfigSources(conf any) error
- func (c *Server) Run(ctx context.Context) error
- func (c *Server) SetHandler(handler http.Handler)
- func (c *Server) Shutdown(ctx context.Context) error
- type ServerConfig
- type SourceOption
Constants ¶
const ( // ErrorCodeBadRequest indicates invalid request data. ErrorCodeBadRequest = "BAD_REQUEST" ErrorCodeUnauthorized = "UNAUTHORIZED" // ErrorCodeForbidden indicates insufficient permissions. ErrorCodeForbidden = "FORBIDDEN" // ErrorCodeNotFound indicates the requested resource was not found. ErrorCodeNotFound = "NOT_FOUND" // ErrorCodeConflict indicates a conflict with the current state. ErrorCodeConflict = "CONFLICT" // ErrorCodeInternal indicates an internal server error. ErrorCodeInternal = "INTERNAL_ERROR" // ErrorCodeValidation indicates validation errors. ErrorCodeValidation = "VALIDATION_ERROR" )
Common error codes
const ( // HTTPInstrumentationMiddleware marks samples from cf_http.Metrics middleware // (route from r.Pattern / "unknown"). This is the usual REST path. HTTPInstrumentationMiddleware = "middleware" // HTTPInstrumentationApp marks samples from an explicit Record call // (Echo/chi shims, custom middleware). Also normal — use when the router // does not set r.Pattern. HTTPInstrumentationApp = "app" )
Values for the http_instrumentation metric label on http_requests_* series.
const ( // ComponentName is the default framework name for the HTTP server. ComponentName = "http" // ComponentStage is the serving plane, above the data plane. ComponentStage = cf.Stage("app") )
const ( // GraphQLInstrumentationApp marks samples recorded by application / // engine hooks (RecordGraphQLMetric, StartOperation, RecordResolver). GraphQLInstrumentationApp = "app" // GraphQLInstrumentationHTTPPeek marks samples from graphql.Metrics // auto body-peek extraction — convenient, not the usual production path. GraphQLInstrumentationHTTPPeek = "http_peek" )
Values for the graphql_instrumentation metric label.
Variables ¶
var ErrCORSCredentialsWildcard = errors.New(
"cf_http: CORS AllowCredentials cannot be true when AllowedOrigins contains '*'",
)
ErrCORSCredentialsWildcard is returned by CORSConfig.Validate when AllowCredentials is true and AllowedOrigins contains "*".
var ErrServerRestartRequired = errors.New("cf_http: server settings changed; immediate restart requested")
ErrServerRestartRequired is returned by Run when a live configuration reload changed settings that cannot rebind in place and the active restart policy was "immediate". Run has already drained and returned; the process should exit so the orchestrator starts a fresh instance with the new settings.
Functions ¶
func DefaultErrorWriter ¶
func DefaultErrorWriter(w http.ResponseWriter, r *http.Request, failure Failure)
DefaultErrorWriter is the default ErrorWriter. It writes Message when non-empty, else http.StatusText(Status), via http.Error. Used when a middleware's Write option is nil.
func Record ¶
Record adds one completed request to the server meter with http_instrumentation="app". Empty routes are normalized to unknown so arbitrary URL paths never become metric labels.
func RequestIDFrom ¶
RequestIDFrom extracts the request ID from the request context.
Types ¶
type CORSConfig ¶
type CORSConfig struct {
// AllowedOrigins is a list of origins a cross-domain request can be executed from.
// If the special "*" value is present in the list, all origins will be allowed.
// Default value is [] (empty), which means no origins are allowed.
AllowedOrigins []string
// AllowedMethods is a list of methods the client is allowed to use with
// cross-domain requests. Default value is simple methods (GET, POST, HEAD).
AllowedMethods []string
// AllowedHeaders is a list of non-simple headers the client is allowed to use with
// cross-domain requests. Default value is [] (empty).
AllowedHeaders []string
// ExposedHeaders indicates which headers are safe to expose to the API of a CORS
// API specification.
ExposedHeaders []string
// AllowCredentials indicates whether the request can include user credentials like
// cookies, HTTP authentication or client side SSL certificates.
AllowCredentials bool
// MaxAge indicates how long (in seconds) the results of a preflight request
// can be cached. Default value is 0, which means no caching.
MaxAge int
}
CORSConfig configures CORS middleware.
func (CORSConfig) Validate ¶
func (cfg CORSConfig) Validate() error
Validate reports whether the CORS configuration is usable.
Returns ErrCORSCredentialsWildcard when AllowCredentials is true and any AllowedOrigin is "*". Prefer calling Validate from Init (or wiring) and returning the error; CORS itself still panics on the same rule so a missed Validate cannot serve a browser-rejected policy.
type CSRFConfig ¶
type CSRFConfig struct {
// CookieName is the name of the CSRF cookie. Default is "_csrf".
CookieName string
// HeaderName is the name of the CSRF header. Default is "X-CSRF-Token".
HeaderName string
// TokenLength is the length of the generated token in bytes. Default is 32.
TokenLength int
// Secure controls the cookie's Secure attribute. Nil (unset) means secure:
// the cookie is only sent over HTTPS. Set a non-nil value to override,
// e.g. false for local development over plain HTTP.
Secure *bool
// SameSite is the SameSite attribute of the cookie. Default is Lax.
SameSite http.SameSite
// Write is the ErrorWriter used for rejected requests. Nil uses
// DefaultErrorWriter.
Write ErrorWriter
}
CSRFConfig configures CSRF middleware.
type CompressionConfig ¶
type CompressionConfig struct {
// MinSize is the minimum size in bytes before compression is applied.
// Default is 1024.
MinSize int
// Levels is the gzip compression level. Default is gzip.DefaultCompression.
Level int
}
CompressionConfig configures compression middleware.
type ErrorWriter ¶
type ErrorWriter func(w http.ResponseWriter, r *http.Request, failure Failure)
ErrorWriter is a function that writes an error response to the client. It receives the HTTP response writer, the original request, and the failure. Implementations should set appropriate headers, write the status code, and never expose internal error details.
type Failure ¶
type Failure struct {
// Status is the HTTP status code to send to the client.
Status int
// Code is a stable, machine-readable error code (e.g., "NOT_FOUND").
// It may be empty for plain transport failures.
Code string
// Message is a safe, human-readable error message. It must never contain
// internal causes, stack traces, or user data.
Message string
// RequestID is the request ID for correlation with logs, populated from
// RequestIDFrom(r) by middleware when present.
RequestID string
}
Failure represents an error that occurred during request processing. It contains safe, user-facing information suitable for sending to clients. Internal error details should be logged separately, not included in Failure.
func BadRequest ¶
BadRequest creates a Failure for HTTP 400 Bad Request.
func InternalError ¶
InternalError creates a Failure for HTTP 500 Internal Server Error.
func NewFailure ¶
NewFailure creates a new Failure with the given status, code, and message.
func Unauthorized ¶
Unauthorized creates a Failure for HTTP 401 Unauthorized.
func ValidationError ¶
ValidationError creates a Failure for HTTP 422 Unprocessable Entity.
func (Failure) WithRequestID ¶
WithRequestID sets the request ID on the failure.
type Middleware ¶
Middleware is a function that wraps an http.Handler.
func CORS ¶
func CORS(cfg CORSConfig) Middleware
CORS returns a CORS middleware with the given configuration.
Panics if cfg.Validate() fails (credentials + "*"). Prefer CORSConfig.Validate in Init and return the error; the panic remains as a construction-time guard because CORS returns only Middleware (no error slot). See the README "Security middleware" section.
func CSRF ¶
func CSRF(cfg CSRFConfig) Middleware
CSRF returns a CSRF middleware implementing the double-submit cookie pattern with Origin/Referer validation. Safe methods (GET/HEAD/OPTIONS) mint and set a CSRF cookie when absent; unsafe methods must present a matching header. For unsafe methods, a request with neither an Origin nor a Referer header is rejected (fail closed) because those methods are exactly what CSRF protects.
func Chain ¶
func Chain(mw ...Middleware) Middleware
Chain composes middleware in order. The first middleware is outermost.
func Compression ¶
func Compression(cfg CompressionConfig) Middleware
Compression returns a gzip compression middleware.
func Metrics ¶
func Metrics(server *Server) Middleware
Metrics records request metrics. Uses route pattern (Go 1.22+ ServeMux) for bounded cardinality. Falls back to "unknown" when pattern is not available.
func Recover ¶
func Recover(get func() *slog.Logger, write ErrorWriter) Middleware
Recover recovers from panics and logs them with a stack trace. Only writes an error response if the response has not been committed yet. Uses the provided ErrorWriter, or DefaultErrorWriter when write is nil.
func RequestID ¶
func RequestID() Middleware
RequestID generates a request ID if not present and stores it in context. Validates incoming X-Request-ID header: must be <= 256 bytes and contain only alphanumeric characters, hyphens, or underscores. Invalid values are replaced.
func RequestLog ¶
func RequestLog(logger func() *slog.Logger) Middleware
RequestLog logs each request with method, route pattern, status, duration, and request ID. Uses route pattern when available (Go 1.22+ ServeMux), otherwise "unknown".
type Option ¶
type Option func(*options)
Option configures a Server at construction time.
func WithConfig ¶
func WithConfig(cfg ServerConfig) Option
WithConfig applies a static configuration snapshot.
func WithConfigSource ¶
func WithConfigSource(name, path string, opts ...SourceOption) Option
WithConfigSource binds the server to a self-registered configuration source.
func WithIdleTimeout ¶
WithIdleTimeout sets the keep-alive idle timeout.
func WithLogger ¶
WithLogger supplies an explicit logger for tests or embedded use.
func WithMaxHeaderBytes ¶
WithMaxHeaderBytes sets the maximum request header size.
func WithMetricsEnabled ¶
WithMetricsEnabled enables or disables the component MetricsProvider.
func WithReadHeaderTimeout ¶
WithReadHeaderTimeout sets the maximum header-read duration.
func WithReadTimeout ¶
WithReadTimeout sets the maximum read duration.
func WithRestartPolicy ¶ added in v0.0.3
WithRestartPolicy sets what happens when a live reload changes settings that cannot rebind in place ("handled" default, or "immediate").
func WithShutdownTimeout ¶
WithShutdownTimeout sets the graceful drain deadline.
func WithWriteTimeout ¶
WithWriteTimeout sets the maximum write duration. Zero disables the deadline.
type RestartPolicy ¶
type RestartPolicy string
RestartPolicy controls behavior when server settings change during config reload.
const ( // RestartPolicyHandled logs a warning and continues with current settings. // This is the default and safest option for production. RestartPolicyHandled RestartPolicy = "handled" // RestartPolicyImmediate gracefully stops the server when settings change. // The server must be restarted externally with new settings. RestartPolicyImmediate RestartPolicy = "immediate" )
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server owns the net/http serving lifecycle for an app-owned handler.
func (*Server) Addr ¶
Addr returns the active listener address, or the configured address before serving. It is useful when binding to port zero in tests.
func (*Server) GetDependencies ¶
GetDependencies implements cf.Dependencies.
func (*Server) GetInitOrderStage ¶
GetInitOrderStage implements cf.CaerusComponent.
func (*Server) Logger ¶
Logger returns the current logger for the server. This is useful for middleware that needs to log with the same logger.
func (*Server) Metrics ¶
func (c *Server) Metrics() []cf_observability.Metric
Metrics implements cf_observability.MetricsProvider.
func (*Server) OnConfigReload ¶
OnConfigReload implements cf.ConfigReloader. Metrics enablement is live; listener settings remain active until restart based on restart policy.
func (*Server) RecordGraphQLMetric ¶
RecordGraphQLMetric records one GraphQL operation sample in the dedicated http_graphql_operations_* series with graphql_instrumentation="app". Empty operation names are normalized to "unknown". Callers must pass bounded operation names (allowlist / codegen).
func (*Server) RecordGraphQLMetricFromHTTPPeek ¶
func (c *Server) RecordGraphQLMetricFromHTTPPeek(operation string, status int, duration time.Duration)
RecordGraphQLMetricFromHTTPPeek records a sample produced by graphql.Metrics auto body-peek extraction (graphql_instrumentation="http_peek"). Prefer RecordGraphQLMetric or engine hooks in production; use the label to find leftover auto-instrumentation in scrapes / dashboards.
func (*Server) RecordGraphQLResolverMetric ¶
func (c *Server) RecordGraphQLResolverMetric(operation, resolver string, status int, duration time.Duration)
RecordGraphQLResolverMetric records one GraphQL resolver sample in the dedicated http_graphql_resolvers_* series with graphql_instrumentation="app". Empty operation/resolver values are normalized to "unknown". Cardinality is caller-owned: pass bounded labels (codegen / app allowlist) only.
func (*Server) RegisterConfigSources ¶
RegisterConfigSources implements cf.ConfigSourceRegistrar.
func (*Server) SetHandler ¶
SetHandler registers the app-owned HTTP handler. It must be called before Run.
type ServerConfig ¶
type ServerConfig struct {
Address string `json:"address,omitempty" yaml:"address,omitempty" env:"ADDRESS" flag:"http-address"`
ReadTimeoutSec *float64 `json:"read_timeout_sec,omitempty" yaml:"read_timeout_sec,omitempty" env:"READ_TIMEOUT_SEC" flag:"http-read-timeout-sec"`
WriteTimeoutSec *float64 `json:"write_timeout_sec,omitempty" yaml:"write_timeout_sec,omitempty" env:"WRITE_TIMEOUT_SEC" flag:"http-write-timeout-sec"`
IdleTimeoutSec *float64 `json:"idle_timeout_sec,omitempty" yaml:"idle_timeout_sec,omitempty" env:"IDLE_TIMEOUT_SEC" flag:"http-idle-timeout-sec"`
ReadHeaderTimeoutSec *float64 `` /* 147-byte string literal not displayed */
MaxHeaderBytes *int `json:"max_header_bytes,omitempty" yaml:"max_header_bytes,omitempty" env:"MAX_HEADER_BYTES" flag:"http-max-header-bytes"`
ShutdownTimeoutSec *float64 `` /* 135-byte string literal not displayed */
MetricsEnabled *bool `json:"metrics_enabled,omitempty" yaml:"metrics_enabled,omitempty" env:"METRICS_ENABLED" flag:"http-metrics-enabled"`
RestartPolicy RestartPolicy `json:"restart_policy,omitempty" yaml:"restart_policy,omitempty" env:"RESTART_POLICY" flag:"http-restart-policy"`
}
ServerConfig is the file/env-drivable HTTP server configuration. Pointer fields distinguish omitted values from explicit zero values.
type SourceOption ¶
type SourceOption func(*sourceOptions)
SourceOption configures the self-registered HTTP source.
func WithSourceEnvPrefix ¶
func WithSourceEnvPrefix(prefix string) SourceOption
WithSourceEnvPrefix overrides the environment prefix for a source.
func WithSourceFormat ¶
func WithSourceFormat(format cf_configuration.Format) SourceOption
WithSourceFormat forces the source file format.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package graphql provides GraphQL-over-HTTP telemetry helpers for cf_http.
|
Package graphql provides GraphQL-over-HTTP telemetry helpers for cf_http. |
|
Package problem provides RFC 9457 Problem Details for HTTP APIs helper.
|
Package problem provides RFC 9457 Problem Details for HTTP APIs helper. |