client

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Apr 7, 2026 License: MIT Imports: 26 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// DefaultCacheSize is the default maximum number of templates to cache
	DefaultCacheSize = 100
)
View Source
const EnvelopeVersion = "1"

EnvelopeVersion is the current version of the webhook envelope schema.

View Source
const MaxTemplateOutputBytes = 1 * 1024 * 1024 // 1 MB

MaxTemplateOutputBytes is the maximum allowed output size from a template execution. Templates producing output larger than this are aborted to prevent denial-of-service via crafted templates.

View Source
const TemplateExecutionTimeout = 5 * time.Second

TemplateExecutionTimeout limits CPU time for template execution. Go's text/template has no built-in cancellation, so we run Execute in a goroutine and abandon it on timeout. This prevents a malicious template with tight loops from monopolising a worker indefinitely.

Variables

This section is empty.

Functions

func BuildEnvelopePayload

func BuildEnvelopePayload(
	eventID string,
	eventName string,
	attempt int,
	payload map[string]any,
) ([]byte, error)

BuildEnvelopePayload constructs the default webhook body as a JSON envelope. Namespace, WebhookID, and DeliveryID are not included in the body; they are sent as X-Sparrow-* HTTP headers instead.

func BuildRequest

func BuildRequest(ctx context.Context, dr *DeliveryRequest) (*http.Request, error)

BuildRequest creates an HTTP request from the delivery request

func GetBuffer

func GetBuffer() *bytes.Buffer

GetBuffer retrieves a buffer from the pool

func GetFunctionDocumentation

func GetFunctionDocumentation() string

GetFunctionDocumentation returns markdown documentation for all template functions

func GetFunctionMap

func GetFunctionMap() template.FuncMap

GetFunctionMap returns a template.FuncMap with all utility functions

func GetHeaderMap

func GetHeaderMap() map[string]string

GetHeaderMap retrieves a header map from the pool

func PutBuffer

func PutBuffer(buf *bytes.Buffer)

PutBuffer returns a buffer to the pool

func PutHeaderMap

func PutHeaderMap(m map[string]string)

PutHeaderMap returns a header map to the pool

func ReadBody

func ReadBody(resp *http.Response, limit int64) ([]byte, error)

ReadBody reads the response body safely using a pooled buffer

func ValidateIP

func ValidateIP(ip net.IP) error

ValidateIP checks whether an IP address is safe for outbound webhook delivery. It blocks loopback, private, link-local, multicast, unspecified addresses, cloud metadata endpoints, and IPv6-mapped IPv4 private addresses.

Types

type Config

type Config struct {
	Timeout            time.Duration
	MaxIdleConns       int
	MaxConnsPerHost    int
	IdleConnTimeout    time.Duration
	DisableKeepAlives  bool
	InsecureSkipVerify bool

	// AllowPrivateNetworks disables SSRF protection, permitting webhooks
	// to target loopback and private-network addresses. Useful for
	// self-hosted deployments where webhook targets live on the same
	// network, and required for tests that use httptest.NewServer.
	AllowPrivateNetworks bool
}

Config holds configuration for the webhook client

func DefaultConfig

func DefaultConfig() *Config

DefaultConfig returns the default configuration

type DeliveryRequest

type DeliveryRequest struct {
	WebhookID  uuid.UUID
	DeliveryID string
	URL        string
	Method     string
	Headers    map[string]string
	Payload    []byte
	Secret     string
	Timeout    time.Duration
	RetryCount int
	MaxRetries int
	EventID    uuid.UUID
	EventName  string
	Namespace  string
}

DeliveryRequest represents the data needed to send a webhook

func PrepareDeliveryRequest

func PrepareDeliveryRequest(
	webhook *store.WebhookRegistration,
	sub *store.EventSubscription,
	event *store.EventRecord,
	deliveryID string,
	payload []byte,
	cryptoSvc *crypto.Service,
) *DeliveryRequest

PrepareDeliveryRequest creates a DeliveryRequest from subscription and event data. If cryptoSvc is provided and the webhook has encrypted secret headers, they are decrypted and merged after regular + subscription headers (secret headers win).

type Metrics

type Metrics struct {

	// Request counters
	TotalRequests   int64
	SuccessRequests int64
	FailedRequests  int64

	// Response time tracking
	TotalResponseTime time.Duration
	MinResponseTime   time.Duration
	MaxResponseTime   time.Duration
	// contains filtered or unexported fields
}

Metrics tracks webhook client performance metrics

func NewMetrics

func NewMetrics() *Metrics

NewMetrics creates a new metrics instance

func (*Metrics) RecordFailure

func (m *Metrics) RecordFailure(duration time.Duration)

RecordFailure increments failure counter

func (*Metrics) RecordRequest

func (m *Metrics) RecordRequest()

RecordRequest increments total request counter

func (*Metrics) RecordSuccess

func (m *Metrics) RecordSuccess(duration time.Duration)

RecordSuccess increments success counter

type TemplateCache

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

TemplateCache implements an LRU cache for parsed templates using github.com/hashicorp/golang-lru which provides a thread-safe, size-bounded LRU cache with O(1) operations.

func NewTemplateCache

func NewTemplateCache(maxSize int) *TemplateCache

NewTemplateCache creates a new LRU cache with the specified maximum size

func (*TemplateCache) Get

func (c *TemplateCache) Get(key string) (*template.Template, bool)

Get retrieves a template from the cache

func (*TemplateCache) Put

func (c *TemplateCache) Put(key string, tmpl *template.Template)

Put adds a template to the cache

type TemplateEngine

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

TemplateEngine handles payload transformations using Go templates

func NewTemplateEngine

func NewTemplateEngine() *TemplateEngine

NewTemplateEngine creates a new template engine with default helpers

func NewTemplateEngineWithCacheSize

func NewTemplateEngineWithCacheSize(maxSize int) *TemplateEngine

NewTemplateEngineWithCacheSize creates a new template engine with custom cache size

func (*TemplateEngine) Execute

func (e *TemplateEngine) Execute(tmplStr string, data any) ([]byte, error)

Execute processes a template with the given data. Output is limited to MaxTemplateOutputBytes and execution time is limited to TemplateExecutionTimeout to prevent denial-of-service via crafted templates that consume unbounded CPU or produce unbounded output.

func (*TemplateEngine) TransformPayload

func (e *TemplateEngine) TransformPayload(tmplStr string, data WebhookTemplateContext) ([]byte, error)

TransformPayload applies the template if enabled

func (*TemplateEngine) ValidateTemplate

func (e *TemplateEngine) ValidateTemplate(tmplStr string) error

ValidateTemplate validates a template string without executing it

type TemplateFunc

type TemplateFunc struct {
	Name        string
	Func        any
	Description string
}

TemplateFunc represents a template utility function with enhanced documentation

func GetTemplateFunctions

func GetTemplateFunctions() []TemplateFunc

GetTemplateFunctions returns all available template utility functions with comprehensive documentation

type WebhookClient

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

WebhookClient handles webhook delivery

func NewWebhookClient

func NewWebhookClient(config *Config) *WebhookClient

NewWebhookClient creates a new webhook client

func (*WebhookClient) Close

func (c *WebhookClient) Close() error

Close shuts down the client

func (*WebhookClient) Send

Send executes the webhook delivery

func (*WebhookClient) TransformPayload

func (c *WebhookClient) TransformPayload(tmplStr string, data WebhookTemplateContext) ([]byte, error)

TransformPayload transforms the webhook payload using a template

type WebhookEnvelope

type WebhookEnvelope struct {
	Version   string         `json:"version"`
	EventID   string         `json:"event_id"`
	EventName string         `json:"event_name"`
	Timestamp string         `json:"timestamp"`
	Attempt   int            `json:"attempt"`
	Payload   map[string]any `json:"payload"`
}

WebhookEnvelope is the default JSON body sent to webhook endpoints. All fields use snake_case JSON tags. Namespace, WebhookID, and DeliveryID are conveyed via X-Sparrow-* HTTP headers and are intentionally omitted from the body.

type WebhookTemplateContext

type WebhookTemplateContext = map[string]any

WebhookTemplateContext is the data context passed to Go templates. It uses snake_case keys so that templates reference fields as {{.event_id}}, {{.event_name}}, {{.timestamp}}, {{.attempt}}, and {{.payload}}. Namespace, WebhookID, and DeliveryID are conveyed via HTTP headers and are intentionally omitted from the template context.

func NewWebhookTemplateContext

func NewWebhookTemplateContext(eventID, eventName, timestamp string, attempt int, payload map[string]any) WebhookTemplateContext

NewWebhookTemplateContext builds a template context map with snake_case keys.

Jump to

Keyboard shortcuts

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