httpstore

package
v0.1.0-alpha.9 Latest Latest
Warning

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

Go to latest
Published: Dec 30, 2025 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Overview

Package httpstore provides HTTP resource fetching with caching and validation.

This package implements a store that fetches resources from HTTP(S) URLs, caches them, and supports periodic refresh with a two-version cache for safe validation before accepting new content.

Index

Constants

View Source
const DefaultRetries = 3

DefaultRetries is the default number of retry attempts.

View Source
const DefaultRetryDelay = time.Second

DefaultRetryDelay is the default delay between retry attempts.

View Source
const DefaultTimeout = 30 * time.Second

DefaultTimeout is the default HTTP request timeout.

View Source
const MaxContentSize = 10 * 1024 * 1024

MaxContentSize is the maximum allowed content size (10MB).

Variables

This section is empty.

Functions

func Checksum

func Checksum(content string) string

Checksum computes SHA256 checksum of content.

Types

type AuthConfig

type AuthConfig struct {
	// Type is the authentication type: "basic", "bearer", or "header".
	Type string

	// Username for basic auth.
	Username string

	// Password for basic auth.
	Password string

	// Token for bearer auth.
	Token string

	// Headers for custom header auth (e.g., API keys).
	// These headers are added to every request.
	Headers map[string]string
}

AuthConfig configures HTTP authentication.

type CacheEntry

type CacheEntry struct {
	// URL is the source URL for this entry.
	URL string

	// Accepted version (validated, in production use)
	AcceptedContent  string
	AcceptedChecksum string
	AcceptedTime     time.Time

	// LastAccessTime tracks when this entry was last accessed via Get/Fetch.
	// Used for cache eviction of unused entries.
	LastAccessTime time.Time

	// Pending version (fetched, awaiting validation)
	PendingContent  string
	PendingChecksum string
	HasPending      bool

	// ValidationState tracks the current state of this entry.
	ValidationState ValidationState

	// HTTP caching headers for conditional requests
	ETag         string
	LastModified string

	// Configuration for this URL
	Options FetchOptions
	Auth    *AuthConfig
}

CacheEntry holds cached content with two-version support for safe validation.

The two-version design ensures that new content is only accepted after successful validation. This is critical for resources like IP blocklists where we must not discard the old blocklist before knowing the new one is valid.

type FetchOptions

type FetchOptions struct {
	// Delay is the refresh interval (how often to re-fetch).
	// Zero means no automatic refresh (fetch once).
	Delay time.Duration

	// Timeout is the HTTP request timeout.
	// Default: 30s
	Timeout time.Duration

	// Retries is the number of retry attempts on failure.
	// Default: 3
	Retries int

	// RetryDelay is the wait time between retries.
	// Default: 1s
	RetryDelay time.Duration

	// Critical indicates whether fetch failure should fail the template render.
	// If true, a failed fetch returns an error.
	// If false, a failed fetch returns empty string and logs a warning.
	Critical bool
}

FetchOptions configures HTTP fetching behavior.

func (FetchOptions) WithDefaults

func (o FetchOptions) WithDefaults() FetchOptions

WithDefaults returns a copy of the options with default values applied.

type HTTPStore

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

HTTPStore provides HTTP resource fetching with caching and two-version validation.

The store supports:

  • Synchronous initial fetch (blocks until complete)
  • Cached access to previously fetched content
  • Two-version cache for safe validation (pending vs accepted)
  • Conditional requests using ETag/If-Modified-Since
  • Automatic eviction of unused entries based on last access time

Thread-safe for concurrent access.

func New

func New(logger *slog.Logger, maxAge time.Duration) *HTTPStore

New creates a new HTTPStore with the given logger and maximum cache age.

maxAge is the maximum time an entry can remain unused before becoming eligible for eviction. If maxAge is 0, entries are never evicted based on access time.

func (*HTTPStore) Clear

func (s *HTTPStore) Clear()

Clear removes all entries from the cache.

func (*HTTPStore) EvictUnused

func (s *HTTPStore) EvictUnused() []string

EvictUnused removes cache entries that haven't been accessed within maxAge. Entries with pending validation are never evicted to protect the two-version cache. Returns the list of evicted URLs (empty if none evicted or eviction disabled).

This method is called periodically by the event adapter to prevent unbounded memory growth when templates change and old URLs are no longer used.

func (*HTTPStore) Fetch

func (s *HTTPStore) Fetch(ctx context.Context, url string, opts FetchOptions, auth *AuthConfig) (string, error)

Fetch retrieves content from a URL, using cache if available.

On first call for a URL, this performs a synchronous HTTP fetch and caches the result. Subsequent calls return cached content immediately.

If the URL has a Delay > 0 in options, the caller is responsible for scheduling refreshes (typically done by the event adapter component).

Parameters:

  • ctx: Context for cancellation and timeout
  • url: The HTTP(S) URL to fetch
  • opts: Fetch options (timeout, retries, critical flag, delay for refresh)
  • auth: Optional authentication configuration

Returns:

  • Content string (empty if fetch failed and not critical)
  • Error if critical fetch fails

func (*HTTPStore) Get

func (s *HTTPStore) Get(url string) (string, bool)

Get returns the accepted content for a URL if it exists in cache. Returns empty string and false if not cached. Updates LastAccessTime to track usage for cache eviction.

func (*HTTPStore) GetDelay

func (s *HTTPStore) GetDelay(url string) time.Duration

GetDelay returns the configured delay for a URL. Returns 0 if URL not in cache or no delay configured.

func (*HTTPStore) GetEntry

func (s *HTTPStore) GetEntry(url string) *CacheEntry

GetEntry returns a copy of the cache entry for a URL. Returns nil if not cached.

func (*HTTPStore) GetForValidation

func (s *HTTPStore) GetForValidation(url string) (string, bool)

GetForValidation returns content for validation rendering. If pending content exists, returns pending; otherwise returns accepted. Updates LastAccessTime to track usage for cache eviction.

func (*HTTPStore) GetPending

func (s *HTTPStore) GetPending(url string) (string, bool)

GetPending returns the pending content for a URL if it exists. This is used during validation to render with pending content. Returns empty string and false if no pending content. Updates LastAccessTime to track usage for cache eviction.

func (*HTTPStore) GetPendingURLs

func (s *HTTPStore) GetPendingURLs() []string

GetPendingURLs returns all URLs with pending content awaiting validation.

func (*HTTPStore) GetURLsWithDelay

func (s *HTTPStore) GetURLsWithDelay() []string

GetURLsWithDelay returns all cached URLs that have a refresh delay configured. This is used by the event adapter to schedule refresh timers.

func (*HTTPStore) HasPendingValidation

func (s *HTTPStore) HasPendingValidation() bool

HasPendingValidation returns true if any URL has pending content awaiting validation.

func (*HTTPStore) LoadFixture

func (s *HTTPStore) LoadFixture(url, content string)

LoadFixture loads a single HTTP fixture directly into the store as accepted content. This is used by validation tests to provide mock HTTP responses without making actual HTTP requests.

The fixture is stored directly as accepted content, bypassing the normal fetch and validation workflow.

func (*HTTPStore) PromoteAllPending

func (s *HTTPStore) PromoteAllPending() int

PromoteAllPending promotes all pending content to accepted. This is used when validation succeeds for the entire config.

func (*HTTPStore) PromotePending

func (s *HTTPStore) PromotePending(url string) bool

PromotePending promotes pending content to accepted for a URL. This should be called after successful validation.

func (*HTTPStore) RefreshURL

func (s *HTTPStore) RefreshURL(ctx context.Context, url string) (changed bool, err error)

RefreshURL fetches fresh content for a URL and stores it as pending.

This does NOT replace accepted content immediately. The caller must: 1. Trigger re-render with pending content (using GetForValidation) 2. On successful validation, call PromotePending 3. On failed validation, call RejectPending

Returns:

  • changed: true if content changed from accepted version
  • err: fetch error (nil if successful or 304 Not Modified)

func (*HTTPStore) RejectAllPending

func (s *HTTPStore) RejectAllPending() int

RejectAllPending rejects all pending content. This is used when validation fails for the entire config.

func (*HTTPStore) RejectPending

func (s *HTTPStore) RejectPending(url string) bool

RejectPending discards pending content for a URL. This should be called when validation fails.

func (*HTTPStore) Size

func (s *HTTPStore) Size() int

Size returns the number of cached URLs.

type ValidationState

type ValidationState int

ValidationState represents the current validation state of a cached entry.

const (
	// StateAccepted means the accepted content is in use, no pending content.
	StateAccepted ValidationState = iota

	// StateValidating means pending content exists and is being validated.
	StateValidating

	// StateRejected means the last pending content was rejected, using accepted.
	StateRejected
)

func (ValidationState) String

func (s ValidationState) String() string

String returns a string representation of the validation state.

Jump to

Keyboard shortcuts

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