mirror of
https://github.com/aler9/gortsplib
synced 2025-10-05 23:26:54 +08:00
move headers into dedicated folder
This commit is contained in:
221
headers/auth.go
Normal file
221
headers/auth.go
Normal file
@@ -0,0 +1,221 @@
|
||||
// Package headers contains various RTSP headers.
|
||||
package headers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/aler9/gortsplib/base"
|
||||
)
|
||||
|
||||
// AuthMethod is an authentication method.
|
||||
type AuthMethod int
|
||||
|
||||
const (
|
||||
// AuthBasic is the Basic authentication method
|
||||
AuthBasic AuthMethod = iota
|
||||
|
||||
// AuthDigest is the Digest authentication method
|
||||
AuthDigest
|
||||
)
|
||||
|
||||
// Auth is an Authenticate or a WWWW-Authenticate header.
|
||||
type Auth struct {
|
||||
// authentication method
|
||||
Method AuthMethod
|
||||
|
||||
// (optional) username
|
||||
Username *string
|
||||
|
||||
// (optional) realm
|
||||
Realm *string
|
||||
|
||||
// (optional) nonce
|
||||
Nonce *string
|
||||
|
||||
// (optional) uri
|
||||
URI *string
|
||||
|
||||
// (optional) response
|
||||
Response *string
|
||||
|
||||
// (optional) opaque
|
||||
Opaque *string
|
||||
|
||||
// (optional) stale
|
||||
Stale *string
|
||||
|
||||
// (optional) algorithm
|
||||
Algorithm *string
|
||||
}
|
||||
|
||||
func findValue(v0 string) (string, string, error) {
|
||||
if v0 == "" {
|
||||
return "", "", nil
|
||||
}
|
||||
|
||||
if v0[0] == '"' {
|
||||
i := 1
|
||||
for {
|
||||
if i >= len(v0) {
|
||||
return "", "", fmt.Errorf("apices not closed (%v)", v0)
|
||||
}
|
||||
|
||||
if v0[i] == '"' {
|
||||
return v0[1:i], v0[i+1:], nil
|
||||
}
|
||||
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
i := 0
|
||||
for {
|
||||
if i >= len(v0) || v0[i] == ',' {
|
||||
return v0[:i], v0[i:], nil
|
||||
}
|
||||
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
// ReadAuth parses an Authenticate or a WWW-Authenticate header.
|
||||
func ReadAuth(v base.HeaderValue) (*Auth, error) {
|
||||
if len(v) == 0 {
|
||||
return nil, fmt.Errorf("value not provided")
|
||||
}
|
||||
|
||||
if len(v) > 1 {
|
||||
return nil, fmt.Errorf("value provided multiple times (%v)", v)
|
||||
}
|
||||
|
||||
ha := &Auth{}
|
||||
|
||||
v0 := v[0]
|
||||
|
||||
i := strings.IndexByte(v0, ' ')
|
||||
if i < 0 {
|
||||
return nil, fmt.Errorf("unable to find method (%s)", v0)
|
||||
}
|
||||
|
||||
switch v0[:i] {
|
||||
case "Basic":
|
||||
ha.Method = AuthBasic
|
||||
|
||||
case "Digest":
|
||||
ha.Method = AuthDigest
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid method (%s)", v0[:i])
|
||||
}
|
||||
v0 = v0[i+1:]
|
||||
|
||||
for len(v0) > 0 {
|
||||
i := strings.IndexByte(v0, '=')
|
||||
if i < 0 {
|
||||
return nil, fmt.Errorf("unable to find key (%s)", v0)
|
||||
}
|
||||
var key string
|
||||
key, v0 = v0[:i], v0[i+1:]
|
||||
|
||||
var val string
|
||||
var err error
|
||||
val, v0, err = findValue(v0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch key {
|
||||
case "username":
|
||||
ha.Username = &val
|
||||
|
||||
case "realm":
|
||||
ha.Realm = &val
|
||||
|
||||
case "nonce":
|
||||
ha.Nonce = &val
|
||||
|
||||
case "uri":
|
||||
ha.URI = &val
|
||||
|
||||
case "response":
|
||||
ha.Response = &val
|
||||
|
||||
case "opaque":
|
||||
ha.Opaque = &val
|
||||
|
||||
case "stale":
|
||||
ha.Stale = &val
|
||||
|
||||
case "algorithm":
|
||||
ha.Algorithm = &val
|
||||
|
||||
// ignore non-standard keys
|
||||
}
|
||||
|
||||
// skip comma
|
||||
if len(v0) > 0 && v0[0] == ',' {
|
||||
v0 = v0[1:]
|
||||
}
|
||||
|
||||
// skip spaces
|
||||
for len(v0) > 0 && v0[0] == ' ' {
|
||||
v0 = v0[1:]
|
||||
}
|
||||
}
|
||||
|
||||
return ha, nil
|
||||
}
|
||||
|
||||
// Write encodes an Authenticate or a WWW-Authenticate header.
|
||||
func (ha *Auth) Write() base.HeaderValue {
|
||||
ret := ""
|
||||
|
||||
switch ha.Method {
|
||||
case AuthBasic:
|
||||
ret += "Basic"
|
||||
|
||||
case AuthDigest:
|
||||
ret += "Digest"
|
||||
}
|
||||
|
||||
ret += " "
|
||||
|
||||
var vals []string
|
||||
|
||||
if ha.Username != nil {
|
||||
vals = append(vals, "username=\""+*ha.Username+"\"")
|
||||
}
|
||||
|
||||
if ha.Realm != nil {
|
||||
vals = append(vals, "realm=\""+*ha.Realm+"\"")
|
||||
}
|
||||
|
||||
if ha.Nonce != nil {
|
||||
vals = append(vals, "nonce=\""+*ha.Nonce+"\"")
|
||||
}
|
||||
|
||||
if ha.URI != nil {
|
||||
vals = append(vals, "uri=\""+*ha.URI+"\"")
|
||||
}
|
||||
|
||||
if ha.Response != nil {
|
||||
vals = append(vals, "response=\""+*ha.Response+"\"")
|
||||
}
|
||||
|
||||
if ha.Opaque != nil {
|
||||
vals = append(vals, "opaque=\""+*ha.Opaque+"\"")
|
||||
}
|
||||
|
||||
if ha.Stale != nil {
|
||||
vals = append(vals, "stale=\""+*ha.Stale+"\"")
|
||||
}
|
||||
|
||||
if ha.Algorithm != nil {
|
||||
vals = append(vals, "algorithm=\""+*ha.Algorithm+"\"")
|
||||
}
|
||||
|
||||
ret += strings.Join(vals, ", ")
|
||||
|
||||
return base.HeaderValue{ret}
|
||||
}
|
Reference in New Issue
Block a user