Documentation
¶
Index ¶
- Variables
- func Start(platform platforms.Platform, cfg *config.Instance, st *state.State, ...) error
- func StartWithListener(opts ListenerOptions, platform platforms.Platform, cfg *config.Instance, ...) error
- func StartWithReady(platform platforms.Platform, cfg *config.Instance, st *state.State, ...) error
- type ListenerOptions
- type LocalIPsProvider
- type MethodMap
- func (m *MethodMap) AddMethod(name string, handler func(requests.RequestEnv) (any, error), ...) error
- func (m *MethodMap) GetMethod(name string) (func(requests.RequestEnv) (any, error), bool)
- func (m *MethodMap) ListMethods() []string
- func (m *MethodMap) Load(key any) (any, bool)
- func (m *MethodMap) Range(f func(key, value any) bool)
- func (m *MethodMap) Store(key, value any)
- type OriginsProvider
- type PairingManager
- func (m *PairingManager) CancelPairing()
- func (m *PairingManager) CountClients() (int, error)
- func (m *PairingManager) HandlePairFinish() http.HandlerFunc
- func (m *PairingManager) HandlePairStart() http.HandlerFunc
- func (m *PairingManager) PendingPIN() (pin string, expiresAt time.Time)
- func (m *PairingManager) StartCleanup(ctx context.Context)
- func (m *PairingManager) StartPairing(role string) (pin string, expiresAt time.Time, err error)
- type PairingOption
- type PairingResult
- type RequestTracker
- type ServiceState
- type StartupServer
- func (s *StartupServer) Done() <-chan error
- func (s *StartupServer) Listener() net.Listener
- func (s *StartupServer) Port() int
- func (s *StartupServer) ServeHTTP(w http.ResponseWriter, r *http.Request)
- func (s *StartupServer) SetFailed(headline, detail, logPath string)
- func (s *StartupServer) SetStartingDetail(detail string)
- func (s *StartupServer) Shutdown(ctx context.Context) error
- func (s *StartupServer) State() ServiceState
- func (s *StartupServer) SwapHandler(h http.Handler)
- func (s *StartupServer) WriteHealth(w http.ResponseWriter)
Constants ¶
This section is empty.
Variables ¶
var JSONRPCErrorInternalError = models.ErrorObject{
Code: -32603,
Message: "Internal error",
}
var JSONRPCErrorInvalidParams = models.ErrorObject{
Code: -32602,
Message: "Invalid params",
}
var JSONRPCErrorInvalidRequest = models.ErrorObject{
Code: -32600,
Message: "Invalid Request",
}
var JSONRPCErrorMethodNotFound = models.ErrorObject{
Code: -32601,
Message: "Method not found",
}
var JSONRPCErrorParseError = models.ErrorObject{
Code: -32700,
Message: "Parse error",
}
var JSONRPCErrorServerBusy = models.ErrorObject{
Code: -32000,
Message: "Server busy",
}
Functions ¶
func Start ¶
func Start( platform platforms.Platform, cfg *config.Instance, st *state.State, inTokenQueue chan<- tokens.Token, confirmQueue chan<- chan error, db *database.Database, limitsManager *playtime.LimitsManager, profilesSvc *profiles.Service, notifBroker *broker.Broker, player audio.Player, playbackManager audio.PlaybackManager, indexPauser *syncutil.Pauser, scrapePauser *syncutil.Pauser, backupPauser *syncutil.Pauser, tracker RequestTracker, ) error
Start starts the API web server and blocks until it shuts down.
func StartWithListener ¶ added in v2.19.0
func StartWithListener( opts ListenerOptions, platform platforms.Platform, cfg *config.Instance, st *state.State, inTokenQueue chan<- tokens.Token, confirmQueue chan<- chan error, db *database.Database, limitsManager *playtime.LimitsManager, profilesSvc *profiles.Service, notifBroker *broker.Broker, player audio.Player, playbackManager audio.PlaybackManager, indexPauser *syncutil.Pauser, scrapePauser *syncutil.Pauser, backupPauser *syncutil.Pauser, tracker RequestTracker, ready chan<- error, startup *StartupServer, ) error
StartWithListener serves the existing API on a host-supplied listener. Ownership transfers to this call; cancellation and server exit close it. A nil listener retains standalone TCP behavior. Unix clients require keys even when standalone key configuration is empty; TCP authentication and pairing behavior are unchanged. A supplied listener and a startup server are mutually exclusive: the startup server already owns the listener it bound.
func StartWithReady ¶ added in v2.11.0
func StartWithReady( platform platforms.Platform, cfg *config.Instance, st *state.State, inTokenQueue chan<- tokens.Token, confirmQueue chan<- chan error, db *database.Database, limitsManager *playtime.LimitsManager, profilesSvc *profiles.Service, notifBroker *broker.Broker, player audio.Player, playbackManager audio.PlaybackManager, indexPauser *syncutil.Pauser, scrapePauser *syncutil.Pauser, backupPauser *syncutil.Pauser, tracker RequestTracker, ready chan<- error, startup *StartupServer, ) error
StartWithReady starts the API web server and reports bind success or failure before blocking for shutdown. This lets service startup fail synchronously when the configured API port is unavailable.
When startup is non-nil the listener is already bound and serving the startup page, so this reuses it and swaps the full router in rather than binding a second time.
Types ¶
type ListenerOptions ¶ added in v2.19.0
type ListenerOptions struct {
Listener net.Listener
APIKeys apimiddleware.APIKeyProvider
OnNetwork func(port int)
Network bool
}
ListenerOptions supplies transport resources and an optional per-listener key provider. APIKeys must be safe for concurrent calls. Nil preserves standalone configuration.
Network additionally binds the configured TCP address and serves the same API on it, exactly as a standalone server would: clients of that listener are checked against the configured keys, pairing, encryption, IP filter, rate limits and origins, and APIKeys authenticates nobody there. It is only valid with a supplied Listener, because a standalone server already binds TCP. A failed bind is logged and the supplied listener is served alone.
One rule differs from standalone: no TCP client is local, loopback included. An embedding app shares loopback with every other app on the device, so such clients authenticate, pair and are filtered and rate limited like LAN clients. Only Unix peers of the supplied listener are local.
OnNetwork is called at most once, from the server goroutine, with the TCP port actually bound. It is not called when Network is false or the bind failed, and it must return promptly.
type LocalIPsProvider ¶ added in v2.13.0
type LocalIPsProvider func() []string
LocalIPsProvider is a function that returns current local interface IPs.
type MethodMap ¶
func NewMethodMap ¶
func NewMethodMap() *MethodMap
func (*MethodMap) ListMethods ¶
type OriginsProvider ¶ added in v2.9.0
type OriginsProvider func() []string
OriginsProvider is a function that returns custom origins from config.
type PairingManager ¶ added in v2.11.0
type PairingManager struct {
// contains filtered or unexported fields
}
PairingManager owns the PIN and in-flight sessions (single mutex protects all state).
func NewPairingManager ¶ added in v2.11.0
func NewPairingManager( db database.UserDBI, notifChan chan<- models.Notification, opts ...PairingOption, ) *PairingManager
NewPairingManager constructs a PairingManager (pass nil notifChan to disable notifications).
func (*PairingManager) CancelPairing ¶ added in v2.11.0
func (m *PairingManager) CancelPairing()
CancelPairing clears the current PIN and any in-flight sessions. Safe to call when no pairing is in progress.
func (*PairingManager) CountClients ¶ added in v2.16.0
func (m *PairingManager) CountClients() (int, error)
CountClients returns the number of currently paired clients.
func (*PairingManager) HandlePairFinish ¶ added in v2.11.0
func (m *PairingManager) HandlePairFinish() http.HandlerFunc
HandlePairFinish verifies HMAC, persists client, and returns auth token + confirmation.
func (*PairingManager) HandlePairStart ¶ added in v2.11.0
func (m *PairingManager) HandlePairStart() http.HandlerFunc
HandlePairStart runs the PAKE exchange and returns sessionID + server message.
func (*PairingManager) PendingPIN ¶ added in v2.11.0
func (m *PairingManager) PendingPIN() (pin string, expiresAt time.Time)
PendingPIN returns the currently displayed PIN and its expiry, or an empty PIN if no pairing is in progress.
func (*PairingManager) StartCleanup ¶ added in v2.11.0
func (m *PairingManager) StartCleanup(ctx context.Context)
StartCleanup begins the background cleanup goroutine. The goroutine exits when ctx is canceled. Safe to call multiple times only with distinct contexts; callers should call this once during server startup.
func (*PairingManager) StartPairing ¶ added in v2.11.0
StartPairing generates a new PIN (fails fast if clients are at max). role is the permission role the paired client will receive; it is chosen at this approval step because starting a pairing is a local-only action.
type PairingOption ¶ added in v2.11.0
type PairingOption func(*PairingManager)
PairingOption configures a PairingManager at construction time.
func WithPairingCleanupInterval ¶ added in v2.11.0
func WithPairingCleanupInterval(d time.Duration) PairingOption
WithPairingCleanupInterval overrides the cleanup goroutine tick interval.
func WithPairingMaxAttempts ¶ added in v2.11.0
func WithPairingMaxAttempts(n int) PairingOption
WithPairingMaxAttempts overrides the maximum PIN attempts (default 3).
func WithPairingMaxClients ¶ added in v2.11.0
func WithPairingMaxClients(n int) PairingOption
WithPairingMaxClients overrides the maximum paired clients (default 50).
func WithPairingPINTTL ¶ added in v2.11.0
func WithPairingPINTTL(d time.Duration) PairingOption
WithPairingPINTTL overrides the PIN time-to-live (default 5min).
func WithPairingSessionTTL ¶ added in v2.11.0
func WithPairingSessionTTL(d time.Duration) PairingOption
WithPairingSessionTTL overrides the /pair/start session TTL (default 2min).
type PairingResult ¶ added in v2.11.0
PairingResult is the outcome of a successful PAKE handshake. The Client is persisted to the database; the ServerHMAC must be returned to the client so it can verify the server's identity.
type RequestTracker ¶ added in v2.12.0
type RequestTracker interface {
RequestStarted()
RequestEnded()
}
RequestTracker is implemented by anything that wants to know when an API request starts and ends. The idle scheduler in pkg/service/idle satisfies it; tests can pass nil or a fake. Defined here (not in pkg/service/idle) so the api package doesn't need to import idle.
type ServiceState ¶ added in v2.18.0
type ServiceState string
ServiceState is the coarse lifecycle state Core reports on /health. It exists because everything Core normally uses to talk to a user sits behind the databases being open, so a slow or failed database start is invisible. The listener binds before any database work and answers with one of these from that moment on.
const ( // ServiceStateStarting means the process is alive and working through // startup. Nothing but the startup page and /health answers yet. ServiceStateStarting ServiceState = "starting" // ServiceStateReady means the full API is serving. ServiceStateReady ServiceState = "ready" // ServiceStateFailed means startup stopped on something a person has to // resolve. Core stays bound so it can say what happened. ServiceStateFailed ServiceState = "failed" )
type StartupServer ¶ added in v2.18.0
type StartupServer struct {
// contains filtered or unexported fields
}
StartupServer owns the API listener from before the databases open until shutdown. It serves a startup page and /health until the full router is swapped in, so a slow migration or a refused database has somewhere to be reported.
func NewStartupServer ¶ added in v2.18.0
NewStartupServer binds the configured API address and immediately begins serving the startup page. It is called before any database work so that every later failure has a surface to report on.
func (*StartupServer) Done ¶ added in v2.18.0
func (s *StartupServer) Done() <-chan error
Done reports the result of the serving goroutine.
func (*StartupServer) Listener ¶ added in v2.18.0
func (s *StartupServer) Listener() net.Listener
Listener returns the bound listener.
func (*StartupServer) Port ¶ added in v2.18.0
func (s *StartupServer) Port() int
Port returns the port actually bound.
func (*StartupServer) ServeHTTP ¶ added in v2.18.0
func (s *StartupServer) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP dispatches to whichever handler is currently installed. The handler is swapped once, when the full router is ready.
func (*StartupServer) SetFailed ¶ added in v2.18.0
func (s *StartupServer) SetFailed(headline, detail, logPath string)
SetFailed puts Core into the failed state. Core stays bound and keeps serving the page so the reason is readable without a log or a terminal.
func (*StartupServer) SetStartingDetail ¶ added in v2.18.0
func (s *StartupServer) SetStartingDetail(detail string)
SetStartingDetail updates the sentence shown while startup is still working.
func (*StartupServer) Shutdown ¶ added in v2.18.0
func (s *StartupServer) Shutdown(ctx context.Context) error
Shutdown stops the HTTP server and waits for it to stop serving.
The wait is what makes the port free when this returns, and callers depend on that: the failed state has to give the port back when it is stopped, and a start that ends after the listener was bound has to leave it for the next attempt. http.Server.Shutdown alone does not promise it. It closes the listeners it has been told about, and Serve registers the listener after it starts, so a shutdown landing in that window closes nothing and leaves Serve's own deferred close to do it — after Shutdown has returned. Measured at 1714 of 2000 immediate shutdowns.
func (*StartupServer) State ¶ added in v2.18.0
func (s *StartupServer) State() ServiceState
State returns the current coarse state.
func (*StartupServer) SwapHandler ¶ added in v2.18.0
func (s *StartupServer) SwapHandler(h http.Handler)
SwapHandler installs the full API router and marks the service ready. It is called once, after startup completes.
func (*StartupServer) WriteHealth ¶ added in v2.18.0
func (s *StartupServer) WriteHealth(w http.ResponseWriter)
WriteHealth renders the /health body for the current state. It is used by both the startup handler and the full router so the two never disagree.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package crypto provides AES-256-GCM encryption with HKDF-derived per-session keys for the Zaparoo API WebSocket transport.
|
Package crypto provides AES-256-GCM encryption with HKDF-derived per-session keys for the Zaparoo API WebSocket transport. |
|
Package permissions defines client roles and the capability lookup that gates privileged API methods.
|
Package permissions defines client roles and the capability lookup that gates privileged API methods. |
|
Package validation provides validation for API request parameters using go-playground/validator with custom validators for Zaparoo-specific types.
|
Package validation provides validation for API request parameters using go-playground/validator with custom validators for Zaparoo-specific types. |