Documentation
¶
Overview ¶
Package api provides the REST API handlers and server for Healarr. It includes endpoints for managing scans, corruptions, configurations, notifications, and real-time updates via WebSocket.
Index ¶
- Constants
- Variables
- func GetRequestID(ctx context.Context) string
- func SafeOrderByClause(sortBy, sortOrder string, allowedColumns map[string]string, ...) string
- type GitHubRelease
- type HealthNotifier
- type MountInfo
- type PaginationConfig
- type PaginationParams
- type PaginationResponse
- type PathHealth
- type RESTServer
- type RateLimiter
- type ServerDeps
- type SetupStatus
- type SystemConfigInfo
- type SystemInfo
- type SystemLinks
- type UpdateCheckResponse
- type UpdateInstructions
- type WebSocketHub
- type WebhookRequest
Constants ¶
const ( ErrMsgDatabaseError = "Database error" ErrMsgAuthenticationError = "Authentication error" ErrMsgInvalidRequest = "Invalid request" ErrMsgNotFound = "Not found" ErrMsgInternalError = "Internal server error" ErrMsgScanNotFound = "Scan not found" ErrMsgNoIDsProvided = "No IDs provided" ErrMsgInvalidID = "Invalid ID" )
Standard error messages (don't leak internal details)
const RequestIDKey contextKey = "request_id"
RequestIDKey is the context key for storing the request ID.
Variables ¶
var ( // LoginLimiter: 5 attempts per minute, burst of 5 // Protects against brute force login attempts LoginLimiter = NewRateLimiter(5, time.Minute, 5) // SetupLimiter: 3 attempts per minute, burst of 3 // Setup should only happen once, strict limiting SetupLimiter = NewRateLimiter(3, time.Minute, 3) // WebhookLimiter: 60 requests per minute, burst of 30 // Webhooks can be frequent but need some protection WebhookLimiter = NewRateLimiter(60, time.Minute, 30) // APILimiter: 120 requests per minute per IP, burst of 60 // General API protection against abuse APILimiter = NewRateLimiter(120, time.Minute, 60) )
Global rate limiters for different endpoints
Functions ¶
func GetRequestID ¶ added in v1.2.0
GetRequestID extracts the request ID from a context. Returns an empty string if no request ID is set.
func SafeOrderByClause ¶ added in v1.1.18
func SafeOrderByClause(sortBy, sortOrder string, allowedColumns map[string]string, defaultColumn, defaultOrder string) string
SafeOrderByClause returns a SQL ORDER BY clause with validated column and direction. This function enforces validation at the point of use, making it clear to static analysis tools that the returned string is safe for SQL interpolation. The allowedColumns map contains the ONLY columns that can be used in the ORDER BY. If sortBy is not in allowedColumns, defaultColumn is used. If sortOrder is not "asc" or "desc", defaultOrder is used.
Types ¶
type GitHubRelease ¶ added in v1.1.7
type GitHubRelease struct {
TagName string `json:"tag_name"`
Name string `json:"name"`
Body string `json:"body"`
HTMLURL string `json:"html_url"`
PublishedAt time.Time `json:"published_at"`
Assets []struct {
Name string `json:"name"`
BrowserDownloadURL string `json:"browser_download_url"`
} `json:"assets"`
}
GitHubRelease represents the response from GitHub's releases API
type HealthNotifier ¶ added in v1.1.23
type HealthNotifier interface {
SendSystemHealthDegraded(data map[string]interface{})
}
HealthNotifier defines the interface for health-related notifications. This allows for easier testing by enabling mock implementations.
type MountInfo ¶ added in v1.1.9
type MountInfo struct {
Source string `json:"source"`
Destination string `json:"destination"`
Type string `json:"type,omitempty"`
ReadOnly bool `json:"read_only"`
}
MountInfo contains information about a mounted volume
type PaginationConfig ¶ added in v1.1.0
type PaginationConfig struct {
DefaultLimit int
MaxLimit int
DefaultSortBy string
DefaultSortOrder string
AllowedSortBy map[string]bool
}
PaginationConfig configures pagination parsing behavior
func DefaultPaginationConfig ¶ added in v1.1.0
func DefaultPaginationConfig() PaginationConfig
DefaultPaginationConfig returns a standard config for most endpoints. SECURITY NOTE: AllowedSortBy is nil, meaning no sort column validation is performed. This is ONLY safe when the query uses a FIXED ORDER BY clause (not p.SortBy). For dynamic sorting, always specify AllowedSortBy to prevent SQL injection.
type PaginationParams ¶ added in v1.1.0
PaginationParams holds parsed pagination parameters
func ParsePagination ¶ added in v1.1.0
func ParsePagination(c *gin.Context, cfg PaginationConfig) PaginationParams
ParsePagination extracts and validates pagination parameters from a Gin context
type PaginationResponse ¶ added in v1.1.0
type PaginationResponse struct {
Page int `json:"page"`
Limit int `json:"limit"`
Total int `json:"total"`
TotalPages int `json:"total_pages"`
}
PaginationResponse is the JSON response structure for paginated endpoints
func NewPaginationResponse ¶ added in v1.1.0
func NewPaginationResponse(p PaginationParams, total int) PaginationResponse
NewPaginationResponse creates a pagination response from params and total count
type PathHealth ¶ added in v1.1.30
type PathHealth struct {
PathID int `json:"path_id"`
LocalPath string `json:"local_path"`
Enabled bool `json:"enabled"`
LastScanTime *string `json:"last_scan_time,omitempty"`
LastScanID *int `json:"last_scan_id,omitempty"`
ActiveCorruptions int `json:"active_corruptions"` // Pending + in-progress + failed + manual
TotalCorruptions int `json:"total_corruptions"` // All-time for this path
ResolvedCount int `json:"resolved_count"`
Status string `json:"status"` // "healthy", "warning", "critical", "unknown"
}
PathHealth represents the health status of a configured scan path.
type RESTServer ¶
type RESTServer struct {
// contains filtered or unexported fields
}
RESTServer provides the HTTP REST API for Healarr.
func NewRESTServer ¶
func NewRESTServer(deps ServerDeps) *RESTServer
NewRESTServer creates a new REST server with the provided dependencies.
func (*RESTServer) Shutdown ¶
func (s *RESTServer) Shutdown(ctx context.Context) error
Shutdown gracefully shuts down the HTTP server and WebSocket hub
func (*RESTServer) Start ¶
func (s *RESTServer) Start(addr string) error
Start begins listening for HTTP requests on the specified address.
type RateLimiter ¶
type RateLimiter struct {
// contains filtered or unexported fields
}
RateLimiter implements a token bucket rate limiter per IP address
func NewRateLimiter ¶
func NewRateLimiter(rate int, interval time.Duration, burst int) *RateLimiter
NewRateLimiter creates a rate limiter with specified rate (requests per interval) and burst size
func (*RateLimiter) Allow ¶
func (rl *RateLimiter) Allow(ip string) bool
Allow checks if a request from the given IP should be allowed
func (*RateLimiter) Middleware ¶
func (rl *RateLimiter) Middleware() gin.HandlerFunc
Middleware returns a Gin middleware that rate limits requests
func (*RateLimiter) Shutdown ¶ added in v1.1.0
func (rl *RateLimiter) Shutdown()
Shutdown stops the rate limiter's cleanup goroutine
type ServerDeps ¶ added in v1.1.20
type ServerDeps struct {
DB *sql.DB
EventBus *eventbus.EventBus
Scanner services.Scanner
PathMapper integration.PathMapper
ArrClient integration.ArrClient
Scheduler services.Scheduler
Notifier *notifier.Notifier
Metrics *metrics.MetricsService
}
ServerDeps contains all dependencies required for the REST server
type SetupStatus ¶ added in v1.1.20
type SetupStatus struct {
NeedsSetup bool `json:"needs_setup"`
HasPassword bool `json:"has_password"`
HasAPIKey bool `json:"has_api_key"`
HasInstances bool `json:"has_instances"`
HasScanPaths bool `json:"has_scan_paths"`
OnboardingDismissed bool `json:"onboarding_dismissed"`
}
SetupStatus represents the current setup state of the application
type SystemConfigInfo ¶ added in v1.1.9
type SystemConfigInfo struct {
Port string `json:"port"`
BasePath string `json:"base_path"`
BasePathSource string `json:"base_path_source"`
LogLevel string `json:"log_level"`
DataDir string `json:"data_dir"`
DatabasePath string `json:"database_path"`
LogDir string `json:"log_dir"`
DryRunMode bool `json:"dry_run_mode"`
RetentionDays int `json:"retention_days"`
DefaultMaxRetries int `json:"default_max_retries"`
VerificationTimeout string `json:"verification_timeout"`
VerificationInterval string `json:"verification_interval"`
ArrRateLimitRPS float64 `json:"arr_rate_limit_rps"`
ArrRateLimitBurst int `json:"arr_rate_limit_burst"`
}
SystemConfigInfo contains configuration details
type SystemInfo ¶ added in v1.1.9
type SystemInfo struct {
Version string `json:"version"`
Environment string `json:"environment"` // "docker" or "native"
OS string `json:"os"`
Arch string `json:"arch"`
GoVersion string `json:"go_version"`
Uptime string `json:"uptime"`
UptimeSecs int64 `json:"uptime_seconds"`
StartedAt time.Time `json:"started_at"`
Config SystemConfigInfo `json:"config"`
Mounts []MountInfo `json:"mounts,omitempty"`
Tools map[string]*integration.ToolStatus `json:"tools"`
Links SystemLinks `json:"links"`
}
SystemInfo contains runtime environment information
type SystemLinks ¶ added in v1.1.9
type SystemLinks struct {
GitHub string `json:"github"`
Issues string `json:"issues"`
Releases string `json:"releases"`
Wiki string `json:"wiki"`
Discussions string `json:"discussions"`
}
SystemLinks contains useful links
type UpdateCheckResponse ¶ added in v1.1.7
type UpdateCheckResponse struct {
CurrentVersion string `json:"current_version"`
LatestVersion string `json:"latest_version"`
UpdateAvailable bool `json:"update_available"`
ReleaseURL string `json:"release_url"`
Changelog string `json:"changelog"`
PublishedAt string `json:"published_at"`
DownloadURLs map[string]string `json:"download_urls"`
DockerPullCmd string `json:"docker_pull_cmd"`
UpdateInstructions UpdateInstructions `json:"update_instructions"`
}
UpdateCheckResponse is the response returned to the frontend
type UpdateInstructions ¶ added in v1.1.7
type UpdateInstructions struct {
Docker string `json:"docker"`
Linux string `json:"linux"`
MacOS string `json:"macos"`
Windows string `json:"windows"`
}
UpdateInstructions provides platform-specific upgrade guidance
type WebSocketHub ¶
type WebSocketHub struct {
// contains filtered or unexported fields
}
WebSocketHub manages WebSocket connections and broadcasts events to connected clients.
func NewWebSocketHub ¶
func NewWebSocketHub(eventBus *eventbus.EventBus, metricsService ...*metrics.MetricsService) *WebSocketHub
NewWebSocketHub creates a new WebSocketHub and subscribes to relevant events. The metrics service is optional and enables connection tracking metrics.
func (*WebSocketHub) ClientCount ¶
func (h *WebSocketHub) ClientCount() int
ClientCount returns the number of connected WebSocket clients
func (*WebSocketHub) HandleConnection ¶
func (h *WebSocketHub) HandleConnection(c *gin.Context)
HandleConnection upgrades an HTTP connection to WebSocket and manages its lifecycle.
func (*WebSocketHub) Shutdown ¶ added in v1.1.0
func (h *WebSocketHub) Shutdown()
Shutdown stops the WebSocket hub and closes all client connections
type WebhookRequest ¶
type WebhookRequest struct {
EventType string `json:"eventType"` // Download, Upgrade, etc.
Series struct {
Path string `json:"path"`
} `json:"series"`
Movie struct {
Path string `json:"path"`
} `json:"movie"`
EpisodeFile struct {
Path string `json:"path"`
} `json:"episodeFile"`
MovieFile struct {
Path string `json:"path"`
} `json:"movieFile"`
}
WebhookRequest represents the payload from Sonarr/Radarr
Source Files
¶
- errors.go
- handlers_arr.go
- handlers_auth.go
- handlers_config.go
- handlers_corruptions.go
- handlers_health.go
- handlers_logs.go
- handlers_notifications.go
- handlers_paths.go
- handlers_scans.go
- handlers_schedules.go
- handlers_setup.go
- handlers_stats.go
- handlers_system.go
- handlers_updates.go
- handlers_webhook.go
- pagination.go
- ratelimit.go
- rest.go
- restart_unix.go
- websocket.go