mirror of
https://github.com/aler9/gortsplib
synced 2025-10-07 08:01:14 +08:00
split authClient and AuthServer
This commit is contained in:
109
authclient.go
Normal file
109
authclient.go
Normal file
@@ -0,0 +1,109 @@
|
||||
package gortsplib
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// authClient is an object that helps a client to send its credentials to a
|
||||
// server.
|
||||
type authClient struct {
|
||||
user string
|
||||
pass string
|
||||
method AuthMethod
|
||||
realm string
|
||||
nonce string
|
||||
}
|
||||
|
||||
// newAuthClient allocates an authClient.
|
||||
// header is the WWW-Authenticate header provided by the server.
|
||||
func newAuthClient(v HeaderValue, user string, pass string) (*authClient, error) {
|
||||
// prefer digest
|
||||
if headerAuthDigest := func() string {
|
||||
for _, vi := range v {
|
||||
if strings.HasPrefix(vi, "Digest ") {
|
||||
return vi
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}(); headerAuthDigest != "" {
|
||||
auth, err := ReadHeaderAuth(HeaderValue{headerAuthDigest})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if auth.Realm == nil {
|
||||
return nil, fmt.Errorf("realm not provided")
|
||||
}
|
||||
|
||||
if auth.Nonce == nil {
|
||||
return nil, fmt.Errorf("nonce not provided")
|
||||
}
|
||||
|
||||
return &authClient{
|
||||
user: user,
|
||||
pass: pass,
|
||||
method: Digest,
|
||||
realm: *auth.Realm,
|
||||
nonce: *auth.Nonce,
|
||||
}, nil
|
||||
}
|
||||
|
||||
if headerAuthBasic := func() string {
|
||||
for _, vi := range v {
|
||||
if strings.HasPrefix(vi, "Basic ") {
|
||||
return vi
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}(); headerAuthBasic != "" {
|
||||
auth, err := ReadHeaderAuth(HeaderValue{headerAuthBasic})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if auth.Realm == nil {
|
||||
return nil, fmt.Errorf("realm not provided")
|
||||
}
|
||||
|
||||
return &authClient{
|
||||
user: user,
|
||||
pass: pass,
|
||||
method: Basic,
|
||||
realm: *auth.Realm,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("there are no authentication methods available")
|
||||
}
|
||||
|
||||
// GenerateHeader generates an Authorization Header that allows to authenticate a request with
|
||||
// the given method and url.
|
||||
func (ac *authClient) GenerateHeader(method Method, ur *url.URL) HeaderValue {
|
||||
switch ac.method {
|
||||
case Basic:
|
||||
response := base64.StdEncoding.EncodeToString([]byte(ac.user + ":" + ac.pass))
|
||||
|
||||
return HeaderValue{"Basic " + response}
|
||||
|
||||
case Digest:
|
||||
response := md5Hex(md5Hex(ac.user+":"+ac.realm+":"+ac.pass) + ":" +
|
||||
ac.nonce + ":" + md5Hex(string(method)+":"+ur.String()))
|
||||
|
||||
return (&HeaderAuth{
|
||||
Method: Digest,
|
||||
Username: &ac.user,
|
||||
Realm: &ac.realm,
|
||||
Nonce: &ac.nonce,
|
||||
URI: func() *string {
|
||||
v := ur.String()
|
||||
return &v
|
||||
}(),
|
||||
Response: &response,
|
||||
}).Write()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Reference in New Issue
Block a user