server: use absolute RTSP URL as control attribute (#210)

this is necessary in order to make GStreamer's rtspsrc to send query parameters correctly in SETUP requests.
This commit is contained in:
Alessandro Ros
2023-03-24 10:54:14 +01:00
committed by GitHub
parent d37f4139f3
commit 1ad059a80b
9 changed files with 164 additions and 86 deletions

View File

@@ -23,15 +23,15 @@ import (
"github.com/aler9/gortsplib/v2/pkg/format"
"github.com/aler9/gortsplib/v2/pkg/headers"
"github.com/aler9/gortsplib/v2/pkg/media"
"github.com/aler9/gortsplib/v2/pkg/sdp"
"github.com/aler9/gortsplib/v2/pkg/url"
)
func mustMarshalSDP(sdp *sdp.SessionDescription) []byte {
byts, err := sdp.Marshal()
func mustMarshalMedias(medias media.Medias) []byte {
byts, err := medias.Marshal(false).Marshal()
if err != nil {
panic(err)
}
return byts
}
@@ -148,7 +148,7 @@ func TestClientPlayFormats(t *testing.T) {
"Content-Type": base.HeaderValue{"application/sdp"},
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
},
Body: mustMarshalSDP(medias.Marshal(false)),
Body: mustMarshalMedias(medias),
})
require.NoError(t, err)
@@ -293,7 +293,7 @@ func TestClientPlay(t *testing.T) {
"Content-Type": base.HeaderValue{"application/sdp"},
"Content-Base": base.HeaderValue{scheme + "://" + listenIP + ":8554/test/stream?param=value/"},
},
Body: mustMarshalSDP(medias.Marshal(false)),
Body: mustMarshalMedias(medias),
})
require.NoError(t, err)
@@ -567,7 +567,7 @@ func TestClientPlayPartial(t *testing.T) {
"Content-Type": base.HeaderValue{"application/sdp"},
"Content-Base": base.HeaderValue{"rtsp://" + listenIP + ":8554/teststream/"},
},
Body: mustMarshalSDP(medias.Marshal(false)),
Body: mustMarshalMedias(medias),
})
require.NoError(t, err)
@@ -711,12 +711,12 @@ func TestClientPlayContentBase(t *testing.T) {
Header: base.Header{
"Content-Type": base.HeaderValue{"application/sdp"},
},
Body: mustMarshalSDP(medias.Marshal(false)),
Body: mustMarshalMedias(medias),
})
require.NoError(t, err)
case "inside control attribute":
body := string(mustMarshalSDP(medias.Marshal(false)))
body := string(mustMarshalMedias(medias))
body = strings.Replace(body, "t=0 0", "t=0 0\r\na=control:rtsp://localhost:8554/teststream", 1)
err = conn.WriteResponse(&base.Response{
@@ -840,7 +840,7 @@ func TestClientPlayAnyPort(t *testing.T) {
"Content-Type": base.HeaderValue{"application/sdp"},
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
},
Body: mustMarshalSDP(medias.Marshal(false)),
Body: mustMarshalMedias(medias),
})
require.NoError(t, err)
@@ -994,7 +994,7 @@ func TestClientPlayAutomaticProtocol(t *testing.T) {
"Content-Type": base.HeaderValue{"application/sdp"},
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
},
Body: mustMarshalSDP(medias.Marshal(false)),
Body: mustMarshalMedias(medias),
})
require.NoError(t, err)
@@ -1109,7 +1109,7 @@ func TestClientPlayAutomaticProtocol(t *testing.T) {
"Content-Type": base.HeaderValue{"application/sdp"},
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
},
Body: mustMarshalSDP(medias.Marshal(false)),
Body: mustMarshalMedias(medias),
})
require.NoError(t, err)
@@ -1178,7 +1178,7 @@ func TestClientPlayAutomaticProtocol(t *testing.T) {
"Content-Type": base.HeaderValue{"application/sdp"},
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
},
Body: mustMarshalSDP(medias.Marshal(false)),
Body: mustMarshalMedias(medias),
})
require.NoError(t, err)
@@ -1302,7 +1302,7 @@ func TestClientPlayAutomaticProtocol(t *testing.T) {
"Content-Type": base.HeaderValue{"application/sdp"},
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
},
Body: mustMarshalSDP(medias.Marshal(false)),
Body: mustMarshalMedias(medias),
})
require.NoError(t, err)
@@ -1384,7 +1384,7 @@ func TestClientPlayAutomaticProtocol(t *testing.T) {
"Content-Type": base.HeaderValue{"application/sdp"},
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
},
Body: mustMarshalSDP(medias.Marshal(false)),
Body: mustMarshalMedias(medias),
})
require.NoError(t, err)
@@ -1522,7 +1522,7 @@ func TestClientPlayDifferentInterleavedIDs(t *testing.T) {
"Content-Type": base.HeaderValue{"application/sdp"},
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
},
Body: mustMarshalSDP(medias.Marshal(false)),
Body: mustMarshalMedias(medias),
})
require.NoError(t, err)
@@ -1717,7 +1717,7 @@ func TestClientPlayRedirect(t *testing.T) {
"Content-Type": base.HeaderValue{"application/sdp"},
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
},
Body: mustMarshalSDP(medias.Marshal(false)),
Body: mustMarshalMedias(medias),
})
require.NoError(t, err)
@@ -1878,7 +1878,7 @@ func TestClientPlayPause(t *testing.T) {
"Content-Type": base.HeaderValue{"application/sdp"},
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
},
Body: mustMarshalSDP(medias.Marshal(false)),
Body: mustMarshalMedias(medias),
})
require.NoError(t, err)
@@ -2046,7 +2046,7 @@ func TestClientPlayRTCPReport(t *testing.T) {
"Content-Type": base.HeaderValue{"application/sdp"},
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
},
Body: mustMarshalSDP(medias.Marshal(false)),
Body: mustMarshalMedias(medias),
})
require.NoError(t, err)
@@ -2224,7 +2224,7 @@ func TestClientPlayErrorTimeout(t *testing.T) {
"Content-Type": base.HeaderValue{"application/sdp"},
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
},
Body: mustMarshalSDP(medias.Marshal(false)),
Body: mustMarshalMedias(medias),
})
require.NoError(t, err)
@@ -2370,7 +2370,7 @@ func TestClientPlayIgnoreTCPInvalidMedia(t *testing.T) {
"Content-Type": base.HeaderValue{"application/sdp"},
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
},
Body: mustMarshalSDP(medias.Marshal(false)),
Body: mustMarshalMedias(medias),
})
require.NoError(t, err)
@@ -2493,7 +2493,7 @@ func TestClientPlaySeek(t *testing.T) {
"Content-Type": base.HeaderValue{"application/sdp"},
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
},
Body: mustMarshalSDP(medias.Marshal(false)),
Body: mustMarshalMedias(medias),
})
require.NoError(t, err)
@@ -2657,7 +2657,7 @@ func TestClientPlayKeepaliveFromSession(t *testing.T) {
"Content-Type": base.HeaderValue{"application/sdp"},
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
},
Body: mustMarshalSDP(medias.Marshal(false)),
Body: mustMarshalMedias(medias),
})
require.NoError(t, err)
@@ -2780,7 +2780,7 @@ func TestClientPlayDifferentSource(t *testing.T) {
"Content-Type": base.HeaderValue{"application/sdp"},
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/test/stream?param=value/"},
},
Body: mustMarshalSDP(medias.Marshal(false)),
Body: mustMarshalMedias(medias),
})
require.NoError(t, err)
@@ -2933,7 +2933,7 @@ func TestClientPlayDecodeErrors(t *testing.T) {
"Content-Type": base.HeaderValue{"application/sdp"},
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/stream/"},
},
Body: mustMarshalSDP(medias.Marshal(false)),
Body: mustMarshalMedias(medias),
})
require.NoError(t, err)

View File

@@ -170,7 +170,7 @@ func TestClientRecordSerial(t *testing.T) {
require.NoError(t, err)
require.Equal(t, base.Setup, req.Method)
require.Equal(t, mustParseURL(
scheme+"://localhost:8554/teststream/"+controlAttribute(desc.MediaDescriptions[0])), req.URL)
scheme+"://localhost:8554/teststream/"+relativeControlAttribute(desc.MediaDescriptions[0])), req.URL)
var inTH headers.Transport
err = inTH.Unmarshal(req.Header["Transport"])

View File

@@ -114,7 +114,7 @@ func TestClientSession(t *testing.T) {
"Content-Type": base.HeaderValue{"application/sdp"},
"Session": base.HeaderValue{"123456"},
},
Body: mustMarshalSDP(medias.Marshal(false)),
Body: mustMarshalMedias(medias),
})
require.NoError(t, err)
}()
@@ -190,7 +190,7 @@ func TestClientAuth(t *testing.T) {
Header: base.Header{
"Content-Type": base.HeaderValue{"application/sdp"},
},
Body: mustMarshalSDP(medias.Marshal(false)),
Body: mustMarshalMedias(medias),
})
require.NoError(t, err)
}()
@@ -250,7 +250,7 @@ func TestClientDescribeCharset(t *testing.T) {
"Content-Type": base.HeaderValue{"application/sdp; charset=utf-8"},
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
},
Body: mustMarshalSDP(medias.Marshal(false)),
Body: mustMarshalMedias(medias),
})
require.NoError(t, err)
}()

View File

@@ -155,7 +155,7 @@ func (m Media) Marshal() *psdp.MediaDescription {
return md
}
// URL returns the media URL.
// URL returns the absolute URL of the media.
func (m Media) URL(contentBase *url.URL) (*url.URL, error) {
if contentBase == nil {
return nil, fmt.Errorf("Content-Base header not provided")

View File

@@ -16,7 +16,7 @@ var casesMedias = []struct {
medias Medias
}{
{
"one track for each media",
"one format for each media, absolute",
"v=0\r\n" +
"o=- 0 0 IN IP4 10.0.0.131\r\n" +
"s=Media Presentation\r\n" +
@@ -84,7 +84,74 @@ var casesMedias = []struct {
},
},
{
"multiple tracks for each media",
"one format for each media, relative",
"v=0\r\n" +
"o=- 0 0 IN IP4 10.0.0.131\r\n" +
"s=Media Presentation\r\n" +
"i=samsung\r\n" +
"c=IN IP4 0.0.0.0\r\n" +
"b=AS:2632\r\n" +
"t=0 0\r\n" +
"a=range:npt=now-\r\n" +
"m=video 42504 RTP/AVP 97\r\n" +
"b=AS:2560\r\n" +
"a=rtpmap:97 H264/90000\r\n" +
"a=control:trackID=1\r\n" +
"a=cliprect:0,0,1080,1920\r\n" +
"a=framesize:97 1920-1080\r\n" +
"a=framerate:30.0\r\n" +
"a=fmtp:97 packetization-mode=1;profile-level-id=640028;sprop-parameter-sets=Z2QAKKy0A8ARPyo=,aO4Bniw=\r\n" +
"m=audio 42506 RTP/AVP 0\r\n" +
"b=AS:64\r\n" +
"a=rtpmap:0 PCMU/8000\r\n" +
"a=control:trackID=2\r\n" +
"a=recvonly\r\n" +
"m=application 42508 RTP/AVP 107\r\n" +
"b=AS:8\r\n",
"v=0\r\n" +
"o=- 0 0 IN IP4 127.0.0.1\r\n" +
"s=Stream\r\n" +
"c=IN IP4 0.0.0.0\r\n" +
"t=0 0\r\n" +
"m=video 0 RTP/AVP 97\r\n" +
"a=control:trackID=1\r\n" +
"a=rtpmap:97 H264/90000\r\n" +
"a=fmtp:97 packetization-mode=1; profile-level-id=640028; sprop-parameter-sets=Z2QAKKy0A8ARPyo=,aO4Bniw=\r\n" +
"m=audio 0 RTP/AVP 0\r\n" +
"a=control:trackID=2\r\n" +
"a=recvonly\r\n" +
"a=rtpmap:0 PCMU/8000\r\n" +
"m=application 0 RTP/AVP 107\r\n" +
"a=control\r\n",
Medias{
{
Type: "video",
Control: "trackID=1",
Formats: []format.Format{&format.H264{
PayloadTyp: 97,
PacketizationMode: 1,
SPS: []byte{0x67, 0x64, 0x00, 0x28, 0xac, 0xb4, 0x03, 0xc0, 0x11, 0x3f, 0x2a},
PPS: []byte{0x68, 0xee, 0x01, 0x9e, 0x2c},
}},
},
{
Type: "audio",
Direction: DirectionRecvonly,
Control: "trackID=2",
Formats: []format.Format{&format.G711{
MULaw: true,
}},
},
{
Type: "application",
Formats: []format.Format{&format.Generic{
PayloadTyp: 107,
}},
},
},
},
{
"multiple formats for each media",
"v=0\r\n" +
"o=- 4158123474391860926 2 IN IP4 127.0.0.1\r\n" +
"s=-\r\n" +
@@ -353,7 +420,7 @@ var casesMedias = []struct {
},
},
{
"multiple tracks for each media 2",
"multiple formats for each media 2",
"v=0\r\n" +
"o=- 4158123474391860926 2 IN IP4 127.0.0.1\r\n" +
"s=-\r\n" +
@@ -417,17 +484,14 @@ var casesMedias = []struct {
"c=IN IP4 0.0.0.0\r\n" +
"t=0 0\r\n" +
"m=video 0 RTP/AVP 26\r\n" +
"a=control:rtsp://192.168.0.1/video\r\n" +
"a=recvonly\r\n" +
"a=rtpmap:26 JPEG/90000\r\n" +
"m=audio 0 RTP/AVP 0\r\n" +
"a=control:rtsp://192.168.0.1/audio\r\n" +
"a=recvonly\r\n" +
"a=rtpmap:0 PCMU/8000\r\n" +
"m=audio 0 RTP/AVP 0\r\n" +
"a=control:rtsp://192.168.0.1/audioback\r\n" +
"a=sendonly\r\n" +
"a=rtpmap:0 PCMU/8000\r\n",
@@ -507,8 +571,7 @@ func TestMediasReadErrors(t *testing.T) {
func TestMediasMarshal(t *testing.T) {
for _, ca := range casesMedias {
t.Run(ca.name, func(t *testing.T) {
sdp := ca.medias.Marshal(false)
byts, err := sdp.Marshal()
byts, err := ca.medias.Marshal(false).Marshal()
require.NoError(t, err)
require.Equal(t, ca.out, string(byts))
})

View File

@@ -25,15 +25,27 @@ func getSessionID(header base.Header) string {
return ""
}
func filterMedias(medias media.Medias, streamMedias map[*media.Media]*serverStreamMedia) media.Medias {
func mediasForSDP(
medias media.Medias,
streamMedias map[*media.Media]*serverStreamMedia,
contentBase *url.URL,
) media.Medias {
copy := make(media.Medias, len(medias))
for i, medi := range medias {
copy[i] = &media.Media{
mc := &media.Media{
Type: medi.Type,
// Direction: skipped for the moment
Formats: medi.Formats,
Control: "mediaUUID=" + streamMedias[medi].uuid.String(),
}
// always use the absolute URL of the track as control attribute, in order
// to support GStreamer's rtspsrc. When a relative control is used, GStreamer
// puts it between path and query, instead of appending it to the URL.
u, _ := mc.URL(contentBase)
mc.Control = u.String()
copy[i] = mc
}
return copy
}
@@ -392,7 +404,7 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) {
}
if stream != nil {
byts, _ := filterMedias(stream.medias, stream.streamMedias).Marshal(multicast).Marshal()
byts, _ := mediasForSDP(stream.medias, stream.streamMedias, req.URL).Marshal(multicast).Marshal()
res.Body = byts
}
}

View File

@@ -52,7 +52,13 @@ func multicastCapableIP(t *testing.T) string {
return ""
}
func controlAttribute(md *psdp.MediaDescription) string {
func relativeControlAttribute(md *psdp.MediaDescription) string {
v, _ := md.Attribute("control")
i := strings.Index(v, "mediaUUID=")
return v[i:]
}
func absoluteControlAttribute(md *psdp.MediaDescription) string {
v, _ := md.Attribute("control")
return v
}
@@ -60,7 +66,7 @@ func controlAttribute(md *psdp.MediaDescription) string {
func doDescribe(conn *conn.Conn) (*sdp.SessionDescription, error) {
res, err := writeReqReadRes(conn, base.Request{
Method: base.Describe,
URL: mustParseURL("rtsp://localhost:8554/pa"),
URL: mustParseURL("rtsp://localhost:8554/teststream"),
Header: base.Header{
"CSeq": base.HeaderValue{"1"},
},
@@ -198,11 +204,10 @@ func TestServerPlayPath(t *testing.T) {
InterleavedIDs: &[2]int{0, 1},
}
v, _ := desc.MediaDescriptions[1].Attribute("control")
res, err := writeReqReadRes(conn, base.Request{
Method: base.Setup,
URL: mustParseURL(strings.ReplaceAll(ca.setupURL, "[control]", "/"+v)),
URL: mustParseURL(strings.ReplaceAll(ca.setupURL, "[control]", "/"+
relativeControlAttribute(desc.MediaDescriptions[1]))),
Header: base.Header{
"CSeq": base.HeaderValue{"2"},
"Transport": th.Marshal(),
@@ -301,7 +306,7 @@ func TestServerPlaySetupErrors(t *testing.T) {
res, err := writeReqReadRes(conn, base.Request{
Method: base.Setup,
URL: mustParseURL("rtsp://localhost:8554/teststream/" + controlAttribute(desc.MediaDescriptions[0])),
URL: mustParseURL(absoluteControlAttribute(desc.MediaDescriptions[0])),
Header: base.Header{
"CSeq": base.HeaderValue{"2"},
"Transport": th.Marshal(),
@@ -320,7 +325,7 @@ func TestServerPlaySetupErrors(t *testing.T) {
res, err = writeReqReadRes(conn, base.Request{
Method: base.Setup,
URL: mustParseURL("rtsp://localhost:8554/test12stream/" + controlAttribute(desc.MediaDescriptions[0])),
URL: mustParseURL("rtsp://localhost:8554/test12stream/" + relativeControlAttribute(desc.MediaDescriptions[0])),
Header: base.Header{
"CSeq": base.HeaderValue{"3"},
"Transport": th.Marshal(),
@@ -341,7 +346,7 @@ func TestServerPlaySetupErrors(t *testing.T) {
res, err = writeReqReadRes(conn, base.Request{
Method: base.Setup,
URL: mustParseURL("rtsp://localhost:8554/teststream/" + controlAttribute(desc.MediaDescriptions[0])),
URL: mustParseURL(absoluteControlAttribute(desc.MediaDescriptions[0])),
Header: base.Header{
"CSeq": base.HeaderValue{"4"},
"Transport": th.Marshal(),
@@ -425,7 +430,7 @@ func TestServerPlaySetupErrorSameUDPPortsAndIP(t *testing.T) {
res, err := writeReqReadRes(conn, base.Request{
Method: base.Setup,
URL: mustParseURL("rtsp://localhost:8554/teststream/" + controlAttribute(desc.MediaDescriptions[0])),
URL: mustParseURL(absoluteControlAttribute(desc.MediaDescriptions[0])),
Header: base.Header{
"CSeq": base.HeaderValue{"2"},
"Transport": inTH.Marshal(),
@@ -592,7 +597,7 @@ func TestServerPlay(t *testing.T) {
res, err := writeReqReadRes(conn, base.Request{
Method: base.Setup,
URL: mustParseURL("rtsp://" + listenIP + ":8554/teststream/" + controlAttribute(desc.MediaDescriptions[0])),
URL: mustParseURL(absoluteControlAttribute(desc.MediaDescriptions[0])),
Header: base.Header{
"CSeq": base.HeaderValue{"2"},
"Transport": inTH.Marshal(),
@@ -886,7 +891,7 @@ func TestServerPlayDecodeErrors(t *testing.T) {
res, err := writeReqReadRes(conn, base.Request{
Method: base.Setup,
URL: mustParseURL("rtsp://localhost:8554/teststream/" + controlAttribute(desc.MediaDescriptions[0])),
URL: mustParseURL(absoluteControlAttribute(desc.MediaDescriptions[0])),
Header: base.Header{
"CSeq": base.HeaderValue{"2"},
"Transport": inTH.Marshal(),
@@ -1023,7 +1028,7 @@ func TestServerPlayRTCPReport(t *testing.T) {
res, err := writeReqReadRes(conn, base.Request{
Method: base.Setup,
URL: mustParseURL("rtsp://localhost:8554/teststream/" + controlAttribute(desc.MediaDescriptions[0])),
URL: mustParseURL(absoluteControlAttribute(desc.MediaDescriptions[0])),
Header: base.Header{
"CSeq": base.HeaderValue{"2"},
"Transport": inTH.Marshal(),
@@ -1226,7 +1231,7 @@ func TestServerPlayTCPResponseBeforeFrames(t *testing.T) {
res, err := writeReqReadRes(conn, base.Request{
Method: base.Setup,
URL: mustParseURL("rtsp://localhost:8554/teststream/" + controlAttribute(desc.MediaDescriptions[0])),
URL: mustParseURL(absoluteControlAttribute(desc.MediaDescriptions[0])),
Header: base.Header{
"CSeq": base.HeaderValue{"2"},
"Transport": headers.Transport{
@@ -1306,7 +1311,7 @@ func TestServerPlayPlayPlay(t *testing.T) {
res, err := writeReqReadRes(conn, base.Request{
Method: base.Setup,
URL: mustParseURL("rtsp://localhost:8554/teststream/" + controlAttribute(desc.MediaDescriptions[0])),
URL: mustParseURL(absoluteControlAttribute(desc.MediaDescriptions[0])),
Header: base.Header{
"CSeq": base.HeaderValue{"2"},
"Transport": headers.Transport{
@@ -1424,7 +1429,7 @@ func TestServerPlayPlayPausePlay(t *testing.T) {
res, err := writeReqReadRes(conn, base.Request{
Method: base.Setup,
URL: mustParseURL("rtsp://localhost:8554/teststream/" + controlAttribute(desc.MediaDescriptions[0])),
URL: mustParseURL(absoluteControlAttribute(desc.MediaDescriptions[0])),
Header: base.Header{
"CSeq": base.HeaderValue{"2"},
"Transport": headers.Transport{
@@ -1549,7 +1554,7 @@ func TestServerPlayPlayPausePause(t *testing.T) {
res, err := writeReqReadRes(conn, base.Request{
Method: base.Setup,
URL: mustParseURL("rtsp://localhost:8554/teststream/" + controlAttribute(desc.MediaDescriptions[0])),
URL: mustParseURL(absoluteControlAttribute(desc.MediaDescriptions[0])),
Header: base.Header{
"CSeq": base.HeaderValue{"2"},
"Transport": headers.Transport{
@@ -1697,7 +1702,7 @@ func TestServerPlayTimeout(t *testing.T) {
res, err := writeReqReadRes(conn, base.Request{
Method: base.Setup,
URL: mustParseURL("rtsp://localhost:8554/teststream/" + controlAttribute(desc.MediaDescriptions[0])),
URL: mustParseURL(absoluteControlAttribute(desc.MediaDescriptions[0])),
Header: base.Header{
"CSeq": base.HeaderValue{"2"},
"Transport": inTH.Marshal(),
@@ -1805,7 +1810,7 @@ func TestServerPlayWithoutTeardown(t *testing.T) {
res, err := writeReqReadRes(conn, base.Request{
Method: base.Setup,
URL: mustParseURL("rtsp://localhost:8554/teststream/" + controlAttribute(desc.MediaDescriptions[0])),
URL: mustParseURL(absoluteControlAttribute(desc.MediaDescriptions[0])),
Header: base.Header{
"CSeq": base.HeaderValue{"2"},
"Transport": inTH.Marshal(),
@@ -1899,7 +1904,7 @@ func TestServerPlayUDPChangeConn(t *testing.T) {
res, err := writeReqReadRes(conn, base.Request{
Method: base.Setup,
URL: mustParseURL("rtsp://localhost:8554/teststream/" + controlAttribute(desc.MediaDescriptions[0])),
URL: mustParseURL(absoluteControlAttribute(desc.MediaDescriptions[0])),
Header: base.Header{
"CSeq": base.HeaderValue{"2"},
"Transport": inTH.Marshal(),
@@ -2003,7 +2008,7 @@ func TestServerPlayPartialMedias(t *testing.T) {
res, err := writeReqReadRes(conn, base.Request{
Method: base.Setup,
URL: mustParseURL("rtsp://localhost:8554/teststream/" + controlAttribute(desc.MediaDescriptions[1])),
URL: mustParseURL(absoluteControlAttribute(desc.MediaDescriptions[1])),
Header: base.Header{
"CSeq": base.HeaderValue{"2"},
"Transport": inTH.Marshal(),
@@ -2058,7 +2063,7 @@ func TestServerPlayAdditionalInfos(t *testing.T) {
res, err := writeReqReadRes(conn, base.Request{
Method: base.Setup,
URL: mustParseURL("rtsp://localhost:8554/teststream/" + controlAttribute(desc.MediaDescriptions[0])),
URL: mustParseURL(absoluteControlAttribute(desc.MediaDescriptions[0])),
Header: base.Header{
"CSeq": base.HeaderValue{"2"},
"Transport": inTH.Marshal(),
@@ -2092,7 +2097,7 @@ func TestServerPlayAdditionalInfos(t *testing.T) {
res, err = writeReqReadRes(conn, base.Request{
Method: base.Setup,
URL: mustParseURL("rtsp://localhost:8554/teststream/" + controlAttribute(desc.MediaDescriptions[1])),
URL: mustParseURL(absoluteControlAttribute(desc.MediaDescriptions[1])),
Header: base.Header{
"CSeq": base.HeaderValue{"3"},
"Transport": inTH.Marshal(),

View File

@@ -246,9 +246,7 @@ func TestServerRecordPath(t *testing.T) {
TimeDescriptions: []psdp.TimeDescription{
{Timing: psdp.Timing{0, 0}}, //nolint:govet
},
MediaDescriptions: []*psdp.MediaDescription{
media.Marshal(),
},
MediaDescriptions: []*psdp.MediaDescription{media.Marshal()},
}
byts, _ := sout.Marshal()
@@ -348,7 +346,7 @@ func TestServerRecordErrorSetupMediaTwice(t *testing.T) {
"CSeq": base.HeaderValue{"1"},
"Content-Type": base.HeaderValue{"application/sdp"},
},
Body: mustMarshalSDP(medias.Marshal(false)),
Body: mustMarshalMedias(medias),
})
require.NoError(t, err)
require.Equal(t, base.StatusOK, res.StatusCode)
@@ -468,7 +466,7 @@ func TestServerRecordErrorRecordPartialMedias(t *testing.T) {
"CSeq": base.HeaderValue{"1"},
"Content-Type": base.HeaderValue{"application/sdp"},
},
Body: mustMarshalSDP(medias.Marshal(false)),
Body: mustMarshalMedias(medias),
})
require.NoError(t, err)
require.Equal(t, base.StatusOK, res.StatusCode)
@@ -641,7 +639,7 @@ func TestServerRecord(t *testing.T) {
"CSeq": base.HeaderValue{"1"},
"Content-Type": base.HeaderValue{"application/sdp"},
},
Body: mustMarshalSDP(medias.Marshal(false)),
Body: mustMarshalMedias(medias),
})
require.NoError(t, err)
require.Equal(t, base.StatusOK, res.StatusCode)
@@ -845,7 +843,7 @@ func TestServerRecordErrorInvalidProtocol(t *testing.T) {
"CSeq": base.HeaderValue{"1"},
"Content-Type": base.HeaderValue{"application/sdp"},
},
Body: mustMarshalSDP(medias.Marshal(false)),
Body: mustMarshalMedias(medias),
})
require.NoError(t, err)
require.Equal(t, base.StatusOK, res.StatusCode)
@@ -946,7 +944,7 @@ func TestServerRecordRTCPReport(t *testing.T) {
"CSeq": base.HeaderValue{"1"},
"Content-Type": base.HeaderValue{"application/sdp"},
},
Body: mustMarshalSDP(medias.Marshal(false)),
Body: mustMarshalMedias(medias),
})
require.NoError(t, err)
require.Equal(t, base.StatusOK, res.StatusCode)
@@ -1121,7 +1119,7 @@ func TestServerRecordTimeout(t *testing.T) {
"CSeq": base.HeaderValue{"1"},
"Content-Type": base.HeaderValue{"application/sdp"},
},
Body: mustMarshalSDP(medias.Marshal(false)),
Body: mustMarshalMedias(medias),
})
require.NoError(t, err)
require.Equal(t, base.StatusOK, res.StatusCode)
@@ -1244,7 +1242,7 @@ func TestServerRecordWithoutTeardown(t *testing.T) {
"CSeq": base.HeaderValue{"1"},
"Content-Type": base.HeaderValue{"application/sdp"},
},
Body: mustMarshalSDP(medias.Marshal(false)),
Body: mustMarshalMedias(medias),
})
require.NoError(t, err)
require.Equal(t, base.StatusOK, res.StatusCode)
@@ -1357,7 +1355,7 @@ func TestServerRecordUDPChangeConn(t *testing.T) {
"CSeq": base.HeaderValue{"1"},
"Content-Type": base.HeaderValue{"application/sdp"},
},
Body: mustMarshalSDP(medias.Marshal(false)),
Body: mustMarshalMedias(medias),
})
require.NoError(t, err)
require.Equal(t, base.StatusOK, res.StatusCode)
@@ -1512,7 +1510,7 @@ func TestServerRecordDecodeErrors(t *testing.T) {
"CSeq": base.HeaderValue{"1"},
"Content-Type": base.HeaderValue{"application/sdp"},
},
Body: mustMarshalSDP(medias.Marshal(false)),
Body: mustMarshalMedias(medias),
})
require.NoError(t, err)
require.Equal(t, base.StatusOK, res.StatusCode)

View File

@@ -359,7 +359,7 @@ func TestServerErrorMethodNotImplemented(t *testing.T) {
if ca == "inside session" {
res, err := writeReqReadRes(conn, base.Request{
Method: base.Setup,
URL: mustParseURL("rtsp://localhost:8554/teststream/" + controlAttribute(desc.MediaDescriptions[0])),
URL: mustParseURL(absoluteControlAttribute(desc.MediaDescriptions[0])),
Header: base.Header{
"CSeq": base.HeaderValue{"1"},
"Transport": headers.Transport{
@@ -391,7 +391,7 @@ func TestServerErrorMethodNotImplemented(t *testing.T) {
res, err := writeReqReadRes(conn, base.Request{
Method: base.SetParameter,
URL: mustParseURL("rtsp://localhost:8554/teststream/" + controlAttribute(desc.MediaDescriptions[0])),
URL: mustParseURL(absoluteControlAttribute(desc.MediaDescriptions[0])),
Header: headers,
})
require.NoError(t, err)
@@ -459,7 +459,7 @@ func TestServerErrorTCPTwoConnOneSession(t *testing.T) {
res, err := writeReqReadRes(conn1, base.Request{
Method: base.Setup,
URL: mustParseURL("rtsp://localhost:8554/teststream/" + controlAttribute(desc1.MediaDescriptions[0])),
URL: mustParseURL(absoluteControlAttribute(desc1.MediaDescriptions[0])),
Header: base.Header{
"CSeq": base.HeaderValue{"1"},
"Transport": headers.Transport{
@@ -504,7 +504,7 @@ func TestServerErrorTCPTwoConnOneSession(t *testing.T) {
res, err = writeReqReadRes(conn2, base.Request{
Method: base.Setup,
URL: mustParseURL("rtsp://localhost:8554/teststream/" + controlAttribute(desc2.MediaDescriptions[0])),
URL: mustParseURL(absoluteControlAttribute(desc2.MediaDescriptions[0])),
Header: base.Header{
"CSeq": base.HeaderValue{"1"},
"Transport": headers.Transport{
@@ -570,7 +570,7 @@ func TestServerErrorTCPOneConnTwoSessions(t *testing.T) {
res, err := writeReqReadRes(conn, base.Request{
Method: base.Setup,
URL: mustParseURL("rtsp://localhost:8554/teststream/" + controlAttribute(desc.MediaDescriptions[0])),
URL: mustParseURL(absoluteControlAttribute(desc.MediaDescriptions[0])),
Header: base.Header{
"CSeq": base.HeaderValue{"1"},
"Transport": headers.Transport{
@@ -607,7 +607,7 @@ func TestServerErrorTCPOneConnTwoSessions(t *testing.T) {
res, err = writeReqReadRes(conn, base.Request{
Method: base.Setup,
URL: mustParseURL("rtsp://localhost:8554/teststream/" + controlAttribute(desc.MediaDescriptions[0])),
URL: mustParseURL(absoluteControlAttribute(desc.MediaDescriptions[0])),
Header: base.Header{
"CSeq": base.HeaderValue{"3"},
"Transport": headers.Transport{
@@ -689,7 +689,7 @@ func TestServerSetupMultipleTransports(t *testing.T) {
res, err := writeReqReadRes(conn, base.Request{
Method: base.Setup,
URL: mustParseURL("rtsp://localhost:8554/teststream/" + controlAttribute(desc.MediaDescriptions[0])),
URL: mustParseURL(absoluteControlAttribute(desc.MediaDescriptions[0])),
Header: base.Header{
"CSeq": base.HeaderValue{"1"},
"Transport": inTHS.Marshal(),
@@ -776,7 +776,7 @@ func TestServerGetSetParameter(t *testing.T) {
if ca == "inside session" {
res, err := writeReqReadRes(conn, base.Request{
Method: base.Setup,
URL: mustParseURL("rtsp://localhost:8554/teststream/" + controlAttribute(desc.MediaDescriptions[0])),
URL: mustParseURL(absoluteControlAttribute(desc.MediaDescriptions[0])),
Header: base.Header{
"CSeq": base.HeaderValue{"2"},
"Transport": headers.Transport{
@@ -927,7 +927,7 @@ func TestServerSessionClose(t *testing.T) {
res, err := writeReqReadRes(conn, base.Request{
Method: base.Setup,
URL: mustParseURL("rtsp://localhost:8554/teststream/" + controlAttribute(desc.MediaDescriptions[0])),
URL: mustParseURL(absoluteControlAttribute(desc.MediaDescriptions[0])),
Header: base.Header{
"CSeq": base.HeaderValue{"1"},
"Transport": headers.Transport{
@@ -1008,7 +1008,7 @@ func TestServerSessionAutoClose(t *testing.T) {
_, err = writeReqReadRes(conn, base.Request{
Method: base.Setup,
URL: mustParseURL("rtsp://localhost:8554/teststream/" + controlAttribute(desc.MediaDescriptions[0])),
URL: mustParseURL(absoluteControlAttribute(desc.MediaDescriptions[0])),
Header: base.Header{
"CSeq": base.HeaderValue{"1"},
"Transport": headers.Transport{
@@ -1068,7 +1068,7 @@ func TestServerSessionTeardown(t *testing.T) {
res, err := writeReqReadRes(conn, base.Request{
Method: base.Setup,
URL: mustParseURL("rtsp://localhost:8554/teststream/" + controlAttribute(desc.MediaDescriptions[0])),
URL: mustParseURL(absoluteControlAttribute(desc.MediaDescriptions[0])),
Header: base.Header{
"CSeq": base.HeaderValue{"1"},
"Transport": headers.Transport{
@@ -1156,7 +1156,7 @@ func TestServerAuth(t *testing.T) {
"CSeq": base.HeaderValue{"1"},
"Content-Type": base.HeaderValue{"application/sdp"},
},
Body: mustMarshalSDP(medias.Marshal(false)),
Body: mustMarshalMedias(medias),
}
res, err := writeReqReadRes(conn, req)