server: change OnSetup() to allow users to set SSRC (#33)

This commit is contained in:
aler9
2021-05-16 15:09:08 +02:00
parent 39c544e09f
commit 4b385ec04b
7 changed files with 106 additions and 97 deletions

View File

@@ -93,12 +93,12 @@ func (sh *serverHandler) OnAnnounce(ctx *gortsplib.ServerHandlerOnAnnounceCtx) (
} }
// called after receiving a SETUP request. // called after receiving a SETUP request.
func (sh *serverHandler) OnSetup(ctx *gortsplib.ServerHandlerOnSetupCtx) (*base.Response, error) { func (sh *serverHandler) OnSetup(ctx *gortsplib.ServerHandlerOnSetupCtx) (*base.Response, *uint32, error) {
log.Printf("setup request") log.Printf("setup request")
return &base.Response{ return &base.Response{
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil, nil
} }
// called after receiving a PLAY request. // called after receiving a PLAY request.

View File

@@ -92,12 +92,12 @@ func (sh *serverHandler) OnAnnounce(ctx *gortsplib.ServerHandlerOnAnnounceCtx) (
} }
// called after receiving a SETUP request. // called after receiving a SETUP request.
func (sh *serverHandler) OnSetup(ctx *gortsplib.ServerHandlerOnSetupCtx) (*base.Response, error) { func (sh *serverHandler) OnSetup(ctx *gortsplib.ServerHandlerOnSetupCtx) (*base.Response, *uint32, error) {
log.Printf("setup request") log.Printf("setup request")
return &base.Response{ return &base.Response{
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil, nil
} }
// called after receiving a PLAY request. // called after receiving a PLAY request.

View File

@@ -301,12 +301,12 @@ func TestServerPublishSetupPath(t *testing.T) {
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil
}, },
onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, error) { onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, *uint32, error) {
require.Equal(t, ca.path, ctx.Path) require.Equal(t, ca.path, ctx.Path)
require.Equal(t, ca.trackID, ctx.TrackID) require.Equal(t, ca.trackID, ctx.TrackID)
return &base.Response{ return &base.Response{
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil, nil
}, },
}, },
} }
@@ -398,10 +398,10 @@ func TestServerPublishErrorSetupDifferentPaths(t *testing.T) {
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil
}, },
onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, error) { onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, *uint32, error) {
return &base.Response{ return &base.Response{
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil, nil
}, },
}, },
} }
@@ -480,10 +480,10 @@ func TestServerPublishErrorSetupTrackTwice(t *testing.T) {
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil
}, },
onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, error) { onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, *uint32, error) {
return &base.Response{ return &base.Response{
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil, nil
}, },
}, },
} }
@@ -574,10 +574,10 @@ func TestServerPublishErrorRecordPartialTracks(t *testing.T) {
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil
}, },
onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, error) { onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, *uint32, error) {
return &base.Response{ return &base.Response{
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil, nil
}, },
onRecord: func(ctx *ServerHandlerOnRecordCtx) (*base.Response, error) { onRecord: func(ctx *ServerHandlerOnRecordCtx) (*base.Response, error) {
return &base.Response{ return &base.Response{
@@ -694,10 +694,10 @@ func TestServerPublish(t *testing.T) {
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil
}, },
onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, error) { onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, *uint32, error) {
return &base.Response{ return &base.Response{
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil, nil
}, },
onRecord: func(ctx *ServerHandlerOnRecordCtx) (*base.Response, error) { onRecord: func(ctx *ServerHandlerOnRecordCtx) (*base.Response, error) {
return &base.Response{ return &base.Response{
@@ -912,10 +912,10 @@ func TestServerPublishErrorWrongProtocol(t *testing.T) {
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil
}, },
onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, error) { onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, *uint32, error) {
return &base.Response{ return &base.Response{
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil, nil
}, },
onRecord: func(ctx *ServerHandlerOnRecordCtx) (*base.Response, error) { onRecord: func(ctx *ServerHandlerOnRecordCtx) (*base.Response, error) {
return &base.Response{ return &base.Response{
@@ -1018,10 +1018,10 @@ func TestServerPublishRTCPReport(t *testing.T) {
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil
}, },
onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, error) { onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, *uint32, error) {
return &base.Response{ return &base.Response{
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil, nil
}, },
onRecord: func(ctx *ServerHandlerOnRecordCtx) (*base.Response, error) { onRecord: func(ctx *ServerHandlerOnRecordCtx) (*base.Response, error) {
return &base.Response{ return &base.Response{
@@ -1174,10 +1174,10 @@ func TestServerPublishTimeout(t *testing.T) {
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil
}, },
onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, error) { onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, *uint32, error) {
return &base.Response{ return &base.Response{
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil, nil
}, },
onRecord: func(ctx *ServerHandlerOnRecordCtx) (*base.Response, error) { onRecord: func(ctx *ServerHandlerOnRecordCtx) (*base.Response, error) {
return &base.Response{ return &base.Response{
@@ -1302,10 +1302,10 @@ func TestServerPublishWithoutTeardown(t *testing.T) {
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil
}, },
onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, error) { onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, *uint32, error) {
return &base.Response{ return &base.Response{
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil, nil
}, },
onRecord: func(ctx *ServerHandlerOnRecordCtx) (*base.Response, error) { onRecord: func(ctx *ServerHandlerOnRecordCtx) (*base.Response, error) {
return &base.Response{ return &base.Response{
@@ -1414,10 +1414,10 @@ func TestServerPublishUDPChangeConn(t *testing.T) {
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil
}, },
onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, error) { onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, *uint32, error) {
return &base.Response{ return &base.Response{
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil, nil
}, },
onRecord: func(ctx *ServerHandlerOnRecordCtx) (*base.Response, error) { onRecord: func(ctx *ServerHandlerOnRecordCtx) (*base.Response, error) {
return &base.Response{ return &base.Response{

View File

@@ -61,12 +61,12 @@ func TestServerReadSetupPath(t *testing.T) {
t.Run(ca.name, func(t *testing.T) { t.Run(ca.name, func(t *testing.T) {
s := &Server{ s := &Server{
Handler: &testServerHandler{ Handler: &testServerHandler{
onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, error) { onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, *uint32, error) {
require.Equal(t, ca.path, ctx.Path) require.Equal(t, ca.path, ctx.Path)
require.Equal(t, ca.trackID, ctx.TrackID) require.Equal(t, ca.trackID, ctx.TrackID)
return &base.Response{ return &base.Response{
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil, nil
}, },
}, },
} }
@@ -116,10 +116,10 @@ func TestServerReadErrorSetupDifferentPaths(t *testing.T) {
require.Equal(t, "can't setup tracks with different paths", ctx.Error.Error()) require.Equal(t, "can't setup tracks with different paths", ctx.Error.Error())
close(connClosed) close(connClosed)
}, },
onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, error) { onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, *uint32, error) {
return &base.Response{ return &base.Response{
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil, nil
}, },
}, },
} }
@@ -183,10 +183,10 @@ func TestServerReadErrorSetupTrackTwice(t *testing.T) {
require.Equal(t, "track 0 has already been setup", ctx.Error.Error()) require.Equal(t, "track 0 has already been setup", ctx.Error.Error())
close(connClosed) close(connClosed)
}, },
onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, error) { onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, *uint32, error) {
return &base.Response{ return &base.Response{
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil, nil
}, },
}, },
} }
@@ -268,10 +268,11 @@ func TestServerRead(t *testing.T) {
onSessionClose: func(ctx *ServerHandlerOnSessionCloseCtx) { onSessionClose: func(ctx *ServerHandlerOnSessionCloseCtx) {
close(sessionClosed) close(sessionClosed)
}, },
onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, error) { onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, *uint32, error) {
v := uint32(123456)
return &base.Response{ return &base.Response{
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, &v, nil
}, },
onPlay: func(ctx *ServerHandlerOnPlayCtx) (*base.Response, error) { onPlay: func(ctx *ServerHandlerOnPlayCtx) (*base.Response, error) {
ctx.Session.WriteFrame(0, StreamTypeRTP, []byte{0x01, 0x02, 0x03, 0x04}) ctx.Session.WriteFrame(0, StreamTypeRTP, []byte{0x01, 0x02, 0x03, 0x04})
@@ -356,6 +357,7 @@ func TestServerRead(t *testing.T) {
var th headers.Transport var th headers.Transport
err = th.Read(res.Header["Transport"]) err = th.Read(res.Header["Transport"])
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, uint32(123456), *th.SSRC)
<-sessionOpened <-sessionOpened
@@ -483,10 +485,10 @@ func TestServerReadTCPResponseBeforeFrames(t *testing.T) {
close(writerTerminate) close(writerTerminate)
<-writerDone <-writerDone
}, },
onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, error) { onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, *uint32, error) {
return &base.Response{ return &base.Response{
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil, nil
}, },
onPlay: func(ctx *ServerHandlerOnPlayCtx) (*base.Response, error) { onPlay: func(ctx *ServerHandlerOnPlayCtx) (*base.Response, error) {
go func() { go func() {
@@ -567,10 +569,10 @@ func TestServerReadTCPResponseBeforeFrames(t *testing.T) {
func TestServerReadPlayPlay(t *testing.T) { func TestServerReadPlayPlay(t *testing.T) {
s := &Server{ s := &Server{
Handler: &testServerHandler{ Handler: &testServerHandler{
onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, error) { onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, *uint32, error) {
return &base.Response{ return &base.Response{
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil, nil
}, },
onPlay: func(ctx *ServerHandlerOnPlayCtx) (*base.Response, error) { onPlay: func(ctx *ServerHandlerOnPlayCtx) (*base.Response, error) {
return &base.Response{ return &base.Response{
@@ -647,10 +649,10 @@ func TestServerReadPlayPausePlay(t *testing.T) {
close(writerTerminate) close(writerTerminate)
<-writerDone <-writerDone
}, },
onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, error) { onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, *uint32, error) {
return &base.Response{ return &base.Response{
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil, nil
}, },
onPlay: func(ctx *ServerHandlerOnPlayCtx) (*base.Response, error) { onPlay: func(ctx *ServerHandlerOnPlayCtx) (*base.Response, error) {
if !writerStarted { if !writerStarted {
@@ -759,10 +761,10 @@ func TestServerReadPlayPausePause(t *testing.T) {
close(writerTerminate) close(writerTerminate)
<-writerDone <-writerDone
}, },
onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, error) { onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, *uint32, error) {
return &base.Response{ return &base.Response{
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil, nil
}, },
onPlay: func(ctx *ServerHandlerOnPlayCtx) (*base.Response, error) { onPlay: func(ctx *ServerHandlerOnPlayCtx) (*base.Response, error) {
go func() { go func() {
@@ -882,10 +884,10 @@ func TestServerReadTimeout(t *testing.T) {
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil
}, },
onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, error) { onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, *uint32, error) {
return &base.Response{ return &base.Response{
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil, nil
}, },
onPlay: func(ctx *ServerHandlerOnPlayCtx) (*base.Response, error) { onPlay: func(ctx *ServerHandlerOnPlayCtx) (*base.Response, error) {
return &base.Response{ return &base.Response{
@@ -972,10 +974,10 @@ func TestServerReadWithoutTeardown(t *testing.T) {
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil
}, },
onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, error) { onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, *uint32, error) {
return &base.Response{ return &base.Response{
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil, nil
}, },
onPlay: func(ctx *ServerHandlerOnPlayCtx) (*base.Response, error) { onPlay: func(ctx *ServerHandlerOnPlayCtx) (*base.Response, error) {
return &base.Response{ return &base.Response{
@@ -1053,10 +1055,10 @@ func TestServerReadWithoutTeardown(t *testing.T) {
func TestServerReadUDPChangeConn(t *testing.T) { func TestServerReadUDPChangeConn(t *testing.T) {
s := &Server{ s := &Server{
Handler: &testServerHandler{ Handler: &testServerHandler{
onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, error) { onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, *uint32, error) {
return &base.Response{ return &base.Response{
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil, nil
}, },
onPlay: func(ctx *ServerHandlerOnPlayCtx) (*base.Response, error) { onPlay: func(ctx *ServerHandlerOnPlayCtx) (*base.Response, error) {
return &base.Response{ return &base.Response{

View File

@@ -44,7 +44,7 @@ type testServerHandler struct {
onSessionClose func(*ServerHandlerOnSessionCloseCtx) onSessionClose func(*ServerHandlerOnSessionCloseCtx)
onDescribe func(*ServerHandlerOnDescribeCtx) (*base.Response, []byte, error) onDescribe func(*ServerHandlerOnDescribeCtx) (*base.Response, []byte, error)
onAnnounce func(*ServerHandlerOnAnnounceCtx) (*base.Response, error) onAnnounce func(*ServerHandlerOnAnnounceCtx) (*base.Response, error)
onSetup func(*ServerHandlerOnSetupCtx) (*base.Response, error) onSetup func(*ServerHandlerOnSetupCtx) (*base.Response, *uint32, error)
onPlay func(*ServerHandlerOnPlayCtx) (*base.Response, error) onPlay func(*ServerHandlerOnPlayCtx) (*base.Response, error)
onRecord func(*ServerHandlerOnRecordCtx) (*base.Response, error) onRecord func(*ServerHandlerOnRecordCtx) (*base.Response, error)
onPause func(*ServerHandlerOnPauseCtx) (*base.Response, error) onPause func(*ServerHandlerOnPauseCtx) (*base.Response, error)
@@ -91,11 +91,11 @@ func (sh *testServerHandler) OnAnnounce(ctx *ServerHandlerOnAnnounceCtx) (*base.
return nil, fmt.Errorf("unimplemented") return nil, fmt.Errorf("unimplemented")
} }
func (sh *testServerHandler) OnSetup(ctx *ServerHandlerOnSetupCtx) (*base.Response, error) { func (sh *testServerHandler) OnSetup(ctx *ServerHandlerOnSetupCtx) (*base.Response, *uint32, error) {
if sh.onSetup != nil { if sh.onSetup != nil {
return sh.onSetup(ctx) return sh.onSetup(ctx)
} }
return nil, fmt.Errorf("unimplemented") return nil, nil, fmt.Errorf("unimplemented")
} }
func (sh *testServerHandler) OnPlay(ctx *ServerHandlerOnPlayCtx) (*base.Response, error) { func (sh *testServerHandler) OnPlay(ctx *ServerHandlerOnPlayCtx) (*base.Response, error) {
@@ -327,11 +327,11 @@ func TestServerHighLevelPublishRead(t *testing.T) {
}, },
}, nil }, nil
}, },
onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, error) { onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, *uint32, error) {
if ctx.Path != "teststream" { if ctx.Path != "teststream" {
return &base.Response{ return &base.Response{
StatusCode: base.StatusBadRequest, StatusCode: base.StatusBadRequest,
}, fmt.Errorf("invalid path (%s)", ctx.Req.URL) }, nil, fmt.Errorf("invalid path (%s)", ctx.Req.URL)
} }
return &base.Response{ return &base.Response{
@@ -339,7 +339,7 @@ func TestServerHighLevelPublishRead(t *testing.T) {
Header: base.Header{ Header: base.Header{
"Session": base.HeaderValue{"12345678"}, "Session": base.HeaderValue{"12345678"},
}, },
}, nil }, nil, nil
}, },
onPlay: func(ctx *ServerHandlerOnPlayCtx) (*base.Response, error) { onPlay: func(ctx *ServerHandlerOnPlayCtx) (*base.Response, error) {
if ctx.Path != "teststream" { if ctx.Path != "teststream" {
@@ -620,10 +620,10 @@ func TestServerErrorInvalidMethod(t *testing.T) {
func TestServerErrorTCPTwoConnOneSession(t *testing.T) { func TestServerErrorTCPTwoConnOneSession(t *testing.T) {
s := &Server{ s := &Server{
Handler: &testServerHandler{ Handler: &testServerHandler{
onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, error) { onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, *uint32, error) {
return &base.Response{ return &base.Response{
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil, nil
}, },
onPlay: func(ctx *ServerHandlerOnPlayCtx) (*base.Response, error) { onPlay: func(ctx *ServerHandlerOnPlayCtx) (*base.Response, error) {
return &base.Response{ return &base.Response{
@@ -712,10 +712,10 @@ func TestServerErrorTCPTwoConnOneSession(t *testing.T) {
func TestServerErrorTCPOneConnTwoSessions(t *testing.T) { func TestServerErrorTCPOneConnTwoSessions(t *testing.T) {
s := &Server{ s := &Server{
Handler: &testServerHandler{ Handler: &testServerHandler{
onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, error) { onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, *uint32, error) {
return &base.Response{ return &base.Response{
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil, nil
}, },
onPlay: func(ctx *ServerHandlerOnPlayCtx) (*base.Response, error) { onPlay: func(ctx *ServerHandlerOnPlayCtx) (*base.Response, error) {
return &base.Response{ return &base.Response{
@@ -920,10 +920,10 @@ func TestServerSessionClose(t *testing.T) {
onSessionClose: func(ctx *ServerHandlerOnSessionCloseCtx) { onSessionClose: func(ctx *ServerHandlerOnSessionCloseCtx) {
close(sessionClosed) close(sessionClosed)
}, },
onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, error) { onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, *uint32, error) {
return &base.Response{ return &base.Response{
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil, nil
}, },
}, },
} }
@@ -969,10 +969,10 @@ func TestServerSessionAutoClose(t *testing.T) {
onSessionClose: func(ctx *ServerHandlerOnSessionCloseCtx) { onSessionClose: func(ctx *ServerHandlerOnSessionCloseCtx) {
close(sessionClosed) close(sessionClosed)
}, },
onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, error) { onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, *uint32, error) {
return &base.Response{ return &base.Response{
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil, nil
}, },
}, },
} }
@@ -1036,10 +1036,10 @@ func TestServerErrorInvalidPath(t *testing.T) {
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil
}, },
onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, error) { onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, *uint32, error) {
return &base.Response{ return &base.Response{
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, nil }, nil, nil
}, },
onPlay: func(ctx *ServerHandlerOnPlayCtx) (*base.Response, error) { onPlay: func(ctx *ServerHandlerOnPlayCtx) (*base.Response, error) {
return &base.Response{ return &base.Response{

View File

@@ -103,7 +103,9 @@ type ServerHandlerOnSetupCtx struct {
// ServerHandlerOnSetup can be implemented by a ServerHandler. // ServerHandlerOnSetup can be implemented by a ServerHandler.
type ServerHandlerOnSetup interface { type ServerHandlerOnSetup interface {
OnSetup(*ServerHandlerOnSetupCtx) (*base.Response, error) // returns a Response and an optional SSRC that is
// inserted into the Transport header.
OnSetup(*ServerHandlerOnSetupCtx) (*base.Response, *uint32, error)
} }
// ServerHandlerOnPlayCtx is the context of a PLAY request. // ServerHandlerOnPlayCtx is the context of a PLAY request.

View File

@@ -503,21 +503,21 @@ func (ss *ServerSession) handleRequest(sc *ServerConn, req *base.Request) (*base
}, err }, err
} }
var th headers.Transport var inTH headers.Transport
err = th.Read(req.Header["Transport"]) err = inTH.Read(req.Header["Transport"])
if err != nil { if err != nil {
return &base.Response{ return &base.Response{
StatusCode: base.StatusBadRequest, StatusCode: base.StatusBadRequest,
}, liberrors.ErrServerTransportHeaderInvalid{Err: err} }, liberrors.ErrServerTransportHeaderInvalid{Err: err}
} }
if th.Delivery != nil && *th.Delivery == base.StreamDeliveryMulticast { if inTH.Delivery != nil && *inTH.Delivery == base.StreamDeliveryMulticast {
return &base.Response{ return &base.Response{
StatusCode: base.StatusUnsupportedTransport, StatusCode: base.StatusUnsupportedTransport,
}, nil }, nil
} }
trackID, path, query, err := setupGetTrackIDPathQuery(req.URL, th.Mode, trackID, path, query, err := setupGetTrackIDPathQuery(req.URL, inTH.Mode,
ss.announcedTracks, ss.setupPath, ss.setupQuery) ss.announcedTracks, ss.setupPath, ss.setupQuery)
if err != nil { if err != nil {
return &base.Response{ return &base.Response{
@@ -533,67 +533,67 @@ func (ss *ServerSession) handleRequest(sc *ServerConn, req *base.Request) (*base
switch ss.state { switch ss.state {
case ServerSessionStateInitial, ServerSessionStatePrePlay: // play case ServerSessionStateInitial, ServerSessionStatePrePlay: // play
if th.Mode != nil && *th.Mode != headers.TransportModePlay { if inTH.Mode != nil && *inTH.Mode != headers.TransportModePlay {
return &base.Response{ return &base.Response{
StatusCode: base.StatusBadRequest, StatusCode: base.StatusBadRequest,
}, liberrors.ErrServerTransportHeaderWrongMode{Mode: th.Mode} }, liberrors.ErrServerTransportHeaderWrongMode{Mode: inTH.Mode}
} }
default: // record default: // record
if th.Mode == nil || *th.Mode != headers.TransportModeRecord { if inTH.Mode == nil || *inTH.Mode != headers.TransportModeRecord {
return &base.Response{ return &base.Response{
StatusCode: base.StatusBadRequest, StatusCode: base.StatusBadRequest,
}, liberrors.ErrServerTransportHeaderWrongMode{Mode: th.Mode} }, liberrors.ErrServerTransportHeaderWrongMode{Mode: inTH.Mode}
} }
} }
if th.Protocol == StreamProtocolUDP { if inTH.Protocol == StreamProtocolUDP {
if ss.s.udpRTPListener == nil { if ss.s.udpRTPListener == nil {
return &base.Response{ return &base.Response{
StatusCode: base.StatusUnsupportedTransport, StatusCode: base.StatusUnsupportedTransport,
}, nil }, nil
} }
if th.ClientPorts == nil { if inTH.ClientPorts == nil {
return &base.Response{ return &base.Response{
StatusCode: base.StatusBadRequest, StatusCode: base.StatusBadRequest,
}, liberrors.ErrServerTransportHeaderNoClientPorts{} }, liberrors.ErrServerTransportHeaderNoClientPorts{}
} }
} else { } else {
if th.InterleavedIDs == nil { if inTH.InterleavedIDs == nil {
return &base.Response{ return &base.Response{
StatusCode: base.StatusBadRequest, StatusCode: base.StatusBadRequest,
}, liberrors.ErrServerTransportHeaderNoInterleavedIDs{} }, liberrors.ErrServerTransportHeaderNoInterleavedIDs{}
} }
if th.InterleavedIDs[0] != (trackID*2) || if inTH.InterleavedIDs[0] != (trackID*2) ||
th.InterleavedIDs[1] != (1+trackID*2) { inTH.InterleavedIDs[1] != (1+trackID*2) {
return &base.Response{ return &base.Response{
StatusCode: base.StatusBadRequest, StatusCode: base.StatusBadRequest,
}, liberrors.ErrServerTransportHeaderWrongInterleavedIDs{ }, liberrors.ErrServerTransportHeaderWrongInterleavedIDs{
Expected: [2]int{(trackID * 2), (1 + trackID*2)}, Value: *th.InterleavedIDs} Expected: [2]int{(trackID * 2), (1 + trackID*2)}, Value: *inTH.InterleavedIDs}
} }
} }
if ss.setupProtocol != nil && *ss.setupProtocol != th.Protocol { if ss.setupProtocol != nil && *ss.setupProtocol != inTH.Protocol {
return &base.Response{ return &base.Response{
StatusCode: base.StatusBadRequest, StatusCode: base.StatusBadRequest,
}, liberrors.ErrServerTracksDifferentProtocols{} }, liberrors.ErrServerTracksDifferentProtocols{}
} }
res, err := ss.s.Handler.(ServerHandlerOnSetup).OnSetup(&ServerHandlerOnSetupCtx{ res, ssrc, err := ss.s.Handler.(ServerHandlerOnSetup).OnSetup(&ServerHandlerOnSetupCtx{
Session: ss, Session: ss,
Conn: sc, Conn: sc,
Req: req, Req: req,
Path: path, Path: path,
Query: query, Query: query,
TrackID: trackID, TrackID: trackID,
Transport: &th, Transport: &inTH,
}) })
if res.StatusCode == base.StatusOK { if res.StatusCode == base.StatusOK {
ss.setupProtocol = &th.Protocol ss.setupProtocol = &inTH.Protocol
if ss.setuppedTracks == nil { if ss.setuppedTracks == nil {
ss.setuppedTracks = make(map[int]ServerSessionSetuppedTrack) ss.setuppedTracks = make(map[int]ServerSessionSetuppedTrack)
@@ -603,30 +603,35 @@ func (ss *ServerSession) handleRequest(sc *ServerConn, req *base.Request) (*base
res.Header = make(base.Header) res.Header = make(base.Header)
} }
if th.Protocol == StreamProtocolUDP { th := headers.Transport{
Delivery: func() *base.StreamDelivery {
v := base.StreamDeliveryUnicast
return &v
}(),
}
if inTH.Protocol == StreamProtocolUDP {
ss.setuppedTracks[trackID] = ServerSessionSetuppedTrack{ ss.setuppedTracks[trackID] = ServerSessionSetuppedTrack{
udpRTPPort: th.ClientPorts[0], udpRTPPort: inTH.ClientPorts[0],
udpRTCPPort: th.ClientPorts[1], udpRTCPPort: inTH.ClientPorts[1],
} }
res.Header["Transport"] = headers.Transport{ th.Protocol = StreamProtocolUDP
Protocol: StreamProtocolUDP, th.ClientPorts = inTH.ClientPorts
Delivery: func() *base.StreamDelivery { th.ServerPorts = &[2]int{sc.s.udpRTPListener.port(), sc.s.udpRTCPListener.port()}
v := base.StreamDeliveryUnicast
return &v
}(),
ClientPorts: th.ClientPorts,
ServerPorts: &[2]int{sc.s.udpRTPListener.port(), sc.s.udpRTCPListener.port()},
}.Write()
} else { } else {
ss.setuppedTracks[trackID] = ServerSessionSetuppedTrack{} ss.setuppedTracks[trackID] = ServerSessionSetuppedTrack{}
res.Header["Transport"] = headers.Transport{ th.Protocol = StreamProtocolTCP
Protocol: StreamProtocolTCP, th.InterleavedIDs = inTH.InterleavedIDs
InterleavedIDs: th.InterleavedIDs,
}.Write()
} }
if ssrc != nil {
th.SSRC = ssrc
}
res.Header["Transport"] = th.Write()
} }
if ss.state == ServerSessionStateInitial { if ss.state == ServerSessionStateInitial {