diff --git a/pkg/base/url.go b/pkg/base/url.go index a2172ff1..83e74450 100644 --- a/pkg/base/url.go +++ b/pkg/base/url.go @@ -83,7 +83,7 @@ func (u *URL) RTSPPath() (string, bool) { return path, true } -// RTSPPathAndQuery returns the path and the query of a RTSP URL. +// RTSPPathAndQuery returns the path and query of a RTSP URL. func (u *URL) RTSPPathAndQuery() (string, bool) { var pathAndQuery string if u.RawPath != "" { @@ -104,6 +104,19 @@ func (u *URL) RTSPPathAndQuery() (string, bool) { return pathAndQuery, true } +// SetRTSPPathAndQuery sets the path and query of a RTSP URL. +func (u *URL) SetRTSPPathAndQuery(pathAndQuery string) { + nu1 := &URL{ + Scheme: u.Scheme, + Opaque: u.Opaque, + User: u.User, + Host: u.Host, + Path: "/", + } + nu2, _ := ParseURL(nu1.String() + pathAndQuery) + *u = *nu2 +} + // AddControlAttribute adds a control attribute to a RTSP url. func (u *URL) AddControlAttribute(controlPath string) { if controlPath[0] != '?' { diff --git a/serverconf_test.go b/serverconf_test.go index 5c2ace55..557425cc 100644 --- a/serverconf_test.go +++ b/serverconf_test.go @@ -170,6 +170,22 @@ func (ts *testServ) handleConn(conn *ServerConn) { } onSetup := func(req *base.Request, th *headers.Transport, trackID int) (*base.Response, error) { + reqPath, ok := req.URL.RTSPPath() + if !ok { + return &base.Response{ + StatusCode: base.StatusBadRequest, + }, fmt.Errorf("invalid path (%s)", req.URL) + } + + switch conn.State() { + case ServerConnStateInitial, ServerConnStatePrePlay: + if reqPath != "teststream" { + return &base.Response{ + StatusCode: base.StatusBadRequest, + }, fmt.Errorf("invalid path (%s)", req.URL) + } + } + return &base.Response{ StatusCode: base.StatusOK, Header: base.Header{ diff --git a/serverconn.go b/serverconn.go index 49d8fc97..a1817503 100644 --- a/serverconn.go +++ b/serverconn.go @@ -514,12 +514,8 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) { trackID := int(tmp) // remove track ID from path - nu := &base.URL{ - Scheme: req.URL.Scheme, - Host: req.URL.Host, - User: req.URL.User, - } - nu, _ = base.ParseURL(nu.String() + pathAndQuery[:i]) + nu := req.URL.Clone() + nu.SetRTSPPathAndQuery(pathAndQuery[:i]) req.URL = nu return trackID, nil diff --git a/track.go b/track.go index d77cd08d..627acf1a 100644 --- a/track.go +++ b/track.go @@ -167,7 +167,7 @@ func (t *Track) URL() (*base.URL, error) { return nil, fmt.Errorf("empty base url") } - control := func() string { + controlAttr := func() string { for _, attr := range t.Media.Attributes { if attr.Key == "control" { return attr.Value @@ -177,13 +177,13 @@ func (t *Track) URL() (*base.URL, error) { }() // no control attribute, use base URL - if control == "" { + if controlAttr == "" { return t.BaseURL, nil } // control attribute contains an absolute path - if strings.HasPrefix(control, "rtsp://") { - ur, err := base.ParseURL(control) + if strings.HasPrefix(controlAttr, "rtsp://") { + ur, err := base.ParseURL(controlAttr) if err != nil { return nil, err } @@ -196,7 +196,7 @@ func (t *Track) URL() (*base.URL, error) { // control attribute contains a relative control attribute ur := t.BaseURL.Clone() - ur.AddControlAttribute(control) + ur.AddControlAttribute(controlAttr) return ur, nil }