mirror of
https://github.com/aler9/gortsplib
synced 2025-10-05 15:16:51 +08:00
split headers.Authenticate and headers.Authorization (#523)
This commit is contained in:
@@ -13,14 +13,37 @@ type Authorization struct {
|
||||
// authentication method
|
||||
Method AuthMethod
|
||||
|
||||
// basic user
|
||||
//
|
||||
// Basic authentication fields
|
||||
//
|
||||
|
||||
// user
|
||||
BasicUser string
|
||||
|
||||
// basic password
|
||||
// password
|
||||
BasicPass string
|
||||
|
||||
// digest values
|
||||
DigestValues Authenticate
|
||||
//
|
||||
// Digest authentication fields
|
||||
//
|
||||
|
||||
// username
|
||||
Username string
|
||||
|
||||
// realm
|
||||
Realm string
|
||||
|
||||
// nonce
|
||||
Nonce string
|
||||
|
||||
// URI
|
||||
URI string
|
||||
|
||||
// response
|
||||
Response string
|
||||
|
||||
// response
|
||||
Opaque *string
|
||||
}
|
||||
|
||||
// Unmarshal decodes an Authorization header.
|
||||
@@ -35,12 +58,24 @@ func (h *Authorization) Unmarshal(v base.HeaderValue) error {
|
||||
|
||||
v0 := v[0]
|
||||
|
||||
switch {
|
||||
case strings.HasPrefix(v0, "Basic "):
|
||||
i := strings.IndexByte(v0, ' ')
|
||||
if i < 0 {
|
||||
return fmt.Errorf("unable to split between method and keys (%v)", v0)
|
||||
}
|
||||
method, v0 := v0[:i], v0[i+1:]
|
||||
|
||||
switch method {
|
||||
case "Basic":
|
||||
h.Method = AuthBasic
|
||||
|
||||
v0 = v0[len("Basic "):]
|
||||
case "Digest":
|
||||
h.Method = AuthDigest
|
||||
|
||||
default:
|
||||
return fmt.Errorf("invalid method (%s)", method)
|
||||
}
|
||||
|
||||
if h.Method == AuthBasic {
|
||||
tmp, err := base64.StdEncoding.DecodeString(v0)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid value")
|
||||
@@ -52,20 +87,50 @@ func (h *Authorization) Unmarshal(v base.HeaderValue) error {
|
||||
}
|
||||
|
||||
h.BasicUser, h.BasicPass = tmp2[0], tmp2[1]
|
||||
|
||||
case strings.HasPrefix(v0, "Digest "):
|
||||
h.Method = AuthDigest
|
||||
|
||||
var vals Authenticate
|
||||
err := vals.Unmarshal(base.HeaderValue{v0})
|
||||
} else { // digest
|
||||
kvs, err := keyValParse(v0, ',')
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
h.DigestValues = vals
|
||||
realmReceived := false
|
||||
usernameReceived := false
|
||||
nonceReceived := false
|
||||
uriReceived := false
|
||||
responseReceived := false
|
||||
|
||||
default:
|
||||
return fmt.Errorf("invalid authorization header")
|
||||
for k, rv := range kvs {
|
||||
v := rv
|
||||
|
||||
switch k {
|
||||
case "realm":
|
||||
h.Realm = v
|
||||
realmReceived = true
|
||||
|
||||
case "username":
|
||||
h.Username = v
|
||||
usernameReceived = true
|
||||
|
||||
case "nonce":
|
||||
h.Nonce = v
|
||||
nonceReceived = true
|
||||
|
||||
case "uri":
|
||||
h.URI = v
|
||||
uriReceived = true
|
||||
|
||||
case "response":
|
||||
h.Response = v
|
||||
responseReceived = true
|
||||
|
||||
case "opaque":
|
||||
h.Opaque = &v
|
||||
}
|
||||
}
|
||||
|
||||
if !realmReceived || !usernameReceived || !nonceReceived || !uriReceived || !responseReceived {
|
||||
return fmt.Errorf("one or more digest fields are missing")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -73,13 +138,18 @@ func (h *Authorization) Unmarshal(v base.HeaderValue) error {
|
||||
|
||||
// Marshal encodes an Authorization header.
|
||||
func (h Authorization) Marshal() base.HeaderValue {
|
||||
switch h.Method {
|
||||
case AuthBasic:
|
||||
response := base64.StdEncoding.EncodeToString([]byte(h.BasicUser + ":" + h.BasicPass))
|
||||
|
||||
return base.HeaderValue{"Basic " + response}
|
||||
|
||||
default: // AuthDigest
|
||||
return h.DigestValues.Marshal()
|
||||
if h.Method == AuthBasic {
|
||||
return base.HeaderValue{"Basic " +
|
||||
base64.StdEncoding.EncodeToString([]byte(h.BasicUser+":"+h.BasicPass))}
|
||||
}
|
||||
|
||||
ret := "Digest " +
|
||||
"username=\"" + h.Username + "\", realm=\"" + h.Realm + "\", " +
|
||||
"nonce=\"" + h.Nonce + "\", uri=\"" + h.URI + "\", response=\"" + h.Response + "\""
|
||||
|
||||
if h.Opaque != nil {
|
||||
ret += ", opaque=\"" + *h.Opaque + "\""
|
||||
}
|
||||
|
||||
return base.HeaderValue{ret}
|
||||
}
|
||||
|
Reference in New Issue
Block a user