- lighthouse: Registry of namespace authorizers (Result, Allowed, Denied), ParseChannel, ChannelID with PHP (int)-cast semantics (PHPInt, pinned by a php -r table test), FormatChannels, WithClientID/ClientID - centrifugo: ProxyHandler (constant-time X-Centrifugo-Secret, HTTP 200 generic deny, info [] on allow, presence allow/override merge, 64 KiB body cap) mounted as the ServerToServer subscribe route - README: proxy contract, registry and channel rules
85 lines
2.6 KiB
Go
85 lines
2.6 KiB
Go
// Package centrifugo is the Centrifugo driver of lighthouse: an HTTP API
|
|
// client, a connection and subscription token issuer, and the subscribe
|
|
// proxy handler. Import it for its side effect to register the
|
|
// "centrifugo" realtime.driver.
|
|
package centrifugo
|
|
|
|
import (
|
|
"net/netip"
|
|
"strings"
|
|
"time"
|
|
|
|
"git.golem15.com/golem15/summercms/modules/compass"
|
|
"git.golem15.com/golem15/summercms/modules/lighthouse"
|
|
"git.golem15.com/golem15/summercms/modules/surf"
|
|
)
|
|
|
|
// Default values of the realtime.centrifugo.* keys.
|
|
const (
|
|
DefaultAPIURL = "http://127.0.0.1:8001/api"
|
|
DefaultTokenTTL = 3600 * time.Second
|
|
DefaultWSURL = "/ws"
|
|
DefaultTokenPath = "/api/realtime/token"
|
|
DefaultSubscribePath = "/api/realtime/subscribe"
|
|
)
|
|
|
|
// Config is the realtime.centrifugo.* configuration.
|
|
type Config struct {
|
|
// APIURL is the Centrifugo HTTP API base, without a trailing method.
|
|
APIURL string
|
|
// APIKey authenticates publishes; empty disables them.
|
|
APIKey string
|
|
// TokenSecret signs connection and subscription tokens (HS256); empty
|
|
// makes the token route answer 503.
|
|
TokenSecret string
|
|
// TokenTTL is the lifetime of issued tokens.
|
|
TokenTTL time.Duration
|
|
// WSURL is the WebSocket URL the client connects to.
|
|
WSURL string
|
|
// ProxySecret is the X-Centrifugo-Secret header value the subscribe
|
|
// proxy expects; empty denies every subscribe.
|
|
ProxySecret string
|
|
// TokenPath and SubscribePath are the mounted route paths.
|
|
TokenPath string
|
|
SubscribePath string
|
|
// TrustedProxies are the http.trusted_proxies used to log the client IP
|
|
// of a denied subscribe.
|
|
TrustedProxies []netip.Prefix
|
|
}
|
|
|
|
// LoadConfig reads realtime.centrifugo.* from c, filling the defaults.
|
|
// token_ttl is an integer number of seconds or a duration string.
|
|
func LoadConfig(c *compass.Config) Config {
|
|
cfg := Config{
|
|
APIURL: DefaultAPIURL,
|
|
TokenTTL: DefaultTokenTTL,
|
|
WSURL: DefaultWSURL,
|
|
TokenPath: DefaultTokenPath,
|
|
SubscribePath: DefaultSubscribePath,
|
|
}
|
|
if c == nil {
|
|
return cfg
|
|
}
|
|
str := func(key string) string { return strings.TrimSpace(c.String("realtime.centrifugo." + key)) }
|
|
if v := str("api_url"); v != "" {
|
|
cfg.APIURL = strings.TrimSuffix(v, "/")
|
|
}
|
|
cfg.APIKey = str("api_key")
|
|
cfg.TokenSecret = str("token_secret")
|
|
cfg.ProxySecret = str("proxy_secret")
|
|
if d := lighthouse.DurationSetting(c, "realtime.centrifugo.token_ttl"); d > 0 {
|
|
cfg.TokenTTL = d
|
|
}
|
|
if v := str("ws_url"); v != "" {
|
|
cfg.WSURL = v
|
|
}
|
|
if v := str("token_path"); v != "" {
|
|
cfg.TokenPath = v
|
|
}
|
|
if v := str("subscribe_path"); v != "" {
|
|
cfg.SubscribePath = v
|
|
}
|
|
cfg.TrustedProxies = surf.TrustedProxies(c)
|
|
return cfg
|
|
}
|