diff --git a/client/client.go b/client/client.go index cae12fe0..9ed8e887 100644 --- a/client/client.go +++ b/client/client.go @@ -278,7 +278,7 @@ func (c *Client) Authenticate(authMethods []headers.AuthMethod, ips []interface{ c.authHelper = auth.NewServer(user, pass, authMethods) } - err := c.authHelper.ValidateHeader(req.Header["Authorization"], req.Method, req.Url) + err := c.authHelper.ValidateHeader(req.Header["Authorization"], req.Method, req.URL) if err != nil { c.authFailures += 1 @@ -330,19 +330,6 @@ func (c *Client) handleRequest(req *base.Request) error { return errRunTerminate } - pathName := req.Url.Path - if len(pathName) < 1 || pathName[0] != '/' { - c.writeResError(cseq, base.StatusBadRequest, fmt.Errorf("path must begin with a slash")) - return errRunTerminate - } - pathName = pathName[1:] // strip leading slash - - // in RTSP, the control path is inserted after the query. - // therefore, path and query can't be treated separately - if req.Url.RawQuery != "" { - pathName += "?" + req.Url.RawQuery - } - switch req.Method { case base.OPTIONS: c.conn.WriteResponse(&base.Response{ @@ -381,9 +368,13 @@ func (c *Client) handleRequest(req *base.Request) error { return errRunTerminate } - pathName = removeQueryFromPath(pathName) + basePath, ok := base.URLGetBasePath(req.URL) + if !ok { + c.writeResError(cseq, base.StatusBadRequest, fmt.Errorf("unable to find base path (%s)", req.URL)) + return errRunTerminate + } - path, err := c.parent.OnClientDescribe(c, pathName, req) + path, err := c.parent.OnClientDescribe(c, basePath, req) if err != nil { switch terr := err.(type) { case ErrAuthNotCritical: @@ -403,7 +394,7 @@ func (c *Client) handleRequest(req *base.Request) error { c.path = path c.state = stateWaitingDescribe c.describeCSeq = cseq - c.describeUrl = req.Url.String() + c.describeUrl = req.URL.String() return errRunWaitingDescribe @@ -436,9 +427,13 @@ func (c *Client) handleRequest(req *base.Request) error { return errRunTerminate } - pathName = removeQueryFromPath(pathName) + basePath, ok := base.URLGetBasePath(req.URL) + if !ok { + c.writeResError(cseq, base.StatusBadRequest, fmt.Errorf("unable to find base path (%s)", req.URL)) + return errRunTerminate + } - path, err := c.parent.OnClientAnnounce(c, pathName, tracks, req) + path, err := c.parent.OnClientAnnounce(c, basePath, tracks, req) if err != nil { switch terr := err.(type) { case ErrAuthNotCritical: @@ -478,14 +473,12 @@ func (c *Client) handleRequest(req *base.Request) error { return errRunTerminate } - basePath, controlPath, err := splitPathIntoBaseAndControl(pathName) - if err != nil { - c.writeResError(cseq, base.StatusBadRequest, err) + basePath, controlPath, ok := base.URLGetBaseControlPath(req.URL) + if !ok { + c.writeResError(cseq, base.StatusBadRequest, fmt.Errorf("unable to find control path (%s)", req.URL)) return errRunTerminate } - basePath = removeQueryFromPath(basePath) - switch c.state { // play case stateInitial, statePrePlay: @@ -759,13 +752,17 @@ func (c *Client) handleRequest(req *base.Request) error { return errRunTerminate } - pathName = removeQueryFromPath(pathName) + basePath, ok := base.URLGetBasePath(req.URL) + if !ok { + c.writeResError(cseq, base.StatusBadRequest, fmt.Errorf("unable to find base path (%s)", req.URL)) + return errRunTerminate + } // path can end with a slash, remove it - pathName = strings.TrimSuffix(pathName, "/") + basePath = strings.TrimSuffix(basePath, "/") - if pathName != c.path.Name() { - c.writeResError(cseq, base.StatusBadRequest, fmt.Errorf("path has changed, was '%s', now is '%s'", c.path.Name(), pathName)) + if basePath != c.path.Name() { + c.writeResError(cseq, base.StatusBadRequest, fmt.Errorf("path has changed, was '%s', now is '%s'", c.path.Name(), basePath)) return errRunTerminate } @@ -794,13 +791,17 @@ func (c *Client) handleRequest(req *base.Request) error { return errRunTerminate } - pathName = removeQueryFromPath(pathName) + basePath, ok := base.URLGetBasePath(req.URL) + if !ok { + c.writeResError(cseq, base.StatusBadRequest, fmt.Errorf("unable to find base path (%s)", req.URL)) + return errRunTerminate + } // path can end with a slash, remove it - pathName = strings.TrimSuffix(pathName, "/") + basePath = strings.TrimSuffix(basePath, "/") - if pathName != c.path.Name() { - c.writeResError(cseq, base.StatusBadRequest, fmt.Errorf("path has changed, was '%s', now is '%s'", c.path.Name(), pathName)) + if basePath != c.path.Name() { + c.writeResError(cseq, base.StatusBadRequest, fmt.Errorf("path has changed, was '%s', now is '%s'", c.path.Name(), basePath)) return errRunTerminate } diff --git a/client/utils.go b/client/utils.go index 68f44fd4..8d8e1454 100644 --- a/client/utils.go +++ b/client/utils.go @@ -1,9 +1,7 @@ package client import ( - "fmt" "net" - "strings" ) func ipEqualOrInRange(ip net.IP, ips []interface{}) bool { @@ -22,39 +20,3 @@ func ipEqualOrInRange(ip net.IP, ips []interface{}) bool { } return false } - -func removeQueryFromPath(path string) string { - i := strings.Index(path, "?") - if i >= 0 { - return path[:i] - } - return path -} - -func splitPathIntoBaseAndControl(path string) (string, string, error) { - pos := func() int { - for i := len(path) - 1; i >= 0; i-- { - if path[i] == '/' { - return i - } - } - return -1 - }() - - if pos < 0 { - return "", "", fmt.Errorf("the path must contain a base path and a control path (%s)", path) - } - - basePath := path[:pos] - controlPath := path[pos+1:] - - if len(basePath) == 0 { - return "", "", fmt.Errorf("empty base path (%s)", basePath) - } - - if len(controlPath) == 0 { - return "", "", fmt.Errorf("empty control path (%s)", controlPath) - } - - return basePath, controlPath, nil -} diff --git a/go.mod b/go.mod index 05477f83..9113fafe 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.15 require ( github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect - github.com/aler9/gortsplib v0.0.0-20201029205139-75db154a17e9 + github.com/aler9/gortsplib v0.0.0-20201031143942-e4e66789e9fe github.com/davecgh/go-spew v1.1.1 // indirect github.com/fsnotify/fsnotify v1.4.9 github.com/notedit/rtmp v0.0.2 diff --git a/go.sum b/go.sum index 0ca5abc4..134b2dc1 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafo github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/aler9/gortsplib v0.0.0-20201029205139-75db154a17e9 h1:Yyp3cCYdYQ5mkXuA/D8fS6Xg5ZXddw0gd9gShYixKac= -github.com/aler9/gortsplib v0.0.0-20201029205139-75db154a17e9/go.mod h1:8mpBfMEJIZn2C5fMM6vRYHgGH49WX0EH8gP1SDxv0Uw= +github.com/aler9/gortsplib v0.0.0-20201031143942-e4e66789e9fe h1:iuI/+O8cu9ts0s5kHddFVEMc+oD06MMDWGN59oxUWTI= +github.com/aler9/gortsplib v0.0.0-20201031143942-e4e66789e9fe/go.mod h1:8mpBfMEJIZn2C5fMM6vRYHgGH49WX0EH8gP1SDxv0Uw= github.com/aler9/sdp-dirty/v3 v3.0.0-20200919115950-f1abc664f625 h1:A3upkpYzceQTuBPvVleu1zd6R8jInhg5ifimSO7ku/o= github.com/aler9/sdp-dirty/v3 v3.0.0-20200919115950-f1abc664f625/go.mod h1:5bO/aUQr9m3OasDatNNcVqKAgs7r5hgGXmszWHaC6mI= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= diff --git a/main_test.go b/main_test.go index ff029f9e..a4967b12 100644 --- a/main_test.go +++ b/main_test.go @@ -454,7 +454,7 @@ func TestAuth(t *testing.T) { "-c", "copy", "-f", "rtsp", "-rtsp_transport", "udp", - "rtsp://testuser:test!$()*+.;<=>[]^_-{}@" + ownDockerIp + ":8554/teststream", + "rtsp://testuser:test!$()*+.;<=>[]^_-{}@" + ownDockerIp + ":8554/test/stream", }) require.NoError(t, err) defer cnt1.close() @@ -463,7 +463,7 @@ func TestAuth(t *testing.T) { cnt2, err := newContainer("ffmpeg", "dest", []string{ "-rtsp_transport", "udp", - "-i", "rtsp://" + ownDockerIp + ":8554/teststream", + "-i", "rtsp://" + ownDockerIp + ":8554/test/stream", "-vframes", "1", "-f", "image2", "-y", "/dev/null", @@ -497,7 +497,7 @@ func TestAuth(t *testing.T) { "-c", "copy", "-f", "rtsp", "-rtsp_transport", "udp", - "rtsp://" + ownDockerIp + ":8554/teststream", + "rtsp://" + ownDockerIp + ":8554/test/stream", }) require.NoError(t, err) defer cnt1.close() @@ -507,7 +507,7 @@ func TestAuth(t *testing.T) { if soft == "ffmpeg" { cnt2, err := newContainer("ffmpeg", "dest", []string{ "-rtsp_transport", "udp", - "-i", "rtsp://testuser:test!$()*+.;<=>[]^_-{}@" + ownDockerIp + ":8554/teststream", + "-i", "rtsp://testuser:test!$()*+.;<=>[]^_-{}@" + ownDockerIp + ":8554/test/stream", "-vframes", "1", "-f", "image2", "-y", "/dev/null", @@ -520,7 +520,7 @@ func TestAuth(t *testing.T) { } else { cnt2, err := newContainer("vlc", "dest", []string{ - "rtsp://testuser:test!$()*+.;<=>[]^_-{}@" + ownDockerIp + ":8554/teststream", + "rtsp://testuser:test!$()*+.;<=>[]^_-{}@" + ownDockerIp + ":8554/test/stream", }) require.NoError(t, err) defer cnt2.close()