server: fix crash that happens when a reader tries to setup a closed stream (https://github.com/aler9/rtsp-simple-server/issues/866)

This commit is contained in:
aler9
2022-06-14 15:32:16 +02:00
parent 7d0e8ed058
commit aa08f973dd
2 changed files with 44 additions and 12 deletions

View File

@@ -148,7 +148,11 @@ func TestServerReadSetupPath(t *testing.T) {
}
func TestServerReadSetupErrors(t *testing.T) {
for _, ca := range []string{"different paths", "double setup"} {
for _, ca := range []string{
"different paths",
"double setup",
"closed stream",
} {
t.Run(ca, func(t *testing.T) {
connClosed := make(chan struct{})
@@ -156,15 +160,24 @@ func TestServerReadSetupErrors(t *testing.T) {
require.NoError(t, err)
stream := NewServerStream(Tracks{track})
if ca == "closed stream" {
stream.Close()
} else {
defer stream.Close()
}
s := &Server{
Handler: &testServerHandler{
onConnClose: func(ctx *ServerHandlerOnConnCloseCtx) {
if ca == "different paths" {
switch ca {
case "different paths":
require.EqualError(t, ctx.Error, "can't setup tracks with different paths")
} else {
case "double setup":
require.EqualError(t, ctx.Error, "track 0 has already been setup")
case "closed stream":
require.EqualError(t, ctx.Error, "stream is closed")
}
close(connClosed)
},
@@ -207,16 +220,17 @@ func TestServerReadSetupErrors(t *testing.T) {
"Transport": th.Write(),
},
})
switch ca {
case "different paths":
require.NoError(t, err)
require.Equal(t, base.StatusOK, res.StatusCode)
th.InterleavedIDs = &[2]int{2, 3}
var sx headers.Session
err = sx.Read(res.Header["Session"])
require.NoError(t, err)
th.InterleavedIDs = &[2]int{2, 3}
if ca == "different paths" {
res, err = writeReqReadRes(conn, br, base.Request{
Method: base.Setup,
URL: mustParseURL("rtsp://localhost:8554/test12stream/trackID=1"),
@@ -228,7 +242,16 @@ func TestServerReadSetupErrors(t *testing.T) {
})
require.NoError(t, err)
require.Equal(t, base.StatusBadRequest, res.StatusCode)
} else {
case "double setup":
require.NoError(t, err)
require.Equal(t, base.StatusOK, res.StatusCode)
var sx headers.Session
err = sx.Read(res.Header["Session"])
require.NoError(t, err)
th.InterleavedIDs = &[2]int{2, 3}
res, err = writeReqReadRes(conn, br, base.Request{
Method: base.Setup,
URL: mustParseURL("rtsp://localhost:8554/teststream/trackID=0"),
@@ -240,6 +263,10 @@ func TestServerReadSetupErrors(t *testing.T) {
})
require.NoError(t, err)
require.Equal(t, base.StatusBadRequest, res.StatusCode)
case "closed stream":
require.NoError(t, err)
require.Equal(t, base.StatusBadRequest, res.StatusCode)
}
<-connClosed

View File

@@ -1,6 +1,7 @@
package gortsplib
import (
"fmt"
"sync"
"time"
@@ -120,6 +121,10 @@ func (st *ServerStream) readerAdd(
st.mutex.Lock()
defer st.mutex.Unlock()
if st.readers == nil {
return fmt.Errorf("stream is closed")
}
if st.s == nil {
st.s = ss.s