client

package
v1.3.4 Latest Latest
Warning

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

Go to latest
Published: May 4, 2026 License: MIT Imports: 27 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 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. The caller is responsible for closing resp.Body.

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
	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 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 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