Documentation
¶
Index ¶
- Constants
- func BuildEnvelopePayload(eventID string, eventName string, attempt int, payload map[string]any) ([]byte, error)
- func BuildRequest(ctx context.Context, dr *DeliveryRequest) (*http.Request, error)
- func GetBuffer() *bytes.Buffer
- func GetFunctionDocumentation() string
- func GetFunctionMap() template.FuncMap
- func GetHeaderMap() map[string]string
- func PutBuffer(buf *bytes.Buffer)
- func PutHeaderMap(m map[string]string)
- func ReadBody(resp *http.Response, limit int64) ([]byte, error)
- func ValidateIP(ip net.IP) error
- type Config
- type DeliveryRequest
- type Metrics
- type TemplateCache
- type TemplateEngine
- type TemplateFunc
- type WebhookClient
- type WebhookEnvelope
- type WebhookTemplateContext
Constants ¶
const (
// DefaultCacheSize is the default maximum number of templates to cache
DefaultCacheSize = 100
)
const EnvelopeVersion = "1"
EnvelopeVersion is the current version of the webhook envelope schema.
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.
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 HTTP headers instead.
func BuildRequest ¶
BuildRequest creates an HTTP request from the delivery request
func GetFunctionDocumentation ¶
func GetFunctionDocumentation() string
GetFunctionDocumentation returns markdown documentation for all template functions
func GetFunctionMap ¶
GetFunctionMap returns a template.FuncMap with all utility functions
func GetHeaderMap ¶
GetHeaderMap retrieves a header map from the pool
func PutHeaderMap ¶
PutHeaderMap returns a header map to the pool
func ReadBody ¶
ReadBody reads the response body safely using a pooled buffer. The caller is responsible for closing resp.Body.
func ValidateIP ¶
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
type DeliveryRequest ¶
type DeliveryRequest struct {
WebhookID uuid.UUID
DeliveryID string
URL string
Method string
Headers map[string]string
Payload []byte
Secret string
Ed25519PrivateKey []byte // Raw Ed25519 private key (64 bytes) for asymmetric signing
SignatureType string // "hmac" or "ed25519" — controls which signing scheme is used
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 (*Metrics) RecordFailure ¶
RecordFailure increments failure counter
func (*Metrics) RecordRequest ¶
func (m *Metrics) RecordRequest()
RecordRequest increments total request counter
func (*Metrics) RecordSuccess ¶
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
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 ¶
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) Send ¶
func (c *WebhookClient) Send(ctx context.Context, req *DeliveryRequest) (*http.Response, time.Duration, error)
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 HTTP headers and are intentionally omitted from the body.
type WebhookTemplateContext ¶
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.