diff --git a/client_play_test.go b/client_play_test.go index 3aee5908..ef685ed4 100644 --- a/client_play_test.go +++ b/client_play_test.go @@ -1074,7 +1074,7 @@ func TestClientPlayAutomaticProtocol(t *testing.T) { require.NoError(t, err) require.Equal(t, base.Describe, req.Method) - err = v.ValidateRequest(req) + err = v.ValidateRequest(req, nil) require.NoError(t, err) err = conn.WriteResponse(&base.Response{ @@ -1188,7 +1188,7 @@ func TestClientPlayAutomaticProtocol(t *testing.T) { require.Equal(t, base.Setup, req.Method) require.Equal(t, mustParseURL("rtsp://localhost:8554/teststream/mediaID=0"), req.URL) - err = v.ValidateRequest(req) + err = v.ValidateRequest(req, nil) require.NoError(t, err) var inTH headers.Transport diff --git a/client_test.go b/client_test.go index bb3e8d43..64b3f061 100644 --- a/client_test.go +++ b/client_test.go @@ -180,7 +180,7 @@ func TestClientAuth(t *testing.T) { require.NoError(t, err) require.Equal(t, base.Describe, req.Method) - err = v.ValidateRequest(req) + err = v.ValidateRequest(req, nil) require.NoError(t, err) medias := media.Medias{testH264Media.Clone()} diff --git a/pkg/auth/package_test.go b/pkg/auth/package_test.go index f513d2c0..51c7fa0b 100644 --- a/pkg/auth/package_test.go +++ b/pkg/auth/package_test.go @@ -78,7 +78,7 @@ func TestAuth(t *testing.T) { req.URL = mustParseURL("rtsp://myhost/mypath") - err = va.ValidateRequest(req) + err = va.ValidateRequest(req, nil) if conf != "nofail" { require.Error(t, err) @@ -93,7 +93,7 @@ func TestAuth(t *testing.T) { func TestAuthVLC(t *testing.T) { for _, ca := range []struct { clientURL string - serverURL string + mediaURL string }{ { "rtsp://myhost/mypath/", @@ -115,11 +115,13 @@ func TestAuthVLC(t *testing.T) { URL: mustParseURL(ca.clientURL), } se.AddAuthorization(req) + req.URL = mustParseURL(ca.mediaURL) - req.URL = mustParseURL(ca.serverURL) - - err = va.ValidateRequest(req) + err = va.ValidateRequest(req, mustParseURL(ca.clientURL)) require.NoError(t, err) + + err = va.ValidateRequest(req, mustParseURL("rtsp://invalid")) + require.Error(t, err) } } @@ -155,7 +157,7 @@ func TestAuthHashed(t *testing.T) { } va.AddAuthorization(req) - err = se.ValidateRequest(req) + err = se.ValidateRequest(req, nil) if conf != "nofail" { require.Error(t, err) diff --git a/pkg/auth/validator.go b/pkg/auth/validator.go index 3f04d27f..fed83b33 100644 --- a/pkg/auth/validator.go +++ b/pkg/auth/validator.go @@ -11,34 +11,6 @@ import ( "github.com/aler9/gortsplib/v2/pkg/url" ) -func stringsReverseIndex(s, substr string) int { - for i := len(s) - 1 - len(substr); i >= 0; i-- { - if s[i:i+len(substr)] == substr { - return i - } - } - return -1 -} - -func generateAltURL(req *base.Request) (*url.URL, bool) { - if req.Method != base.Setup { - return nil, false - } - - pathAndQuery, ok := req.URL.RTSPPathAndQuery() - if !ok { - return nil, false - } - - i := stringsReverseIndex(pathAndQuery, "/trackID=") - if i < 0 { - return nil, false - } - - ur, _ := url.Parse(req.URL.Scheme + "://" + req.URL.Host + "/" + pathAndQuery[:i+1]) - return ur, true -} - // Validator allows to validate credentials generated by a Sender. type Validator struct { user string @@ -113,7 +85,7 @@ func (va *Validator) Header() base.HeaderValue { } // ValidateRequest validates a request sent by a client. -func (va *Validator) ValidateRequest(req *base.Request) error { +func (va *Validator) ValidateRequest(req *base.Request, baseURL *url.URL) error { var auth headers.Authorization err := auth.Unmarshal(req.Header["Authorization"]) if err != nil { @@ -179,10 +151,9 @@ func (va *Validator) ValidateRequest(req *base.Request) error { if *auth.DigestValues.URI != ur.String() { // in SETUP requests, VLC strips the control attribute. - // try again with an alternative URL without the control attribute. - if altURL, ok := generateAltURL(req); ok { - ur = altURL - + // try again with the base URL. + if baseURL != nil { + ur = baseURL if *auth.DigestValues.URI != ur.String() { return fmt.Errorf("wrong URL") } diff --git a/pkg/auth/validator_test.go b/pkg/auth/validator_test.go index cb2a89e1..646f06e2 100644 --- a/pkg/auth/validator_test.go +++ b/pkg/auth/validator_test.go @@ -64,7 +64,7 @@ func TestValidatorErrors(t *testing.T) { Header: base.Header{ "Authorization": ca.hv, }, - }) + }, nil) require.EqualError(t, err, ca.err) }) } diff --git a/pkg/format/g711_test.go b/pkg/format/g711_test.go index b3b977e9..6c774add 100644 --- a/pkg/format/g711_test.go +++ b/pkg/format/g711_test.go @@ -3,6 +3,7 @@ package format import ( "testing" + "github.com/pion/rtp" "github.com/stretchr/testify/require" ) @@ -11,6 +12,7 @@ func TestG711Attributes(t *testing.T) { require.Equal(t, "G711", format.String()) require.Equal(t, 8000, format.ClockRate()) require.Equal(t, uint8(8), format.PayloadType()) + require.Equal(t, true, format.PTSEqualsDTS(&rtp.Packet{})) format = &G711{ MULaw: true, diff --git a/pkg/format/g722_test.go b/pkg/format/g722_test.go index 39838e08..a9d8f1b4 100644 --- a/pkg/format/g722_test.go +++ b/pkg/format/g722_test.go @@ -3,6 +3,7 @@ package format import ( "testing" + "github.com/pion/rtp" "github.com/stretchr/testify/require" ) @@ -11,6 +12,7 @@ func TestG722Attributes(t *testing.T) { require.Equal(t, "G722", format.String()) require.Equal(t, 8000, format.ClockRate()) require.Equal(t, uint8(9), format.PayloadType()) + require.Equal(t, true, format.PTSEqualsDTS(&rtp.Packet{})) } func TestG722Clone(t *testing.T) { diff --git a/pkg/format/generic_test.go b/pkg/format/generic_test.go index 05fe86c2..3427d92b 100644 --- a/pkg/format/generic_test.go +++ b/pkg/format/generic_test.go @@ -3,6 +3,7 @@ package format import ( "testing" + "github.com/pion/rtp" "github.com/stretchr/testify/require" ) @@ -19,6 +20,7 @@ func TestGenericAttributes(t *testing.T) { require.Equal(t, "Generic", format.String()) require.Equal(t, 90000, format.ClockRate()) require.Equal(t, uint8(98), format.PayloadType()) + require.Equal(t, true, format.PTSEqualsDTS(&rtp.Packet{})) } func TestGenericClone(t *testing.T) { diff --git a/pkg/format/h264_test.go b/pkg/format/h264_test.go index 29cb6ad9..e7228b38 100644 --- a/pkg/format/h264_test.go +++ b/pkg/format/h264_test.go @@ -3,6 +3,7 @@ package format import ( "testing" + "github.com/pion/rtp" "github.com/stretchr/testify/require" ) @@ -25,6 +26,22 @@ func TestH264Attributes(t *testing.T) { require.Equal(t, []byte{0x09, 0x0A}, format.SafePPS()) } +func TestH264PTSEqualsDTS(t *testing.T) { + format := &H264{ + PayloadTyp: 96, + SPS: []byte{0x01, 0x02}, + PPS: []byte{0x03, 0x04}, + PacketizationMode: 1, + } + + require.Equal(t, true, format.PTSEqualsDTS(&rtp.Packet{ + Payload: []byte{0x05}, + })) + require.Equal(t, false, format.PTSEqualsDTS(&rtp.Packet{ + Payload: []byte{0x01}, + })) +} + func TestH264Clone(t *testing.T) { format := &H264{ PayloadTyp: 96, diff --git a/pkg/format/h265_test.go b/pkg/format/h265_test.go index 7c9c14da..9174b30a 100644 --- a/pkg/format/h265_test.go +++ b/pkg/format/h265_test.go @@ -3,6 +3,7 @@ package format import ( "testing" + "github.com/pion/rtp" "github.com/stretchr/testify/require" ) @@ -16,6 +17,7 @@ func TestH265Attributes(t *testing.T) { require.Equal(t, "H265", format.String()) require.Equal(t, 90000, format.ClockRate()) require.Equal(t, uint8(96), format.PayloadType()) + require.Equal(t, true, format.PTSEqualsDTS(&rtp.Packet{})) require.Equal(t, []byte{0x01, 0x02}, format.SafeVPS()) require.Equal(t, []byte{0x03, 0x04}, format.SafeSPS()) require.Equal(t, []byte{0x05, 0x06}, format.SafePPS()) diff --git a/pkg/format/jpeg_test.go b/pkg/format/jpeg_test.go index f78105da..3ef04bde 100644 --- a/pkg/format/jpeg_test.go +++ b/pkg/format/jpeg_test.go @@ -3,6 +3,7 @@ package format import ( "testing" + "github.com/pion/rtp" "github.com/stretchr/testify/require" ) @@ -11,6 +12,7 @@ func TestJPEGAttributes(t *testing.T) { require.Equal(t, "JPEG", format.String()) require.Equal(t, 90000, format.ClockRate()) require.Equal(t, uint8(26), format.PayloadType()) + require.Equal(t, true, format.PTSEqualsDTS(&rtp.Packet{})) } func TestJPEGClone(t *testing.T) { diff --git a/pkg/format/lpcm_test.go b/pkg/format/lpcm_test.go index 05bd39b4..ebd9f226 100644 --- a/pkg/format/lpcm_test.go +++ b/pkg/format/lpcm_test.go @@ -3,6 +3,7 @@ package format import ( "testing" + "github.com/pion/rtp" "github.com/stretchr/testify/require" ) @@ -16,6 +17,7 @@ func TestLPCMAttributes(t *testing.T) { require.Equal(t, "LPCM", format.String()) require.Equal(t, 44100, format.ClockRate()) require.Equal(t, uint8(96), format.PayloadType()) + require.Equal(t, true, format.PTSEqualsDTS(&rtp.Packet{})) } func TestTracLPCMClone(t *testing.T) { diff --git a/pkg/format/mpeg2audio_test.go b/pkg/format/mpeg2audio_test.go index 3c9f07ad..49aea3db 100644 --- a/pkg/format/mpeg2audio_test.go +++ b/pkg/format/mpeg2audio_test.go @@ -3,6 +3,7 @@ package format import ( "testing" + "github.com/pion/rtp" "github.com/stretchr/testify/require" ) @@ -11,6 +12,7 @@ func TestMPEG2AudioAttributes(t *testing.T) { require.Equal(t, "MPEG2-audio", format.String()) require.Equal(t, 90000, format.ClockRate()) require.Equal(t, uint8(14), format.PayloadType()) + require.Equal(t, true, format.PTSEqualsDTS(&rtp.Packet{})) } func TestMPEG2AudioClone(t *testing.T) { diff --git a/pkg/format/mpeg2video_test.go b/pkg/format/mpeg2video_test.go index a6be4934..b754b314 100644 --- a/pkg/format/mpeg2video_test.go +++ b/pkg/format/mpeg2video_test.go @@ -3,6 +3,7 @@ package format import ( "testing" + "github.com/pion/rtp" "github.com/stretchr/testify/require" ) @@ -11,6 +12,7 @@ func TestMPEG2VideoAttributes(t *testing.T) { require.Equal(t, "MPEG2-video", format.String()) require.Equal(t, 90000, format.ClockRate()) require.Equal(t, uint8(32), format.PayloadType()) + require.Equal(t, true, format.PTSEqualsDTS(&rtp.Packet{})) } func TestMPEG2VideoClone(t *testing.T) { diff --git a/pkg/format/mpeg4audio_test.go b/pkg/format/mpeg4audio_test.go index aa75e513..c245bab9 100644 --- a/pkg/format/mpeg4audio_test.go +++ b/pkg/format/mpeg4audio_test.go @@ -3,6 +3,7 @@ package format import ( "testing" + "github.com/pion/rtp" "github.com/stretchr/testify/require" "github.com/aler9/gortsplib/v2/pkg/mpeg4audio" @@ -23,6 +24,7 @@ func TestMPEG4AudioAttributes(t *testing.T) { require.Equal(t, "MPEG4-audio", format.String()) require.Equal(t, 48000, format.ClockRate()) require.Equal(t, uint8(96), format.PayloadType()) + require.Equal(t, true, format.PTSEqualsDTS(&rtp.Packet{})) } func TestMPEG4AudioClone(t *testing.T) { diff --git a/pkg/format/opus_test.go b/pkg/format/opus_test.go index 36639657..a61aad58 100644 --- a/pkg/format/opus_test.go +++ b/pkg/format/opus_test.go @@ -3,6 +3,7 @@ package format import ( "testing" + "github.com/pion/rtp" "github.com/stretchr/testify/require" ) @@ -15,6 +16,7 @@ func TestOpusAttributes(t *testing.T) { require.Equal(t, "Opus", format.String()) require.Equal(t, 48000, format.ClockRate()) require.Equal(t, uint8(96), format.PayloadType()) + require.Equal(t, true, format.PTSEqualsDTS(&rtp.Packet{})) } func TestTracOpusClone(t *testing.T) { diff --git a/pkg/format/vorbis_test.go b/pkg/format/vorbis_test.go index 473c74ca..13b6fe33 100644 --- a/pkg/format/vorbis_test.go +++ b/pkg/format/vorbis_test.go @@ -3,6 +3,7 @@ package format import ( "testing" + "github.com/pion/rtp" "github.com/stretchr/testify/require" ) @@ -16,6 +17,7 @@ func TestVorbisAttributes(t *testing.T) { require.Equal(t, "Vorbis", format.String()) require.Equal(t, 48000, format.ClockRate()) require.Equal(t, uint8(96), format.PayloadType()) + require.Equal(t, true, format.PTSEqualsDTS(&rtp.Packet{})) } func TestTracVorbisClone(t *testing.T) { diff --git a/pkg/format/vp8_test.go b/pkg/format/vp8_test.go index 154f4a57..69447811 100644 --- a/pkg/format/vp8_test.go +++ b/pkg/format/vp8_test.go @@ -3,6 +3,7 @@ package format import ( "testing" + "github.com/pion/rtp" "github.com/stretchr/testify/require" ) @@ -13,6 +14,7 @@ func TestVP8ttributes(t *testing.T) { require.Equal(t, "VP8", format.String()) require.Equal(t, 90000, format.ClockRate()) require.Equal(t, uint8(99), format.PayloadType()) + require.Equal(t, true, format.PTSEqualsDTS(&rtp.Packet{})) } func TestVP8Clone(t *testing.T) { diff --git a/pkg/format/vp9_test.go b/pkg/format/vp9_test.go index 5cc56b8e..9a24384f 100644 --- a/pkg/format/vp9_test.go +++ b/pkg/format/vp9_test.go @@ -3,6 +3,7 @@ package format import ( "testing" + "github.com/pion/rtp" "github.com/stretchr/testify/require" ) @@ -13,6 +14,7 @@ func TestVP9Attributes(t *testing.T) { require.Equal(t, "VP9", format.String()) require.Equal(t, 90000, format.ClockRate()) require.Equal(t, uint8(100), format.PayloadType()) + require.Equal(t, true, format.PTSEqualsDTS(&rtp.Packet{})) } func TestVP9Clone(t *testing.T) { diff --git a/pkg/h264/idrpresent_test.go b/pkg/h264/idrpresent_test.go new file mode 100644 index 00000000..209f9c80 --- /dev/null +++ b/pkg/h264/idrpresent_test.go @@ -0,0 +1,17 @@ +package h264 + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestIDRPresent(t *testing.T) { + require.Equal(t, true, IDRPresent([][]byte{ + {0x05}, + {0x07}, + })) + require.Equal(t, false, IDRPresent([][]byte{ + {0x01}, + })) +} diff --git a/pkg/mpeg4audio/config_test.go b/pkg/mpeg4audio/config_test.go index ecc6c573..d7606da1 100644 --- a/pkg/mpeg4audio/config_test.go +++ b/pkg/mpeg4audio/config_test.go @@ -67,6 +67,15 @@ var configCases = []struct { CoreCoderDelay: 385, }, }, + { + "aac-lc 44.1khz 8 chans", + []byte{0x12, 0x38}, + Config{ + Type: ObjectTypeAACLC, + SampleRate: 44100, + ChannelCount: 8, + }, + }, { "sbr (he-aac v1) 44.1khz stereo", []byte{0x2b, 0x8a, 0x00}, @@ -90,6 +99,46 @@ func TestConfigUnmarshal(t *testing.T) { } } +func TestConfigUnmarshalErrors(t *testing.T) { + for _, ca := range []struct { + name string + enc []byte + err string + }{ + { + "empty", + []byte{}, + "not enough bits", + }, + { + "unsupported object type", + []byte{0xF1}, + "unsupported object type: 30", + }, + { + "no sample rate index", + []byte{0b00010000}, + "not enough bits", + }, + { + "invalid sample rate index", + []byte{0b00010110, 0b10000000}, + "invalid sample rate index (13)", + }, + { + "channel config 0", + []byte{0b00010100, 0b00000000}, + "not yet supported", + }, + } { + t.Run(ca.name, func(t *testing.T) { + var dec Config + err := dec.Unmarshal(ca.enc) + require.EqualError(t, err, ca.err) + }) + } +} + func TestConfigMarshal(t *testing.T) { for _, ca := range configCases { t.Run(ca.name, func(t *testing.T) { diff --git a/server_test.go b/server_test.go index 8d3fa8a2..f1d6401b 100644 --- a/server_test.go +++ b/server_test.go @@ -1136,7 +1136,7 @@ func TestServerAuth(t *testing.T) { s := &Server{ Handler: &testServerHandler{ onAnnounce: func(ctx *ServerHandlerOnAnnounceCtx) (*base.Response, error) { - err := authValidator.ValidateRequest(ctx.Request) + err := authValidator.ValidateRequest(ctx.Request, nil) if err != nil { return &base.Response{ StatusCode: base.StatusUnauthorized,