From 2bffbe4a093e391134a6dbe31c80b85706c107b1 Mon Sep 17 00:00:00 2001 From: aler9 <46489434+aler9@users.noreply.github.com> Date: Sat, 29 May 2021 18:29:32 +0200 Subject: [PATCH] RTSP: support sources with empty passwords (#395) --- internal/conf/path.go | 11 +------- main_rtspsource_test.go | 59 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 10 deletions(-) diff --git a/internal/conf/path.go b/internal/conf/path.go index ba3323bb..78a73671 100644 --- a/internal/conf/path.go +++ b/internal/conf/path.go @@ -137,20 +137,11 @@ func (pconf *PathConf) fillAndCheck(name string) error { return fmt.Errorf("a path with a regular expression (or path 'all') cannot have a RTSP source; use another path") } - u, err := base.ParseURL(pconf.Source) + _, err := base.ParseURL(pconf.Source) if err != nil { return fmt.Errorf("'%s' is not a valid RTSP URL", pconf.Source) } - if u.User != nil { - pass, _ := u.User.Password() - user := u.User.Username() - if user != "" && pass == "" || - user == "" && pass != "" { - return fmt.Errorf("username and password must be both provided") - } - } - if pconf.SourceProtocol == "" { pconf.SourceProtocol = "automatic" } diff --git a/main_rtspsource_test.go b/main_rtspsource_test.go index d3e29f89..df2673bf 100644 --- a/main_rtspsource_test.go +++ b/main_rtspsource_test.go @@ -5,6 +5,9 @@ import ( "testing" "time" + "github.com/aler9/gortsplib" + "github.com/aler9/gortsplib/pkg/auth" + "github.com/aler9/gortsplib/pkg/base" "github.com/stretchr/testify/require" ) @@ -116,3 +119,59 @@ func TestSourceRTSP(t *testing.T) { }) } } + +type testServerNoPassword struct { + authValidator *auth.Validator + done chan struct{} +} + +func (sh *testServerNoPassword) OnDescribe(ctx *gortsplib.ServerHandlerOnDescribeCtx) (*base.Response, []byte, error) { + if sh.authValidator == nil { + sh.authValidator = auth.NewValidator("testuser", "", nil) + } + + err := sh.authValidator.ValidateHeader(ctx.Req.Header["Authorization"], + ctx.Req.Method, ctx.Req.URL, nil) + if err != nil { + return &base.Response{ + StatusCode: base.StatusUnauthorized, + Header: base.Header{ + "WWW-Authenticate": sh.authValidator.GenerateHeader(), + }, + }, nil, nil + } + + track, _ := gortsplib.NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x05, 0x06}) + + return &base.Response{ + StatusCode: base.StatusOK, + }, gortsplib.Tracks{track}.Write(), nil +} + +// called after receiving a SETUP request. +func (sh *testServerNoPassword) OnSetup(ctx *gortsplib.ServerHandlerOnSetupCtx) (*base.Response, *uint32, error) { + close(sh.done) + return &base.Response{ + StatusCode: base.StatusOK, + }, nil, nil +} + +func TestSourceRTSPNoPassword(t *testing.T) { + done := make(chan struct{}) + s := gortsplib.Server{Handler: &testServerNoPassword{done: done}} + err := s.Start("127.0.0.1:8555") + require.NoError(t, err) + defer s.Close() + + p, ok := testProgram("rtmpDisable: yes\n" + + "hlsDisable: yes\n" + + "paths:\n" + + " proxied:\n" + + " source: rtsp://testuser:@127.0.0.1:8555/teststream\n" + + " sourceProtocol: tcp\n") + require.Equal(t, true, ok) + defer p.close() + + <-done + // require.Equal(t, 0, cnt.wait()) +}