mirror of
https://github.com/bluenviron/mediamtx.git
synced 2026-01-26 21:39:16 -08:00
fix error when using vlc, authentication and slashes in paths
This commit is contained in:
parent
c0d282ab42
commit
e511eb4ef1
5 changed files with 41 additions and 78 deletions
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
2
go.mod
2
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
|
||||
|
|
|
|||
4
go.sum
4
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=
|
||||
|
|
|
|||
10
main_test.go
10
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()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue