Browse Source

fix error when using vlc, authentication and slashes in paths

pull/169/head
aler9 5 years ago
parent
commit
e511eb4ef1
  1. 65
      client/client.go
  2. 38
      client/utils.go
  3. 2
      go.mod
  4. 4
      go.sum
  5. 10
      main_test.go

65
client/client.go

@ -278,7 +278,7 @@ func (c *Client) Authenticate(authMethods []headers.AuthMethod, ips []interface{ @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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
}

38
client/utils.go

@ -1,9 +1,7 @@ @@ -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 { @@ -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
}

2
go.mod

@ -5,7 +5,7 @@ go 1.15 @@ -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

4
go.sum

@ -2,8 +2,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafo @@ -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=

10
main_test.go

@ -454,7 +454,7 @@ func TestAuth(t *testing.T) { @@ -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) { @@ -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) { @@ -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) { @@ -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) { @@ -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()

Loading…
Cancel
Save