diff --git a/go.mod b/go.mod index 5c9436da2..d935ffd67 100644 --- a/go.mod +++ b/go.mod @@ -36,6 +36,7 @@ require ( github.com/stretchr/testify v1.7.0 github.com/thoas/go-funk v0.8.0 github.com/twitchtv/twirp v8.1.0+incompatible + github.com/ua-parser/uap-go v0.0.0-20211112212520-00c877edfe0f github.com/urfave/cli/v2 v2.3.0 github.com/urfave/negroni v1.0.0 go.uber.org/atomic v1.7.0 @@ -82,4 +83,5 @@ require ( google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect google.golang.org/grpc v1.42.0 // indirect gopkg.in/square/go-jose.v2 v2.5.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/go.sum b/go.sum index 8d297d9cc..a90a4398c 100644 --- a/go.sum +++ b/go.sum @@ -263,6 +263,8 @@ github.com/thoas/go-funk v0.8.0 h1:JP9tKSvnpFVclYgDM0Is7FD9M4fhPvqA0s0BsXmzSRQ= github.com/thoas/go-funk v0.8.0/go.mod h1:+IWnUfUmFO1+WVYQWQtIJHeRRdaIyyYglZN7xzUPe4Q= github.com/twitchtv/twirp v8.1.0+incompatible h1:KGXanpa9LXdVE/V5P/tA27rkKFmXRGCtSNT7zdeeVOY= github.com/twitchtv/twirp v8.1.0+incompatible/go.mod h1:RRJoFSAmTEh2weEqWtpPE3vFK5YBhA6bqp2l1kfCC5A= +github.com/ua-parser/uap-go v0.0.0-20211112212520-00c877edfe0f h1:A+MmlgpvrHLeUP8dkBVn4Pnf5Bp5Yk2OALm7SEJLLE8= +github.com/ua-parser/uap-go v0.0.0-20211112212520-00c877edfe0f/go.mod h1:OBcG9bn7sHtXgarhUEb3OfCnNsgtGnkVf41ilSZ3K3E= github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/urfave/negroni v1.0.0 h1:kIimOitoypq34K7TG7DUaJ9kq/N4Ofuwi1sjz0KipXc= diff --git a/pkg/service/rtcservice.go b/pkg/service/rtcservice.go index 12d3e663a..34db353eb 100644 --- a/pkg/service/rtcservice.go +++ b/pkg/service/rtcservice.go @@ -5,13 +5,13 @@ import ( "fmt" "io" "net/http" - "net/url" "strconv" "strings" "github.com/gorilla/websocket" "github.com/livekit/protocol/livekit" "github.com/livekit/protocol/logger" + "github.com/ua-parser/uap-go/uaparser" "github.com/livekit/livekit-server/pkg/config" "github.com/livekit/livekit-server/pkg/routing" @@ -30,6 +30,7 @@ type RTCService struct { config *config.Config isDev bool limits config.LimitConfig + parser *uaparser.Parser } func NewRTCService( @@ -48,6 +49,7 @@ func NewRTCService( config: conf, isDev: conf.Development, limits: conf.Limit, + parser: uaparser.NewFromSaved(), } // allow connections from any origin, since script may be hosted anywhere @@ -116,7 +118,7 @@ func (s *RTCService) validate(r *http.Request) (livekit.RoomName, routing.Partic Metadata: claims.Metadata, Hidden: claims.Video.Hidden, Recorder: claims.Video.Recorder, - Client: ParseClientInfo(r.Form), + Client: s.ParseClientInfo(r), Grants: claims, } @@ -253,7 +255,8 @@ func (s *RTCService) ServeHTTP(w http.ResponseWriter, r *http.Request) { } } -func ParseClientInfo(values url.Values) *livekit.ClientInfo { +func (s *RTCService) ParseClientInfo(r *http.Request) *livekit.ClientInfo { + values := r.Form ci := &livekit.ClientInfo{} if pv, err := strconv.Atoi(values.Get("protocol")); err == nil { ci.Protocol = int32(pv) @@ -273,11 +276,36 @@ func ParseClientInfo(values url.Values) *livekit.ClientInfo { case "unity": ci.Sdk = livekit.ClientInfo_UNITY } + ci.Version = values.Get("version") ci.Os = values.Get("os") ci.OsVersion = values.Get("os_version") ci.Browser = values.Get("browser") ci.BrowserVersion = values.Get("browser_version") ci.DeviceModel = values.Get("device_model") + + // attempt to parse types for SDKs that support browser as a platform + if ci.Sdk == livekit.ClientInfo_JS || + ci.Sdk == livekit.ClientInfo_FLUTTER || + ci.Sdk == livekit.ClientInfo_UNITY { + client := s.parser.Parse(r.UserAgent()) + if ci.Browser == "" { + ci.Browser = client.UserAgent.Family + ci.BrowserVersion = client.UserAgent.ToVersionString() + } + if ci.Os == "" { + ci.Os = client.Os.Family + ci.OsVersion = client.Os.ToVersionString() + } + if ci.DeviceModel == "" { + model := client.Device.Family + if model != "" && client.Device.Model != "" && model != client.Device.Model { + model += " " + client.Device.Model + } + + ci.DeviceModel = model + } + } + return ci }