package webrtc
import (
"encoding/json"
"github.com/pion/stun/v3"
"github.com/pion/webrtc/v4/pkg/rtcerr"
)
type ICEServer struct {
URLs []string `json:"urls"`
Username string `json:"username,omitempty"`
Credential interface {} `json:"credential,omitempty"`
CredentialType ICECredentialType `json:"credentialType,omitempty"`
}
func (s ICEServer ) parseURL (i int ) (*stun .URI , error ) {
return stun .ParseURI (s .URLs [i ])
}
func (s ICEServer ) validate () error {
_ , err := s .urls ()
return err
}
func (s ICEServer ) urls () ([]*stun .URI , error ) {
urls := []*stun .URI {}
for i := range s .URLs {
url , err := s .parseURL (i )
if err != nil {
return nil , &rtcerr .InvalidAccessError {Err : err }
}
if url .Scheme == stun .SchemeTypeTURN || url .Scheme == stun .SchemeTypeTURNS {
if s .Username == "" || s .Credential == nil {
return nil , &rtcerr .InvalidAccessError {Err : ErrNoTurnCredentials }
}
url .Username = s .Username
switch s .CredentialType {
case ICECredentialTypePassword :
password , ok := s .Credential .(string )
if !ok {
return nil , &rtcerr .InvalidAccessError {Err : ErrTurnCredentials }
}
url .Password = password
case ICECredentialTypeOauth :
if _ , ok := s .Credential .(OAuthCredential ); !ok {
return nil , &rtcerr .InvalidAccessError {Err : ErrTurnCredentials }
}
default :
return nil , &rtcerr .InvalidAccessError {Err : ErrTurnCredentials }
}
}
urls = append (urls , url )
}
return urls , nil
}
func iceserverUnmarshalUrls(val interface {}) (*[]string , error ) {
s , ok := val .([]interface {})
if !ok {
return nil , errInvalidICEServer
}
out := make ([]string , len (s ))
for idx , url := range s {
out [idx ], ok = url .(string )
if !ok {
return nil , errInvalidICEServer
}
}
return &out , nil
}
func iceserverUnmarshalOauth(val interface {}) (*OAuthCredential , error ) {
c , ok := val .(map [string ]interface {})
if !ok {
return nil , errInvalidICEServer
}
MACKey , ok := c ["MACKey" ].(string )
if !ok {
return nil , errInvalidICEServer
}
AccessToken , ok := c ["AccessToken" ].(string )
if !ok {
return nil , errInvalidICEServer
}
return &OAuthCredential {
MACKey : MACKey ,
AccessToken : AccessToken ,
}, nil
}
func (s *ICEServer ) iceserverUnmarshalFields (fields map [string ]interface {}) error {
if val , ok := fields ["urls" ]; ok {
u , err := iceserverUnmarshalUrls (val )
if err != nil {
return err
}
s .URLs = *u
} else {
s .URLs = []string {}
}
if val , ok := fields ["username" ]; ok {
s .Username , ok = val .(string )
if !ok {
return errInvalidICEServer
}
}
if val , ok := fields ["credentialType" ]; ok {
ct , ok := val .(string )
if !ok {
return errInvalidICEServer
}
tpe , err := newICECredentialType (ct )
if err != nil {
return err
}
s .CredentialType = tpe
} else {
s .CredentialType = ICECredentialTypePassword
}
if val , ok := fields ["credential" ]; ok {
switch s .CredentialType {
case ICECredentialTypePassword :
s .Credential = val
case ICECredentialTypeOauth :
c , err := iceserverUnmarshalOauth (val )
if err != nil {
return err
}
s .Credential = *c
default :
return errInvalidICECredentialTypeString
}
}
return nil
}
func (s *ICEServer ) UnmarshalJSON (b []byte ) error {
var tmp interface {}
err := json .Unmarshal (b , &tmp )
if err != nil {
return err
}
if m , ok := tmp .(map [string ]interface {}); ok {
return s .iceserverUnmarshalFields (m )
}
return errInvalidICEServer
}
func (s ICEServer ) MarshalJSON () ([]byte , error ) {
m := make (map [string ]interface {})
m ["urls" ] = s .URLs
if s .Username != "" {
m ["username" ] = s .Username
}
if s .Credential != nil {
m ["credential" ] = s .Credential
}
m ["credentialType" ] = s .CredentialType
return json .Marshal (m )
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .