mirror of
https://github.com/livekit/livekit.git
synced 2026-07-28 12:09:26 +00:00
Take ClientInfo from request. (#3738)
This will allow WHIP client to pass in client info which can provide more information about WHIP clients for telemetry.
This commit is contained in:
@@ -169,14 +169,18 @@ func (s *RTCRestService) validateCreate(r *http.Request) (*createRequest, int, e
|
||||
return nil, http.StatusBadRequest, fmt.Errorf("malformed SDP offer: %s", err)
|
||||
}
|
||||
|
||||
ci := ParseClientInfo(r)
|
||||
if ci.Protocol == 0 {
|
||||
// if no client info available (which will be mostly the case with WHIP clients), at least set protocol
|
||||
ci.Protocol = types.CurrentProtocol
|
||||
}
|
||||
|
||||
pi := routing.ParticipantInit{
|
||||
Identity: livekit.ParticipantIdentity(claims.Identity),
|
||||
Name: livekit.ParticipantName(claims.Name),
|
||||
AutoSubscribe: true,
|
||||
Client: &livekit.ClientInfo{
|
||||
Protocol: types.CurrentProtocol,
|
||||
},
|
||||
Grants: claims,
|
||||
Client: ci,
|
||||
Grants: claims,
|
||||
CreateRoom: &livekit.CreateRoomRequest{
|
||||
Name: string(roomName),
|
||||
RoomPreset: claims.RoomPreset,
|
||||
|
||||
@@ -28,7 +28,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/ua-parser/uap-go/uaparser"
|
||||
"go.uber.org/atomic"
|
||||
"golang.org/x/exp/maps"
|
||||
|
||||
@@ -52,7 +51,6 @@ type RTCService struct {
|
||||
config *config.Config
|
||||
isDev bool
|
||||
limits config.LimitConfig
|
||||
parser *uaparser.Parser
|
||||
telemetry telemetry.TelemetryService
|
||||
|
||||
mu sync.Mutex
|
||||
@@ -71,7 +69,6 @@ func NewRTCService(
|
||||
config: conf,
|
||||
isDev: conf.Development,
|
||||
limits: conf.Limit,
|
||||
parser: uaparser.NewFromSaved(),
|
||||
telemetry: telemetry,
|
||||
connections: map[*websocket.Conn]struct{}{},
|
||||
}
|
||||
@@ -229,7 +226,7 @@ func (s *RTCService) validateInternal(log logger.Logger, r *http.Request, strict
|
||||
Identity: livekit.ParticipantIdentity(claims.Identity),
|
||||
Name: livekit.ParticipantName(claims.Name),
|
||||
AutoSubscribe: true,
|
||||
Client: s.ParseClientInfo(r),
|
||||
Client: ParseClientInfo(r),
|
||||
Grants: claims,
|
||||
Region: region,
|
||||
CreateRoom: createRequest,
|
||||
@@ -549,77 +546,6 @@ func (s *RTCService) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
sdkString := values.Get("sdk")
|
||||
switch sdkString {
|
||||
case "js":
|
||||
ci.Sdk = livekit.ClientInfo_JS
|
||||
case "ios", "swift":
|
||||
ci.Sdk = livekit.ClientInfo_SWIFT
|
||||
case "android":
|
||||
ci.Sdk = livekit.ClientInfo_ANDROID
|
||||
case "flutter":
|
||||
ci.Sdk = livekit.ClientInfo_FLUTTER
|
||||
case "go":
|
||||
ci.Sdk = livekit.ClientInfo_GO
|
||||
case "unity":
|
||||
ci.Sdk = livekit.ClientInfo_UNITY
|
||||
case "reactnative":
|
||||
ci.Sdk = livekit.ClientInfo_REACT_NATIVE
|
||||
case "rust":
|
||||
ci.Sdk = livekit.ClientInfo_RUST
|
||||
case "python":
|
||||
ci.Sdk = livekit.ClientInfo_PYTHON
|
||||
case "cpp":
|
||||
ci.Sdk = livekit.ClientInfo_CPP
|
||||
case "unityweb":
|
||||
ci.Sdk = livekit.ClientInfo_UNITY_WEB
|
||||
case "node":
|
||||
ci.Sdk = livekit.ClientInfo_NODE
|
||||
}
|
||||
|
||||
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")
|
||||
ci.Network = values.Get("network")
|
||||
// get real address (forwarded http header) - check Cloudflare headers first, fall back to X-Forwarded-For
|
||||
ci.Address = GetClientIP(r)
|
||||
|
||||
// attempt to parse types for SDKs that support browser as a platform
|
||||
if ci.Sdk == livekit.ClientInfo_JS ||
|
||||
ci.Sdk == livekit.ClientInfo_REACT_NATIVE ||
|
||||
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
|
||||
}
|
||||
|
||||
func (s *RTCService) DrainConnections(interval time.Duration) {
|
||||
s.mu.Lock()
|
||||
conns := maps.Clone(s.connections)
|
||||
|
||||
@@ -20,10 +20,12 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/livekit/livekit-server/pkg/utils"
|
||||
"github.com/livekit/protocol/livekit"
|
||||
"github.com/ua-parser/uap-go/uaparser"
|
||||
)
|
||||
|
||||
func HandleError(w http.ResponseWriter, r *http.Request, status int, err error, keysAndValues ...interface{}) {
|
||||
@@ -82,3 +84,74 @@ func SetRoomConfiguration(createRequest *livekit.CreateRoomRequest, conf *liveki
|
||||
createRequest.MaxPlayoutDelay = conf.MaxPlayoutDelay
|
||||
createRequest.SyncStreams = conf.SyncStreams
|
||||
}
|
||||
|
||||
func 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)
|
||||
}
|
||||
sdkString := values.Get("sdk")
|
||||
switch sdkString {
|
||||
case "js":
|
||||
ci.Sdk = livekit.ClientInfo_JS
|
||||
case "ios", "swift":
|
||||
ci.Sdk = livekit.ClientInfo_SWIFT
|
||||
case "android":
|
||||
ci.Sdk = livekit.ClientInfo_ANDROID
|
||||
case "flutter":
|
||||
ci.Sdk = livekit.ClientInfo_FLUTTER
|
||||
case "go":
|
||||
ci.Sdk = livekit.ClientInfo_GO
|
||||
case "unity":
|
||||
ci.Sdk = livekit.ClientInfo_UNITY
|
||||
case "reactnative":
|
||||
ci.Sdk = livekit.ClientInfo_REACT_NATIVE
|
||||
case "rust":
|
||||
ci.Sdk = livekit.ClientInfo_RUST
|
||||
case "python":
|
||||
ci.Sdk = livekit.ClientInfo_PYTHON
|
||||
case "cpp":
|
||||
ci.Sdk = livekit.ClientInfo_CPP
|
||||
case "unityweb":
|
||||
ci.Sdk = livekit.ClientInfo_UNITY_WEB
|
||||
case "node":
|
||||
ci.Sdk = livekit.ClientInfo_NODE
|
||||
}
|
||||
|
||||
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")
|
||||
ci.Network = values.Get("network")
|
||||
// get real address (forwarded http header) - check Cloudflare headers first, fall back to X-Forwarded-For
|
||||
ci.Address = GetClientIP(r)
|
||||
|
||||
// attempt to parse types for SDKs that support browser as a platform
|
||||
if ci.Sdk == livekit.ClientInfo_JS ||
|
||||
ci.Sdk == livekit.ClientInfo_REACT_NATIVE ||
|
||||
ci.Sdk == livekit.ClientInfo_FLUTTER ||
|
||||
ci.Sdk == livekit.ClientInfo_UNITY {
|
||||
client := uaparser.NewFromSaved().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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user