diff --git a/pkg/auth/verify.go b/pkg/auth/verify.go index 74029417..d30e98f6 100644 --- a/pkg/auth/verify.go +++ b/pkg/auth/verify.go @@ -31,11 +31,11 @@ func urlMatches(expected string, received string, isSetup bool) bool { return true } - // in SETUP requests, VLC uses the base URL of the stream - // instead of the URL of the track. - // Strip the control attribute to obtain the URL of the stream. + // in SETUP requests, some clients do not use the track URL: + // - VLC uses the stream base URL (with trailing slash) + // - HappyTime NVR uses the stream URL (without trailing slash) if isSetup { - if m := reControlAttribute.FindStringSubmatch(expected); m != nil && received == m[1] { + if m := reControlAttribute.FindStringSubmatch(expected); m != nil && (received == m[1] || (received+"/") == m[1]) { return true } } diff --git a/pkg/auth/verify_test.go b/pkg/auth/verify_test.go index 0326b604..22ba25ef 100644 --- a/pkg/auth/verify_test.go +++ b/pkg/auth/verify_test.go @@ -48,6 +48,13 @@ var casesVerify = []struct { "uri=\"rtsp://myhost/mypath?key=val/\", response=\"5ca5ceeca20a05e9a3f49ecde4b42655\"", }, }, + { + "digest happytime", + base.HeaderValue{ + `Digest username="myuser", realm="myrealm", nonce="f49ac6dd0ba708d4becddc9692d1f2ce", ` + + `uri="rtsp://myhost/mypath?key=val", response="c11a6e92b449f221dabf494a7a837ee3"`, + }, + }, } func TestVerify(t *testing.T) {