From d162df21ecc72e679f8b2014abf7424bac3d03d6 Mon Sep 17 00:00:00 2001 From: Yuriy Gabuev Date: Thu, 17 Apr 2025 12:43:01 +0200 Subject: [PATCH] Allow setting response body in OnDescribe (#758) * Allow setting response body in OnDescribe Since commit 8c6495c33b3194f1bf34f3f8a87f51907e567915, the server can no longer directly specify the response body to DESCRIBE requests. This is a breaking change and is a limitation for users who manually handle their SDPs. This commit allows setting the body explicitly and takes it into account if the `ServerStream` part of the `OnDecsribe` return value is nil. If neither the stream, nor the body are set, the application panics. * Add test for non-nil body for Describe --- server_conn.go | 8 ++++++-- server_test.go | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/server_conn.go b/server_conn.go index 38a8ed54..50f24d85 100644 --- a/server_conn.go +++ b/server_conn.go @@ -328,8 +328,8 @@ func (sc *ServerConn) handleRequestInner(req *base.Request) (*base.Response, err }) if res.StatusCode == base.StatusOK { - if stream == nil { - panic("stream cannot be nil when StatusCode is StatusOK") + if stream == nil && len(res.Body) == 0 { + panic("stream should be not nil or response body should be nonempty when StatusCode is StatusOK") } if res.Header == nil { @@ -339,6 +339,10 @@ func (sc *ServerConn) handleRequestInner(req *base.Request) (*base.Response, err res.Header["Content-Base"] = base.HeaderValue{req.URL.String() + "/"} res.Header["Content-Type"] = base.HeaderValue{"application/sdp"} + if stream == nil { + return res, err + } + // VLC uses multicast if the SDP contains a multicast address. // therefore, we introduce a special query (vlcmulticast) that allows // to return a SDP that contains a multicast address. diff --git a/server_test.go b/server_test.go index 4a5af334..f02ac861 100644 --- a/server_test.go +++ b/server_test.go @@ -354,6 +354,41 @@ func TestServerErrorNilURL(t *testing.T) { <-nconnClosed } +func TestServerDescribeNonNilBody(t *testing.T) { + sdpBody := []byte("foo-sdp") + + s := &Server{ + Handler: &testServerHandler{ + onDescribe: func(_ *ServerHandlerOnDescribeCtx) (*base.Response, *ServerStream, error) { + return &base.Response{ + StatusCode: base.StatusOK, + Body: sdpBody, + }, nil, nil + }, + }, + RTSPAddress: "localhost:8554", + } + err := s.Start() + require.NoError(t, err) + defer s.Close() + + nconn, err := net.Dial("tcp", "localhost:8554") + require.NoError(t, err) + defer nconn.Close() + conn := conn.NewConn(nconn) + + res, err := writeReqReadRes(conn, base.Request{ + Method: base.Describe, + URL: mustParseURL("rtsp://localhost:8554/"), + Header: base.Header{ + "CSeq": base.HeaderValue{"1"}, + }, + }) + require.NoError(t, err) + require.Equal(t, base.StatusOK, res.StatusCode) + require.Equal(t, sdpBody, res.Body) +} + type testServerErrMethodNotImplemented struct { stream *ServerStream }