mirror of
https://github.com/openlibrecommunity/olcrtc.git
synced 2026-06-06 12:29:44 +00:00
internal/carrier and internal/carrier/builtin sat between transports and
engines, wrapping every engine.Session in carrier.Session +
engineByteStream/engineVideoTrack adapters that mechanically proxied every
method. That layer existed solely to translate Capabilities/AddTrack names;
no behaviour lived above engine.
Replace with internal/engine/builtin: a name-keyed registry that calls
auth.Issue and engine.New directly. Transports look up engine.Session via
enginebuiltin.Open, then type-assert engine.VideoTrackCapable for video
transports. A small per-transport engineVideoSession adapter unifies the
reconnect callback signature (engine uses func(*webrtc.DataChannel); the
transports want func()).
Updates:
- internal/engine/builtin/builtin.go: new Register/Open registry + auth
pass-through ("none") + auth-driven factories for jazz/telemost/wbstream/jitsi.
- internal/transport/datachannel/transport.go: uses engine.Session directly
via Capabilities().ByteStream check.
- internal/transport/{seichannel,videochannel,vp8channel}: each gains an
engineVideoSession adapter and routes Connect/Send/Close/AddTrack through
the engine session.
- internal/app/session: imports enginebuiltin; carrier.Available() →
enginebuiltin.Available().
- pkg/olcrtc/olcrtc.go: switches to enginebuiltin.RegisterDefaults.
- internal/carrier and internal/carrier/builtin: deleted.
- Tests rewritten to register a fakeEngineSession (implements engine.Session
+ engine.VideoTrackCapable) through enginebuiltin.Register. The e2e
memoryStream gains the same dual interface so memorySession is gone.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
149 lines
5.0 KiB
Go
149 lines
5.0 KiB
Go
// Package builtin wires the built-in auth providers to their engines and
|
|
// registers a name-keyed factory that transports use to obtain an
|
|
// [engine.Session]. The factory replaces the former carrier layer: when
|
|
// the auth provider is "none" the caller supplies engine/URL/token
|
|
// directly; otherwise the named provider issues credentials and the
|
|
// matching engine is constructed.
|
|
package builtin
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/openlibrecommunity/olcrtc/internal/auth"
|
|
authJitsi "github.com/openlibrecommunity/olcrtc/internal/auth/jitsi"
|
|
authSaluteJazz "github.com/openlibrecommunity/olcrtc/internal/auth/salutejazz"
|
|
authTelemost "github.com/openlibrecommunity/olcrtc/internal/auth/telemost"
|
|
authWBStream "github.com/openlibrecommunity/olcrtc/internal/auth/wbstream"
|
|
"github.com/openlibrecommunity/olcrtc/internal/engine"
|
|
_ "github.com/openlibrecommunity/olcrtc/internal/engine/goolom" // register goolom engine via init
|
|
_ "github.com/openlibrecommunity/olcrtc/internal/engine/jitsi" // register jitsi engine via init
|
|
_ "github.com/openlibrecommunity/olcrtc/internal/engine/livekit" // register livekit engine via init
|
|
_ "github.com/openlibrecommunity/olcrtc/internal/engine/salutejazz" // register salutejazz engine via init
|
|
)
|
|
|
|
// ErrCarrierNotFound is returned when an unregistered carrier name is requested.
|
|
var ErrCarrierNotFound = errors.New("carrier not found")
|
|
|
|
// ErrAuthFailed wraps an auth provider rejection. It pairs with the inner
|
|
// provider error returned from [Open].
|
|
var ErrAuthFailed = errors.New("carrier auth failed")
|
|
|
|
// Config holds the inputs to [Open]. The fields mirror the subset of
|
|
// transport.Config that engines consume.
|
|
type Config struct {
|
|
RoomURL string
|
|
Name string
|
|
OnData func([]byte)
|
|
DNSServer string
|
|
ProxyAddr string
|
|
ProxyPort int
|
|
// Engine, URL, Token are honoured only for the "none" carrier (direct
|
|
// engine access); other carriers derive them from their auth provider.
|
|
Engine string
|
|
URL string
|
|
Token string
|
|
}
|
|
|
|
// Factory creates an engine session for a given carrier.
|
|
type Factory func(ctx context.Context, cfg Config) (engine.Session, error)
|
|
|
|
var registry = map[string]Factory{} //nolint:gochecknoglobals // package-level registry
|
|
|
|
// Register adds a carrier factory.
|
|
func Register(name string, f Factory) {
|
|
registry[name] = f
|
|
}
|
|
|
|
// Open looks up the carrier factory and creates an engine session.
|
|
func Open(ctx context.Context, name string, cfg Config) (engine.Session, error) {
|
|
f, ok := registry[name]
|
|
if !ok {
|
|
return nil, fmt.Errorf("%w: %q", ErrCarrierNotFound, name)
|
|
}
|
|
return f(ctx, cfg)
|
|
}
|
|
|
|
// Available reports all registered carrier names.
|
|
func Available() []string {
|
|
names := make([]string, 0, len(registry))
|
|
for name := range registry {
|
|
names = append(names, name)
|
|
}
|
|
return names
|
|
}
|
|
|
|
// RegisterDefaults wires the built-in carriers: jitsi, telemost, jazz, wbstream
|
|
// and "none" (direct engine access).
|
|
func RegisterDefaults() {
|
|
registerEngineAuth("wbstream", authWBStream.Provider{})
|
|
registerEngineAuth("jazz", authSaluteJazz.Provider{})
|
|
registerEngineAuth("telemost", authTelemost.Provider{})
|
|
registerEngineAuth("jitsi", authJitsi.Provider{})
|
|
registerDirect("none")
|
|
}
|
|
|
|
// registerDirect registers a carrier that skips auth: the caller supplies
|
|
// engine/URL/token directly via [Config].
|
|
func registerDirect(name string) {
|
|
Register(name, func(ctx context.Context, cfg Config) (engine.Session, error) {
|
|
engineName := cfg.Engine
|
|
if engineName == "" {
|
|
engineName = "livekit"
|
|
}
|
|
sess, err := engine.New(ctx, engineName, engine.Config{
|
|
URL: cfg.URL,
|
|
Token: cfg.Token,
|
|
Name: cfg.Name,
|
|
OnData: cfg.OnData,
|
|
DNSServer: cfg.DNSServer,
|
|
ProxyAddr: cfg.ProxyAddr,
|
|
ProxyPort: cfg.ProxyPort,
|
|
})
|
|
if err != nil {
|
|
return nil, fmt.Errorf("engine new: %w", err)
|
|
}
|
|
return sess, nil
|
|
})
|
|
}
|
|
|
|
// registerEngineAuth registers a carrier that resolves credentials through an
|
|
// auth provider and connects via the engine the auth provider reports.
|
|
func registerEngineAuth(name string, provider auth.Provider) {
|
|
Register(name, func(ctx context.Context, cfg Config) (engine.Session, error) {
|
|
authCfg := auth.Config{
|
|
RoomURL: cfg.RoomURL,
|
|
Name: cfg.Name,
|
|
DNSServer: cfg.DNSServer,
|
|
ProxyAddr: cfg.ProxyAddr,
|
|
ProxyPort: cfg.ProxyPort,
|
|
}
|
|
creds, err := provider.Issue(ctx, authCfg)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("%w: %w", ErrAuthFailed, err)
|
|
}
|
|
sess, err := engine.New(ctx, provider.Engine(), engine.Config{
|
|
URL: creds.URL,
|
|
Token: creds.Token,
|
|
Name: cfg.Name,
|
|
Extra: creds.Extra,
|
|
OnData: cfg.OnData,
|
|
DNSServer: cfg.DNSServer,
|
|
ProxyAddr: cfg.ProxyAddr,
|
|
ProxyPort: cfg.ProxyPort,
|
|
Refresh: func(ctx context.Context) (engine.Credentials, error) {
|
|
fresh, err := provider.Issue(ctx, authCfg)
|
|
if err != nil {
|
|
return engine.Credentials{}, fmt.Errorf("auth refresh: %w", err)
|
|
}
|
|
return engine.Credentials{URL: fresh.URL, Token: fresh.Token, Extra: fresh.Extra}, nil
|
|
},
|
|
})
|
|
if err != nil {
|
|
return nil, fmt.Errorf("engine new: %w", err)
|
|
}
|
|
return sess, nil
|
|
})
|
|
}
|