Browse Source

rewrite path handling; forbid slashes in base path

pull/54/head
aler9 5 years ago
parent
commit
6fcc3ee1e4
  1. 64
      client.go
  2. 22
      utils.go

64
client.go

@ -275,21 +275,12 @@ func (c *client) handleRequest(req *gortsplib.Request) bool {
return false return false
} }
path := func() string { path := req.Url.Path
ret := req.Url.Path if len(path) < 1 || path[0] != '/' {
c.writeResError(req, gortsplib.StatusBadRequest, fmt.Errorf("path must begin with a slash"))
// remove leading slash return false
if len(ret) > 1 { }
ret = ret[1:] path = path[1:] // strip leading slash
}
// strip any subpath
if n := strings.Index(ret, "/"); n >= 0 {
ret = ret[:n]
}
return ret
}()
switch req.Method { switch req.Method {
case gortsplib.OPTIONS: case gortsplib.OPTIONS:
@ -358,7 +349,12 @@ func (c *client) handleRequest(req *gortsplib.Request) bool {
} }
if len(path) == 0 { if len(path) == 0 {
c.writeResError(req, gortsplib.StatusBadRequest, fmt.Errorf("path can't be empty")) c.writeResError(req, gortsplib.StatusBadRequest, fmt.Errorf("empty base path"))
return false
}
if strings.Index(path, "/") >= 0 {
c.writeResError(req, gortsplib.StatusBadRequest, fmt.Errorf("slashes in the path are not supported (%s)", path))
return false return false
} }
@ -437,13 +433,19 @@ func (c *client) handleRequest(req *gortsplib.Request) bool {
return false return false
} }
basePath, _, err := splitPath(path)
if err != nil {
c.writeResError(req, gortsplib.StatusBadRequest, err)
return false
}
switch c.state { switch c.state {
// play // play
case clientStateInitial, clientStatePrePlay: case clientStateInitial, clientStatePrePlay:
confp := c.p.findConfForPath(path) confp := c.p.findConfForPath(basePath)
if confp == nil { if confp == nil {
c.writeResError(req, gortsplib.StatusBadRequest, c.writeResError(req, gortsplib.StatusBadRequest,
fmt.Errorf("unable to find a valid configuration for path '%s'", path)) fmt.Errorf("unable to find a valid configuration for path '%s'", basePath))
return false return false
} }
@ -478,8 +480,8 @@ func (c *client) handleRequest(req *gortsplib.Request) bool {
return false return false
} }
if c.pathId != "" && path != c.pathId { if c.pathId != "" && basePath != c.pathId {
c.writeResError(req, gortsplib.StatusBadRequest, fmt.Errorf("path has changed")) c.writeResError(req, gortsplib.StatusBadRequest, fmt.Errorf("path has changed, was '%s', now is '%s'", c.pathId, basePath))
return false return false
} }
@ -489,7 +491,7 @@ func (c *client) handleRequest(req *gortsplib.Request) bool {
} }
res := make(chan error) res := make(chan error)
c.p.events <- programEventClientSetupPlay{res, c, path, gortsplib.StreamProtocolUdp, rtpPort, rtcpPort} c.p.events <- programEventClientSetupPlay{res, c, basePath, gortsplib.StreamProtocolUdp, rtpPort, rtcpPort}
err = <-res err = <-res
if err != nil { if err != nil {
c.writeResError(req, gortsplib.StatusBadRequest, err) c.writeResError(req, gortsplib.StatusBadRequest, err)
@ -518,8 +520,8 @@ func (c *client) handleRequest(req *gortsplib.Request) bool {
return false return false
} }
if c.pathId != "" && path != c.pathId { if c.pathId != "" && basePath != c.pathId {
c.writeResError(req, gortsplib.StatusBadRequest, fmt.Errorf("path has changed")) c.writeResError(req, gortsplib.StatusBadRequest, fmt.Errorf("path has changed, was '%s', now is '%s'", c.pathId, basePath))
return false return false
} }
@ -529,7 +531,7 @@ func (c *client) handleRequest(req *gortsplib.Request) bool {
} }
res := make(chan error) res := make(chan error)
c.p.events <- programEventClientSetupPlay{res, c, path, gortsplib.StreamProtocolTcp, 0, 0} c.p.events <- programEventClientSetupPlay{res, c, basePath, gortsplib.StreamProtocolTcp, 0, 0}
err = <-res err = <-res
if err != nil { if err != nil {
c.writeResError(req, gortsplib.StatusBadRequest, err) c.writeResError(req, gortsplib.StatusBadRequest, err)
@ -565,8 +567,8 @@ func (c *client) handleRequest(req *gortsplib.Request) bool {
} }
// after ANNOUNCE, c.pathId is already set // after ANNOUNCE, c.pathId is already set
if path != c.pathId { if basePath != c.pathId {
c.writeResError(req, gortsplib.StatusBadRequest, fmt.Errorf("path has changed")) c.writeResError(req, gortsplib.StatusBadRequest, fmt.Errorf("path has changed, was '%s', now is '%s'", c.pathId, basePath))
return false return false
} }
@ -694,8 +696,11 @@ func (c *client) handleRequest(req *gortsplib.Request) bool {
return false return false
} }
// path can end with a slash, remove it
path = strings.TrimSuffix(path, "/")
if path != c.pathId { if path != c.pathId {
c.writeResError(req, gortsplib.StatusBadRequest, fmt.Errorf("path has changed")) c.writeResError(req, gortsplib.StatusBadRequest, fmt.Errorf("path has changed, was '%s', now is '%s'", c.pathId, path))
return false return false
} }
@ -729,8 +734,11 @@ func (c *client) handleRequest(req *gortsplib.Request) bool {
return false return false
} }
// path can end with a slash, remove it
path = strings.TrimSuffix(path, "/")
if path != c.pathId { if path != c.pathId {
c.writeResError(req, gortsplib.StatusBadRequest, fmt.Errorf("path has changed")) c.writeResError(req, gortsplib.StatusBadRequest, fmt.Errorf("path has changed, was '%s', now is '%s'", c.pathId, path))
return false return false
} }

22
utils.go

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"net" "net"
"strconv" "strconv"
"strings"
"github.com/aler9/gortsplib" "github.com/aler9/gortsplib"
"github.com/aler9/sdp/v3" "github.com/aler9/sdp/v3"
@ -125,3 +126,24 @@ func sdpForServer(tracks []*gortsplib.Track) (*sdp.SessionDescription, []byte) {
bytsout, _ := sout.Marshal() bytsout, _ := sout.Marshal()
return sout, bytsout return sout, bytsout
} }
func splitPath(path string) (string, string, error) {
comps := strings.Split(path, "/")
if len(comps) < 2 {
return "", "", fmt.Errorf("the path must contain a base path and a control path (%s)", path)
}
if len(comps) > 2 {
return "", "", fmt.Errorf("slashes in the path are not supported (%s)", path)
}
if len(comps[0]) == 0 {
return "", "", fmt.Errorf("empty base path (%s)", path)
}
if len(comps[1]) == 0 {
return "", "", fmt.Errorf("empty control path (%s)", path)
}
return comps[0], comps[1], nil
}

Loading…
Cancel
Save