base

package
v0.1.0-alpha.1 Latest Latest
Warning

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

Go to latest
Published: Aug 19, 2026 License: Apache-2.0 Imports: 42 Imported by: 0

Documentation

Index

Constants

View Source
const (
	DefaultRequestBodyMaxBytes  = 1 << 20
	DefaultResponseBodyMaxBytes = 4 << 20
)
View Source
const (
	MAX_REQ_BODY  = 524288 // 512 KiB
	MAX_RESP_BODY = 524288 // 512 KiB
)
View Source
const DefaultBufferedResponseMaxBytes int64 = DefaultResponseBodyMaxBytes

Variables

View Source
var ErrCacheHitResponseAlreadyConsumed = errors.New("cache hit response already consumed")
View Source
var ErrLogQueueFull = errors.New("logger batch processor queue full")

ErrLogQueueFull is returned when a detached log callback cannot enqueue its payload without blocking the request lifecycle.

View Source
var ErrLogQueueUnavailable = errors.New("logger batch processor unavailable")

ErrLogQueueUnavailable reports a logger that has not initialized its bounded processor yet. It is deliberately distinct from capacity drops so callers can surface configuration/lifecycle errors.

View Source
var RequestVariablePattern = regexp.MustCompile(`\$[A-Za-z0-9_]+`)

RequestVariablePattern matches $name and ${name}-less APISIX/NGINX variable references in interpolation templates.

Functions

func AdaptRequestPhase

func AdaptRequestPhase(plugin RequestPhasePlugin, next http.Handler) http.Handler

func ApisixString

func ApisixString(r *http.Request, key string) string

ApisixString reads a string-valued apisix request variable.

func AppendVaryToken

func AppendVaryToken(header http.Header, token string)

AppendVaryToken adds token to all existing Vary field-values once, using a case-insensitive comparison while retaining unrelated tokens and order.

func ApplyBatchDefaults

func ApplyBatchDefaults(d *BatchDefaults)

ApplyBatchDefaults fills zero batch values with logger_batch defaults. RetryDelaySec is only defaulted when RetryDelaySet is false.

func AttachExternalUser

func AttachExternalUser(r *http.Request, userinfo map[string]any, setHeader *bool)

AttachExternalUser publishes userinfo into the $external_user request variable and the X-Userinfo header unless setHeader is non-nil and false.

func BuildAccessLogFromSnapshot

func BuildAccessLogFromSnapshot(snapshot LogSnapshot, routeID string, serverAddr ...string) map[string]any

BuildAccessLogFromSnapshot preserves the default access-log payload after the live request and response writer have been detached.

func BuildAccessLogSnapshot

func BuildAccessLogSnapshot(
	request AccessLogRequest,
	status int,
	responseHeaders http.Header,
	responseSize int64,
	routeID string,
	r *http.Request,
	duration time.Duration,
) map[string]any

BuildAccessLogSnapshot builds the default access-log entry shared by the access-log style logger plugins.

func CallbackPath

func CallbackPath(callbackURI string) string

CallbackPath returns the request path of an absolute callback URI, the original value for relative or unparsable URIs, and "/" when an absolute URI has no path.

func CaptureResponseOutcome

func CaptureResponseOutcome(w http.ResponseWriter) (
	wrapped http.ResponseWriter,
	snapshot func() ctx.ResponseOutcome,
	closeHijacked func() error,
)

CaptureResponseOutcome is retained only as a direct-package compatibility boundary. New production code should use CaptureResponseOutcomeController.

func CodeFromRequest

func CodeFromRequest(r *http.Request, headerName, queryName string) string

CodeFromRequest reads an authorization code from the named header first, falling back to the named query parameter.

func CollapseAccessLogHeaderValues

func CollapseAccessLogHeaderValues(values http.Header) map[string]any

CollapseAccessLogHeaderValues normalizes default access-log headers while omitting sensitive credentials and tokens.

func CollapseHeaderValues

func CollapseHeaderValues(values http.Header) map[string]any

CollapseHeaderValues normalizes header names to lowercase and collapses single-value headers to plain strings.

func CollapseQueryValues

func CollapseQueryValues(values map[string][]string) map[string]any

CollapseQueryValues collapses single-value query parameters to plain strings.

func CookieSameSite

func CookieSameSite(value string) http.SameSite

CookieSameSite maps an OAuth session cookie_same_site setting to its net/http constant, defaulting to Lax for empty or unknown values.

func EncodeLogBatch

func EncodeLogBatch(entries []map[string]any, batchMaxSize int, originKey string) ([]byte, error)

EncodeLogBatch encodes either a single entry or an entry array according to the logger batch boundary. When originKey is set and every entry contains a raw origin string, those strings are encoded instead of their envelopes.

func EnqueueLog

func EnqueueLog(processor *logger_batch.Processor, entry map[string]any) error

EnqueueLog is the standalone form for logger implementations that cannot embed BaseLoggerPlugin (for example metric and file loggers).

func ExprMatched

func ExprMatched(r *http.Request, expressions any, status int) bool

func ExtractResponseTrailers

func ExtractResponseTrailers(header http.Header) http.Header

ExtractResponseTrailers removes trailer declarations and values from a detached header map and returns them as a separate canonical trailer map.

func GetFieldsFromSnapshot

func GetFieldsFromSnapshot(snapshot LogSnapshot, logFormat map[string]string) map[string]any

GetFieldsFromSnapshot keeps field expansion in the detached snapshot layer while giving plugin packages the same base-level entry point as the legacy live-request helper.

func HostWithoutPort

func HostWithoutPort(address string) string

HostWithoutPort strips the port from a host or address.

func Hostname

func Hostname() string

Hostname returns the process hostname, cached once per process so logger transports never re-read it per entry.

func InvalidateBodyDerivedHeaders

func InvalidateBodyDerivedHeaders(header http.Header)

InvalidateBodyDerivedHeaders removes representation metadata that no longer describes the body after a semantic replacement. Iterate the actual map keys because Header.Del only removes the canonical key.

func IsBodyTooLarge

func IsBodyTooLarge(err error) bool

func LoadPluginMetadata

func LoadPluginMetadata[T any](name string) (metadata T)

LoadPluginMetadata returns the stored plugin metadata or a zero value. The store getters guard against a missing process-wide store, so no panic can be masked here; errors are returned as zero metadata.

func LogSnapshotValue

func LogSnapshotValue(snapshot LogSnapshot, name string) any

func MaterializePluginSecrets

func MaterializePluginSecrets(p any) error

MaterializePluginSecrets runs the pre-PostInit secret phase. Plugins that expose a secret reference in Config must declare ownership by implementing SecretMaterializer.

func NestedLogMap

func NestedLogMap(fields map[string]any, key string) map[string]any

func NewBatchProcessor

func NewBatchProcessor(
	name string,
	d BatchDefaults,
	routeID, serverAddr string,
	deliver logger_batch.ContextDeliveryFunc,
) *logger_batch.Processor

NewBatchProcessor constructs a logger batch processor from second-based batch defaults.

func NumberClaim

func NumberClaim(value any) (int64, bool)

NumberClaim converts a JSON-decoded numeric claim to an int64.

func OpenOAuthSession

func OpenOAuthSession(
	encoded string,
	secret string,
	fallbacks []string,
	fingerprint string,
	now time.Time,
) ([]byte, error)

OpenOAuthSession decrypts a bounded OAuth session with the primary secret or one of its rotation fallbacks and validates its version, expiry, and config.

func OriginLogEntries

func OriginLogEntries(entries []map[string]any, originKey string) ([]string, bool)

OriginLogEntries unwraps raw origin entries only when every batch entry contains a string under originKey.

func PrepareExprRegexps

func PrepareExprRegexps(expressionSets ...any) error

PrepareExprRegexps compiles configured logger expression patterns before they enter the request path. An invalid pattern fails plugin initialization so a malformed expression never reaches request handling.

func ProtocolVersion

func ProtocolVersion(r *http.Request) string

ProtocolVersion returns the request protocol version as major.minor.

func ReadAndRestoreRequestBody

func ReadAndRestoreRequestBody(r *http.Request, limit int) (string, error)

func ReadRequestBody

func ReadRequestBody(r *http.Request) ([]byte, error)

func ReadRequestBodyLimited

func ReadRequestBodyLimited(r *http.Request, maxSize int) ([]byte, error)

ReadRequestBodyLimited reads and restores the request body while rejecting bodies larger than maxSize with a size-exceeded error.

func ReadResponseBodyLimited

func ReadResponseBodyLimited(reader io.Reader, maxSize int64) ([]byte, error)

func ReadSharedRequestBody

func ReadSharedRequestBody(r *http.Request, limit int) (string, error)

ReadSharedRequestBody returns the current request body up to limit bytes. The first logger captures and restores r.Body, then adjacent logger plugins reuse that capture. This cache is separate from the request-variable body cache because higher-priority plugins may rewrite r.Body after validation.

func RemoteIP

func RemoteIP(remoteAddr string) string

func RemoveHTTP2ConnectionHeaders

func RemoveHTTP2ConnectionHeaders(header http.Header)

RemoveHTTP2ConnectionHeaders removes response headers that cannot be forwarded on an HTTP/2 downstream connection.

func ReplaceRequestBody

func ReplaceRequestBody(r *http.Request, body []byte)

func RequestInt64

func RequestInt64(r *http.Request, key string) int64

RequestInt64 reads an int-valued apisix request variable.

func RequestURL

func RequestURL(r *http.Request, serverAddr string) string

RequestURL reconstructs the request URL including the server address.

func RequestVar

func RequestVar(r *http.Request, name string, status int) string

func RequestVarFromNginx

func RequestVarFromNginx(r *http.Request, key string) string

func RequireStringLogFormat

func RequireStringLogFormat(pluginName string, route, metadata map[string]string) (map[string]string, error)

RequireStringLogFormat selects a non-empty route log format, falling back to plugin metadata when the route does not provide one. The returned map is owned by the caller and is safe to update without mutating either input.

func ResolveLogFormat

func ResolveLogFormat(format map[string]any, resolve func(string) any) map[string]any

ResolveLogFormat recursively resolves string leaves while preserving maps and non-string values.

func ResolveRequestVariables

func ResolveRequestVariables(value string, lookup func(name string) string) string

ResolveRequestVariables replaces each $name variable reference in value with the lookup result for name. Lookup receives the name without the leading dollar sign.

func ResolveStringLogFormat

func ResolveStringLogFormat(format map[string]string, resolve func(string) any) map[string]any

ResolveStringLogFormat resolves every value in a flat string log format.

func ResponseAllowsBody

func ResponseAllowsBody(method string, status int) bool

ResponseAllowsBody reports whether method/status permits response body bytes. 101 is a final switching-protocols response and is bodyless here.

func SealOAuthSession

func SealOAuthSession(
	payload []byte,
	secret string,
	fingerprint string,
	issuedAt time.Time,
	expiresAt time.Time,
) (string, error)

SealOAuthSession encrypts a bounded OAuth session using the primary secret.

func Sha256Hex

func Sha256Hex(value string) string

Sha256Hex returns the lowercase hex SHA-256 digest of value.

func SignRawSessionValue

func SignRawSessionValue(payload []byte, secret string) string

SignRawSessionValue signs a payload as base64url(payload) + "." + base64url(HMAC-SHA256(payload, secret)). Unlike SignSessionValue, the HMAC covers the raw payload bytes, not the encoded payload.

func SignSessionValue

func SignSessionValue(value []byte, secret string) string

SignSessionValue signs a payload for a session cookie as base64url(payload) + "." + base64url(HMAC-SHA256(base64url(payload), secret)).

func SnapshotExpressionMatches

func SnapshotExpressionMatches(snapshot LogSnapshot, expressions any) bool

SnapshotExpressionMatches preserves the legacy logger expression grammar while resolving every variable from the detached snapshot.

func SnapshotRequestBody

func SnapshotRequestBody(snapshot LogSnapshot, limit int) string

SnapshotRequestBody returns a bounded detached request body.

func SnapshotResponseBody

func SnapshotResponseBody(snapshot LogSnapshot, limit int) string

SnapshotResponseBody returns a bounded response body, decoding the same gzip/brotli encodings handled by the legacy response recorder.

func SnapshotValue

func SnapshotValue(snapshot LogSnapshot, expression string) any

SnapshotValue resolves one access-log expression without consulting a live request. Literal values are preserved as strings, matching legacy format resolution.

func TruncateLogFormat

func TruncateLogFormat(format map[string]any, maxDepth int) (map[string]any, bool)

TruncateLogFormat copies format and replaces nested objects at maxDepth with empty maps. The returned bool reports whether any non-empty object was truncated.

func UpstreamAddress

func UpstreamAddress(r *http.Request) string

UpstreamAddress joins the balancer ip/port request variables.

func ValidateLogCapturePolicy

func ValidateLogCapturePolicy(policy LogCapturePolicy) error

ValidateLogCapturePolicy enforces the existing hard body ceilings. Zero is intentional and means that the corresponding body is not captured.

func VerifyRawSessionValue

func VerifyRawSessionValue(signed, secret string, fallbacks []string) ([]byte, bool)

VerifyRawSessionValue verifies a raw-payload signed value against secret and fallbacks and returns the decoded payload.

func VerifySessionValue

func VerifySessionValue(signed, secret string, fallbacks []string) ([]byte, bool)

VerifySessionValue verifies a signed value against secret and fallbacks and returns the decoded payload.

func WithCacheHitResponseHolder

func WithCacheHitResponseHolder(r *http.Request, holder *CacheHitResponseHolder) *http.Request

func WithResponseCapture

func WithResponseCapture(r *http.Request, capture *ResponseCapture) *http.Request

func WithTransformPipeline

func WithTransformPipeline(count int) func(http.Handler) http.Handler

WithTransformPipeline marks a handler chain containing response-transform plugins. Chains with zero or one transform preserve standalone buffering; chains with multiple transforms share one response body buffer.

func WriteJSONMessage

func WriteJSONMessage(w http.ResponseWriter, status int, message string)

WriteJSONMessage preserves the plugin-base API for existing callers while using the canonical response writer in util.

Types

type AccessLogRequest

type AccessLogRequest struct {
	Method        string
	URI           string
	URL           string
	Host          string
	ClientIP      string
	ContentLength int64
	Headers       map[string]any
	QueryString   map[string]any
	Started       time.Time
}

AccessLogRequest is the captured request snapshot shared by the access-log style logger plugins.

func CaptureAccessLogRequest

func CaptureAccessLogRequest(r *http.Request, started time.Time, serverAddr string) AccessLogRequest

CaptureAccessLogRequest snapshots a request for an access-log entry.

func CaptureMinimalAccessLogRequest

func CaptureMinimalAccessLogRequest(r *http.Request, started time.Time) AccessLogRequest

CaptureMinimalAccessLogRequest captures only fields needed by custom log formats, avoiding header/query snapshots when the default log is disabled.

type AuthorizationFacts

type AuthorizationFacts struct {
	Version    int                   `json:"version"`
	Scheme     string                `json:"scheme"`
	Method     string                `json:"method"`
	Host       string                `json:"host"`
	Path       string                `json:"path"`
	RawQuery   string                `json:"raw_query,omitempty"`
	Headers    map[string][]string   `json:"headers"`
	ClientIP   string                `json:"client_ip"`
	ClientPort string                `json:"client_port,omitempty"`
	ServerAddr string                `json:"server_addr,omitempty"`
	ServerPort string                `json:"server_port,omitempty"`
	Route      AuthorizationResource `json:"route,omitempty"`   //nolint:modernize // fixed external-authorization interface
	Service    AuthorizationResource `json:"service,omitempty"` //nolint:modernize // fixed external-authorization interface
}

AuthorizationFacts is the immutable request snapshot shared by external authorization plugins.

func CaptureAuthorizationFacts

func CaptureAuthorizationFacts(
	r *http.Request,
	serverAddr string,
	route AuthorizationResource,
	service AuthorizationResource,
) AuthorizationFacts

CaptureAuthorizationFacts captures only the request and safe resource identity fields needed by external authorization plugins.

type AuthorizationResource

type AuthorizationResource struct {
	ID   string `json:"id,omitempty"`
	Name string `json:"name,omitempty"`
	URI  string `json:"uri,omitempty"`
}

AuthorizationResource is the safe identity subset of an APISIX resource that may be included in an external-authorization input.

type BaseLoggerPlugin

type BaseLoggerPlugin struct {
	BasePlugin

	FireChan   chan map[string]any
	AsyncBlock bool

	LogFormat map[string]string
	// SnapshotLogFormat is used by plugins whose public log format supports
	// nested values. LogFormat remains the compatibility representation for
	// flat APISIX logger formats.
	SnapshotLogFormat      map[string]any
	SnapshotLogFormatExtra map[string]any
	RequestBodyExpr        any
	ResponseBodyExpr       any
	RequestBodyBytes       int
	ResponseBodyBytes      int

	SendFunc       func(log map[string]any)
	BatchProcessor *logger_batch.Processor
	RouteID        string
	ServerAddr     string

	IncludeRequestBody  bool
	IncludeResponseBody bool
	// contains filtered or unexported fields
}

func (*BaseLoggerPlugin) EnqueueLog

func (p *BaseLoggerPlugin) EnqueueLog(entry map[string]any) error

EnqueueLog exposes the non-blocking delivery boundary used by detached log callbacks. BatchProcessor.Push is the only permitted production path.

func (*BaseLoggerPlugin) Fire

func (p *BaseLoggerPlugin) Fire(entry map[string]any) error

func (*BaseLoggerPlugin) Handler

func (p *BaseLoggerPlugin) Handler(next http.Handler) http.Handler

func (*BaseLoggerPlugin) InitLogger

func (p *BaseLoggerPlugin) InitLogger(send func(map[string]any))

InitLogger initializes the buffered fire channel, blocking policy and the per-plugin Send function.

func (*BaseLoggerPlugin) LogCapturePolicy

func (p *BaseLoggerPlugin) LogCapturePolicy() LogCapturePolicy

LogCapturePolicy returns the body limits configured on the logger. A zero limit means that body bytes are not required by this logger.

func (*BaseLoggerPlugin) RunLogPhase

func (p *BaseLoggerPlugin) RunLogPhase(snapshot LogSnapshot) error

RunLogPhase resolves fields from a detached snapshot and enqueues them on the bounded batch processor. It never falls back to Fire, whose historical AsyncBlock behavior can block a request goroutine.

func (*BaseLoggerPlugin) SetLogCapturePolicy

func (p *BaseLoggerPlugin) SetLogCapturePolicy(
	includeRequest, includeResponse bool,
	requestBytes, responseBytes int,
	requestExpr, responseExpr any,
)

SetLogCapturePolicy wires a logger's bounded body policy into the detached callback implementation while leaving its legacy Handler untouched.

func (*BaseLoggerPlugin) SetRouteContext

func (p *BaseLoggerPlugin) SetRouteContext(routeID string, serverAddr string)

func (*BaseLoggerPlugin) SetSnapshotLogFormat

func (p *BaseLoggerPlugin) SetSnapshotLogFormat(format, extra map[string]any)

func (*BaseLoggerPlugin) Stop

func (p *BaseLoggerPlugin) Stop()

func (*BaseLoggerPlugin) StopWithCleanup

func (p *BaseLoggerPlugin) StopWithCleanup(cleanup func())

StopWithCleanup retains sink resources until every batch delivery callback has returned, while preserving the processor's bounded caller-facing stop.

type BasePlugin

type BasePlugin struct {
	Name           string
	Priority       int
	Schema         string
	MetadataSchema string
}

func (*BasePlugin) GetMetadataSchema

func (p *BasePlugin) GetMetadataSchema() string

func (*BasePlugin) GetName

func (p *BasePlugin) GetName() string

func (*BasePlugin) GetPriority

func (p *BasePlugin) GetPriority() int

func (*BasePlugin) GetSchema

func (p *BasePlugin) GetSchema() string

func (*BasePlugin) SetPriority

func (p *BasePlugin) SetPriority(priority int)

type BatchDefaults

type BatchDefaults struct {
	BatchMaxSize       int
	MaxRetryCount      int
	RetryDelaySec      int
	RetryDelaySet      bool
	BufferDurationSec  int
	InactiveTimeoutSec int
	MaxPendingEntries  int
	PluginID           string

	// Resource overrides are internal until each logger schema exposes them.
	MaxConcurrentDeliveries int
	DeliveryTimeoutSec      int
	ShutdownTimeoutSec      int
}

BatchDefaults carries the per-plugin batch configuration values in seconds.

type BindingPhaseDescriber

type BindingPhaseDescriber interface {
	DescribeBindingPhases() (BindingPhaseDescriptor, error)
}

BindingPhaseDescriber lets config-aware plugins describe the one request stage and response phases selected by their initialized configuration.

type BindingPhaseDescriptor

type BindingPhaseDescriptor struct {
	RequestStage string
	Header       bool
	BufferedBody bool
	Log          bool
}

BindingPhaseDescriptor is the config-derived part of a checked plugin binding. The root plugin package validates the exact request-stage strings and response capability mask for each factory identity.

type BodyTooLargeError

type BodyTooLargeError struct {
	Limit int64
}

BodyTooLargeError reports a bounded read that retained at most Limit+1 bytes. Callers can map this error to the protocol-specific 413/502 status.

func (*BodyTooLargeError) Error

func (e *BodyTooLargeError) Error() string

type BufferedBodyFilterPlugin

type BufferedBodyFilterPlugin interface {
	RunBufferedBodyFilter(*http.Request, *ResponseState) error
}

type BufferedResponseConfig

type BufferedResponseConfig struct {
	MaxBytes int64
}

BufferedResponseConfig controls the bounded response capture.

type BufferedResponseWriter

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

BufferedResponseWriter delays header and body commitment until Commit, allowing the response to be inspected, rewritten and replayed. Distinct from ResponseRecorder, which forwards writes immediately for observers.

In pipeline mode (bodyPtr != nil) multiple BufferedResponseWriter instances share the same underlying bytes.Buffer; Commit detects this and skips the body copy when committing between pipeline writers.

func GetOrCreateTransformResponseWriter

func GetOrCreateTransformResponseWriter(r *http.Request) *BufferedResponseWriter

GetOrCreateTransformResponseWriter returns a BufferedResponseWriter for transform plugins. When multiple transform plugins are present in the handler chain, all returned writers share a single underlying bytes.Buffer via a pipelineBuffer stored in request context. This eliminates O(N) copies of the response body.

Each writer still has its own header map and status code; Commit copies headers between writers and only the final commit writes to the real http.ResponseWriter.

func NewBufferedResponseWriter

func NewBufferedResponseWriter() *BufferedResponseWriter

func (*BufferedResponseWriter) Body

func (w *BufferedResponseWriter) Body() []byte

func (*BufferedResponseWriter) Commit

Commit writes the buffered headers, status and body to dst. When dst is another BufferedResponseWriter that shares the same pipeline buffer, the body copy is skipped (the buffer is already shared).

func (*BufferedResponseWriter) CommitCaptured

func (w *BufferedResponseWriter) CommitCaptured(dst http.ResponseWriter) bool

CommitCaptured replays captured informational responses and commits the final response only when one was actually written. It lets an undecided request become transparent without manufacturing a default 200 response.

func (*BufferedResponseWriter) CommitFinalResponse

func (w *BufferedResponseWriter) CommitFinalResponse(
	dst http.ResponseWriter,
	state ResponseState,
)

CommitFinalResponse replaces only the final canonical representation before using the existing commit path. In particular, private informational responses captured before the final response are retained; Reset must not be used here because it deliberately clears that history.

func (*BufferedResponseWriter) Header

func (w *BufferedResponseWriter) Header() http.Header

func (*BufferedResponseWriter) ReplaceBody

func (w *BufferedResponseWriter) ReplaceBody(body []byte)

ReplaceBody replaces the buffered body and invalidates metadata derived from the previous representation. SetBody intentionally remains a raw operation for callers that already own representation metadata.

func (*BufferedResponseWriter) Reset

func (w *BufferedResponseWriter) Reset()

Reset discards all buffered response state so an error response can replace a failed transformation cleanly, including in a shared transform pipeline.

func (*BufferedResponseWriter) SetBody

func (w *BufferedResponseWriter) SetBody(body []byte)

SetBody replaces the buffered body content.

func (*BufferedResponseWriter) SetStatusCode

func (w *BufferedResponseWriter) SetStatusCode(statusCode int)

SetStatusCode overrides the buffered status, used by response-transform plugins that rewrite the status after capture.

func (*BufferedResponseWriter) StatusCode

func (w *BufferedResponseWriter) StatusCode() int

func (*BufferedResponseWriter) Write

func (w *BufferedResponseWriter) Write(body []byte) (int, error)

func (*BufferedResponseWriter) WriteBodyTo

func (w *BufferedResponseWriter) WriteBodyTo(dst http.ResponseWriter)

WriteBodyTo writes the buffered body to dst. When dst is another BufferedResponseWriter that shares the same pipeline buffer, the body write is a no-op (the data is already shared).

This is useful for plugins that write headers/status/body manually instead of using Commit.

func (*BufferedResponseWriter) WriteHeader

func (w *BufferedResponseWriter) WriteHeader(statusCode int)

type CacheHitResponseHolder

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

CacheHitResponseHolder transports one cache-hit response without making writer calls in the request phase. Publication and consumption deep-copy all mutable response values and consumption is exactly once.

func CacheHitResponseHolderFromRequest

func CacheHitResponseHolderFromRequest(r *http.Request) *CacheHitResponseHolder

func NewCacheHitResponseHolder

func NewCacheHitResponseHolder() *CacheHitResponseHolder

func (*CacheHitResponseHolder) Consume

func (*CacheHitResponseHolder) ConsumePublished

func (h *CacheHitResponseHolder) ConsumePublished() (CachedResponseState, bool, error)

ConsumePublished distinguishes a missing publication from a consumed hit; both remain exactly-once operations, while callers can fail closed when the lifecycle source claims CacheHit without a published representation.

func (*CacheHitResponseHolder) Publish

func (h *CacheHitResponseHolder) Publish(state CachedResponseState)

func (*CacheHitResponseHolder) Published

func (h *CacheHitResponseHolder) Published() bool

type CachedResponseState

type CachedResponseState struct {
	Status  int
	Header  http.Header
	Trailer http.Header
	Body    []byte
}

CachedResponseState is the immutable representation handed from a cache lookup to the response executor. It intentionally mirrors only the canonical response fields.

type ExclusiveProtocolTerminal

type ExclusiveProtocolTerminal interface {
	RunExclusiveProtocol(
		http.ResponseWriter,
		*http.Request,
		http.Handler,
	) (ProtocolDisposition, *http.Request, apisixctx.ResponseSource, error)
}

ExclusiveProtocolTerminal owns one protocol response. The continuation is supplied so protocol translators can frame a normal upstream response while terminal-only owners can ignore it. The source must be selected before the owner writes, flushes, or hijacks.

type FinalResponseStorePlugin

type FinalResponseStorePlugin interface {
	RunFinalResponseStore(*http.Request, ResponseState) error
}

type HeaderFilterPlugin

type HeaderFilterPlugin interface {
	RunHeaderFilter(*http.Request, *ResponseState) error
}

type JWTToken

type JWTToken struct {
	Header    map[string]any
	Payload   map[string]any
	Signing   string
	Signature []byte
}

JWTToken is the parsed representation of an unverified JWT.

func ParseJWT

func ParseJWT(raw string) (JWTToken, error)

ParseJWT splits and decodes a three-part JWT without verifying it.

type LogCapturePolicy

type LogCapturePolicy struct {
	RequestBodyBytes  int
	ResponseBodyBytes int
}

func LogCapturePolicyForFormats

func LogCapturePolicyForFormats(requestBytes, responseBytes int, formats ...any) LogCapturePolicy

LogCapturePolicyForFormats derives bounded body capture requirements from the configured logger formats without retaining plugin configuration in the detached callback.

type LogCapturePolicyPlugin

type LogCapturePolicyPlugin interface {
	LogCapturePolicy() LogCapturePolicy
}

type LogPhasePlugin

type LogPhasePlugin interface {
	RunLogPhase(LogSnapshot) error
}

type LogSnapshot

type LogSnapshot = apisixlog.LogSnapshot

LogSnapshot is the plugin-facing alias for the detached canonical snapshot.

func BuildLogSnapshot

func BuildLogSnapshot(
	r *http.Request,
	response ResponseCaptureSnapshot,
	outcome apisixctx.ResponseOutcome,
	source apisixctx.ResponseSource,
	started,
	finished time.Time,
) LogSnapshot

BuildLogSnapshot converts the outer response capture into the detached canonical representation used by all log/finalizer callbacks.

func BuildLogSnapshotFromOwnedInputs

func BuildLogSnapshotFromOwnedInputs(
	r *http.Request,
	response ResponseCaptureSnapshot,
	requestBody []byte,
	requestBodyTruncated bool,
	outcome apisixctx.ResponseOutcome,
	source apisixctx.ResponseSource,
	started,
	finished time.Time,
) LogSnapshot

BuildLogSnapshotFromOwnedInputs transfers detached response capture and a previously captured request body into a canonical snapshot. The request is inspected only for metadata; its live body is never read.

func CloneLogSnapshotForPolicy

func CloneLogSnapshotForPolicy(snapshot LogSnapshot, policy LogCapturePolicy) LogSnapshot

CloneLogSnapshotForPolicy gives one callback a private bounded view. Every invocation returns a fresh clone, including when both body limits are zero.

type LogSnapshotSanitizerPlugin

type LogSnapshotSanitizerPlugin interface {
	SanitizeLogSnapshot(*LogSnapshot) error
}

LogSnapshotSanitizerPlugin mutates only the detached canonical logging snapshot. The log executor runs sanitizers before cloning the snapshot for any logger or snapshot finalizer callback.

type LogSnapshotSanitizerSelectorPlugin

type LogSnapshotSanitizerSelectorPlugin interface {
	ShouldSanitizeLogSnapshot(LogSnapshot) bool
}

LogSnapshotSanitizerSelectorPlugin optionally restricts a sanitizer to a detached snapshot. The log executor evaluates every selector against the same pre-sanitized snapshot before running any sanitizer callback.

type ProtocolDisposition

type ProtocolDisposition uint8
const (
	ProtocolResponded ProtocolDisposition = iota + 1
	ProtocolHijacked
)

type RedisClusterConnConfig

type RedisClusterConnConfig struct {
	Nodes                                    []string
	Password                                 string
	Timeout, KeepaliveTimeout, KeepalivePool int
	SSL, SSLVerify                           *bool
}

RedisClusterConnConfig is the narrow redis-cluster connection configuration shared by the rate-limit plugins.

func (RedisClusterConnConfig) ClusterOptions

func (c RedisClusterConnConfig) ClusterOptions() *redis.ClusterOptions

ClusterOptions builds a cluster redis.ClusterOptions. Timeout and KeepaliveTimeout are in milliseconds.

type RedisConnConfig

type RedisConnConfig struct {
	Host, Username, Password                                 string
	Port, Database, Timeout, KeepaliveTimeout, KeepalivePool int
	SSL, SSLVerify                                           *bool
}

RedisConnConfig is the narrow standalone Redis connection configuration shared by the rate-limit plugins.

func (RedisConnConfig) Options

func (c RedisConnConfig) Options() *redis.Options

Options builds a standalone redis.Options. Timeout and KeepaliveTimeout are in milliseconds, matching the rate-limit plugin configuration.

type RequestDecision

type RequestDecision uint8
const (
	RequestContinue RequestDecision = iota
	RequestStop
)

type RequestPhasePlugin

type RequestPhasePlugin interface {
	RunRequestPhase(http.ResponseWriter, *http.Request) RequestPhaseResult
}

type RequestPhaseResult

type RequestPhaseResult struct {
	Request  *http.Request
	Decision RequestDecision
	Source   apisixctx.ResponseSource
}

func ContinueRequest

func ContinueRequest(r *http.Request) RequestPhaseResult

func StopRequest

func StopRequest(r *http.Request) RequestPhaseResult

func StopRequestWithSource

func StopRequestWithSource(r *http.Request, source apisixctx.ResponseSource) RequestPhaseResult

type RequestResponseMode

type RequestResponseMode uint8

RequestResponseMode is the one concrete response path selected after all request phases have prepared request-local protocol state and before the first terminal response byte is written.

const (
	RequestResponseModeBounded RequestResponseMode = iota + 1
	RequestResponseModeStreaming
)

type RequestResponseModeSelector

type RequestResponseModeSelector interface {
	SelectResponseMode(*http.Request) RequestResponseMode
}

RequestResponseModeSelector is required when one binding declares both a bounded and streaming response callback. Selection is request-local; a generation must never execute both callbacks for one response.

type ResponseCapture

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

ResponseCapture is the sole outer response observer. It records outcome metadata for every response while retaining a bounded body only when a log binding explicitly enables it.

func CaptureResponseOutcomeController

func CaptureResponseOutcomeController(w http.ResponseWriter) (http.ResponseWriter, *ResponseCapture)

CaptureResponseOutcomeController installs one response capture controller around w. The compatibility wrapper below exposes the historical callback tuple while independent callers migrate to the controller API.

func ResponseCaptureFromRequest

func ResponseCaptureFromRequest(r *http.Request) (*ResponseCapture, bool)

func (*ResponseCapture) CloseHijacked

func (c *ResponseCapture) CloseHijacked() error

func (*ResponseCapture) EnableBodyCapture

func (c *ResponseCapture) EnableBodyCapture(limit int) error

func (*ResponseCapture) Outcome

func (c *ResponseCapture) Outcome() ctx.ResponseOutcome

func (*ResponseCapture) RecordFailure

func (c *ResponseCapture) RecordFailure(reason ctx.ResponseFailureReason) bool

RecordFailure attaches the first bounded transport/application failure to the final response outcome. Raw errors are deliberately excluded.

func (*ResponseCapture) Snapshot

type ResponseCaptureSnapshot

type ResponseCaptureSnapshot struct {
	Header        http.Header
	Trailer       http.Header
	Body          []byte
	BodyTruncated bool
}

ResponseCaptureSnapshot is the detached bounded response view used by log snapshots. Body capture is disabled until EnableBodyCapture is called.

type ResponseEligibility

type ResponseEligibility interface {
	AppliesToResponseSource(apisixctx.ResponseSource) bool
}

type ResponseModeDescriber

type ResponseModeDescriber interface {
	DescribeResponseMode() (ResponseModeDescriptor, error)
}

ResponseModeDescriber is implemented by config-aware plugins whose mode cannot be determined from their factory identity alone.

type ResponseModeDescriptor

type ResponseModeDescriptor struct {
	Modes ResponseModeMask
}

type ResponseModeMask

type ResponseModeMask uint8

ResponseModeMask describes the response modes a plugin can select after its configuration has been initialized. A mask is used because a plugin may support both bounded and streaming responses while remaining incompatible with hijacking.

const (
	ResponseModeNone      ResponseModeMask = 0
	ResponseModeBounded   ResponseModeMask = 1 << 0
	ResponseModeStreaming ResponseModeMask = 1 << 1
	ResponseModeHijack    ResponseModeMask = 1 << 2
)

type ResponseRecorder

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

ResponseRecorder forwards responses while retaining a bounded response body and the status code for logger plugins.

func NewResponseRecorder

func NewResponseRecorder(w http.ResponseWriter, limit int) *ResponseRecorder

func (*ResponseRecorder) Body

func (w *ResponseRecorder) Body() string

func (*ResponseRecorder) HasBody

func (w *ResponseRecorder) HasBody() bool

func (*ResponseRecorder) StatusCode

func (w *ResponseRecorder) StatusCode() int

func (*ResponseRecorder) Write

func (w *ResponseRecorder) Write(body []byte) (int, error)

func (*ResponseRecorder) WriteHeader

func (w *ResponseRecorder) WriteHeader(status int)

type ResponseState

type ResponseState struct {
	Status  int
	Header  http.Header
	Trailer http.Header
	Body    []byte
}

ResponseState is the canonical response representation passed between response callbacks. Keep this deliberately limited to status, headers, trailers and body; request/lifecycle/cache state belongs to their owners.

func CloneResponseState

func CloneResponseState(state ResponseState) ResponseState

type SecretMaterializer

type SecretMaterializer interface {
	MaterializeSecrets() error
}

SecretMaterializer resolves generation-owned credentials after schema decoding and before PostInit.

type SharedResponseRecorder

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

SharedResponseRecorder captures response body once per request and is shared across multiple logger plugins to avoid O(logger × body) buffer duplication.

func GetOrCreateSharedResponseRecorderWithLimit

func GetOrCreateSharedResponseRecorderWithLimit(
	w http.ResponseWriter,
	r *http.Request,
	limit int,
) *SharedResponseRecorder

func NewSharedResponseRecorder

func NewSharedResponseRecorder(w http.ResponseWriter) *SharedResponseRecorder

NewSharedResponseRecorder creates a new shared response recorder wrapping w.

func (*SharedResponseRecorder) Body

func (w *SharedResponseRecorder) Body() string

Body returns the full captured response body as a string.

func (*SharedResponseRecorder) BodyBytes

func (w *SharedResponseRecorder) BodyBytes() []byte

func (*SharedResponseRecorder) BodyDecoded

func (w *SharedResponseRecorder) BodyDecoded(limit int, encoding string) string

BodyDecoded returns the captured response body after decoding gzip or Brotli. The decoded representation is cached per response so adjacent logger plugins do not repeat the decompression or byte-to-string conversion.

func (*SharedResponseRecorder) BodyTruncated

func (w *SharedResponseRecorder) BodyTruncated(limit int) string

BodyTruncated returns the response body as a string, truncated to limit bytes.

func (*SharedResponseRecorder) HasBody

func (w *SharedResponseRecorder) HasBody() bool

func (*SharedResponseRecorder) StatusCode

func (w *SharedResponseRecorder) StatusCode() int

func (*SharedResponseRecorder) Write

func (w *SharedResponseRecorder) Write(body []byte) (int, error)

func (*SharedResponseRecorder) WriteHeader

func (w *SharedResponseRecorder) WriteHeader(status int)

type SnapshotFinalizerPlugin

type SnapshotFinalizerPlugin interface {
	RunSnapshotFinalizer(LogSnapshot) error
}

type StreamingBodyFilterPlugin

type StreamingBodyFilterPlugin interface {
	WrapStreamingResponse(http.ResponseWriter, *http.Request) (http.ResponseWriter, error)
}

type StreamingHeaderFilterPlugin

type StreamingHeaderFilterPlugin interface {
	RunStreamingHeaderFilter(*http.Request, *StreamingResponseState) error
}

type StreamingResponseFinalizer

type StreamingResponseFinalizer interface {
	FinishStreamingResponse(error) error
}

StreamingResponseFinalizer is optional lifecycle ownership for wrappers that retain encoder or connection state. The executor invokes it exactly once with nil on normal completion or the terminal error/panic.

type StreamingResponseState

type StreamingResponseState struct {
	Status  int
	Header  http.Header
	Trailer http.Header
}

StreamingResponseState is the mutable response metadata handed to a streaming header phase. Trailer is kept separate from Header so a wrapper can preserve trailer declarations without treating them as ordinary fields.

func CloneStreamingResponseState

func CloneStreamingResponseState(state StreamingResponseState) StreamingResponseState

Jump to

Keyboard shortcuts

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