Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion challenge.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func (c *Challenge) SupportsQOP(qop string) bool {

// ParseChallenge parses the WWW-Authenticate header challenge
func ParseChallenge(s string) (*Challenge, error) {
s, ok := strings.CutPrefix(s, Prefix)
s, ok := CutPrefix(s)
if !ok {
return nil, errors.New("digest: invalid challenge prefix")
}
Expand Down
15 changes: 14 additions & 1 deletion challenge_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
func TestChallenge(t *testing.T) {
tests := []struct {
input string
output string
challenge *Challenge
}{
{
Expand All @@ -33,13 +34,25 @@ func TestChallenge(t *testing.T) {
QOP: []string{"auth"},
},
},
{
input: `DIGEST realm="DLI LPC92601002528", nonce="NZAeQHhoCNifFjFa"`,
output: `Digest realm="DLI LPC92601002528", nonce="NZAeQHhoCNifFjFa"`,
challenge: &Challenge{
Realm: "DLI LPC92601002528",
Nonce: "NZAeQHhoCNifFjFa",
},
},
}
for i, tt := range tests {
t.Run(strconv.Itoa(i), func(t *testing.T) {
c, err := ParseChallenge(tt.input)
assert.NilError(t, err)
assert.DeepEqual(t, tt.challenge, c)
assert.DeepEqual(t, c.String(), tt.input)
output := tt.output
if output == "" {
output = tt.input
}
assert.DeepEqual(t, output, c.String())
})
}
}
Expand Down
2 changes: 1 addition & 1 deletion credentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ type Credentials struct {

// ParseCredentials parses the Authorization header value into credentials
func ParseCredentials(s string) (*Credentials, error) {
s, ok := strings.CutPrefix(s, Prefix)
s, ok := CutPrefix(s)
if !ok {
return nil, errors.New("digest: invalid credentials prefix")
}
Expand Down
13 changes: 12 additions & 1 deletion digest.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,18 @@ const Prefix = "Digest "

// IsDigest returns true if the header value is a digest auth header
func IsDigest(header string) bool {
return strings.HasPrefix(header, Prefix)
if len(header) < len(Prefix) {
return false
}
return strings.EqualFold(header[:len(Prefix)], Prefix)
}

// CutPrefix removes the digest prefix from the header value
func CutPrefix(s string) (string, bool) {
if !IsDigest(s) {
return s, false
}
return s[len(Prefix):], true
}

// Options for creating a credentials
Expand Down
24 changes: 24 additions & 0 deletions digest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,30 @@ func TestDigestMD5(t *testing.T) {
Nc: 1,
},
},
{
Options{
Comment thread
icholy marked this conversation as resolved.
Method: "REGISTER",
URI: "sip:182.82.132.122",
Username: "the-user",
Password: "********",
Cnonce: "104adc6bd71f49678798ee646edcaa9a",
},
&Challenge{
Realm: "SipPeer",
Nonce: "970a1b42-d8a7-4fce-91a1-4767e9ed561b",
QOP: []string{"auth"},
},
&Credentials{
Username: "the-user",
Realm: "SipPeer",
Nonce: "970a1b42-d8a7-4fce-91a1-4767e9ed561b",
URI: "sip:182.82.132.122",
Response: "6cf0981e056709d40c8acc40c87e73c6",
Cnonce: "104adc6bd71f49678798ee646edcaa9a",
QOP: "auth",
Nc: 1,
},
},
}
for _, tt := range tests {
t.Run("", func(t *testing.T) {
Expand Down