From c1b10a80bec074dd1a0327ec01286aa3aeeb7064 Mon Sep 17 00:00:00 2001 From: aler9 <46489434+aler9@users.noreply.github.com> Date: Wed, 11 May 2022 14:52:20 +0200 Subject: [PATCH] allow writing primitives to static buffers --- client.go | 18 +- client_publish_test.go | 295 +++++------- client_read_test.go | 750 +++++++++++++----------------- client_test.go | 53 +-- pkg/base/body.go | 19 +- pkg/base/body_test.go | 10 +- pkg/base/header.go | 43 +- pkg/base/header_test.go | 5 +- pkg/base/interleavedframe.go | 36 +- pkg/base/interleavedframe_test.go | 6 +- pkg/base/request.go | 50 +- pkg/base/request_test.go | 6 +- pkg/base/response.go | 57 ++- pkg/base/response_test.go | 12 +- server_publish_test.go | 32 +- server_read_test.go | 24 +- server_test.go | 13 +- serverconn.go | 6 +- serversession.go | 13 +- 19 files changed, 662 insertions(+), 786 deletions(-) diff --git a/client.go b/client.go index 576e8d5e..2b24c17b 100644 --- a/client.go +++ b/client.go @@ -9,7 +9,6 @@ package gortsplib import ( "bufio" - "bytes" "context" "crypto/tls" "fmt" @@ -1059,11 +1058,10 @@ func (c *Client) do(req *base.Request, skipResponse bool, allowFrames bool) (*ba c.OnRequest(req) } - var buf bytes.Buffer - req.Write(&buf) + byts, _ := req.Write() c.conn.SetWriteDeadline(time.Now().Add(c.WriteTimeout)) - _, err := c.conn.Write(buf.Bytes()) + _, err := c.conn.Write(byts) if err != nil { return nil, err } @@ -1877,25 +1875,23 @@ func (c *Client) runWriter() { rtcpFrames[trackID] = &base.InterleavedFrame{Channel: cct.tcpChannel + 1} } - var buf bytes.Buffer + buf := make([]byte, maxPacketSize+4) writeFunc = func(trackID int, isRTP bool, payload []byte) { if isRTP { f := rtpFrames[trackID] f.Payload = payload - buf.Reset() - f.Write(&buf) + n, _ := f.WriteTo(buf) c.conn.SetWriteDeadline(time.Now().Add(c.WriteTimeout)) - c.conn.Write(buf.Bytes()) + c.conn.Write(buf[:n]) } else { f := rtcpFrames[trackID] f.Payload = payload - buf.Reset() - f.Write(&buf) + n, _ := f.WriteTo(buf) c.conn.SetWriteDeadline(time.Now().Add(c.WriteTimeout)) - c.conn.Write(buf.Bytes()) + c.conn.Write(buf[:n]) } } } diff --git a/client_publish_test.go b/client_publish_test.go index 9c6fe0a8..530564a6 100644 --- a/client_publish_test.go +++ b/client_publish_test.go @@ -2,7 +2,6 @@ package gortsplib import ( "bufio" - "bytes" "crypto/tls" "net" "strings" @@ -83,15 +82,13 @@ func TestClientPublishSerial(t *testing.T) { require.NoError(t, err) defer conn.Close() br := bufio.NewReader(conn) - var bb bytes.Buffer req, err := readRequest(br) require.NoError(t, err) require.Equal(t, base.Options, req.Method) require.Equal(t, mustParseURL(scheme+"://localhost:8554/teststream"), req.URL) - bb.Reset() - base.Response{ + byts, _ := base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Public": base.HeaderValue{strings.Join([]string{ @@ -100,8 +97,8 @@ func TestClientPublishSerial(t *testing.T) { string(base.Record), }, ", ")}, }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -109,11 +106,10 @@ func TestClientPublishSerial(t *testing.T) { require.Equal(t, base.Announce, req.Method) require.Equal(t, mustParseURL(scheme+"://localhost:8554/teststream"), req.URL) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -153,14 +149,13 @@ func TestClientPublishSerial(t *testing.T) { th.InterleavedIDs = inTH.InterleavedIDs } - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Transport": th.Write(), }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -168,11 +163,10 @@ func TestClientPublishSerial(t *testing.T) { require.Equal(t, base.Record, req.Method) require.Equal(t, mustParseURL(scheme+"://localhost:8554/teststream"), req.URL) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) // client -> server (RTP) @@ -202,12 +196,11 @@ func TestClientPublishSerial(t *testing.T) { Port: th.ClientPorts[1], }) } else { - bb.Reset() - base.InterleavedFrame{ + byts, _ := base.InterleavedFrame{ Channel: 1, Payload: testRTCPPacketMarshaled, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) } @@ -216,11 +209,10 @@ func TestClientPublishSerial(t *testing.T) { require.Equal(t, base.Teardown, req.Method) require.Equal(t, mustParseURL(scheme+"://localhost:8554/teststream"), req.URL) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) }() @@ -303,14 +295,12 @@ func TestClientPublishParallel(t *testing.T) { require.NoError(t, err) defer conn.Close() br := bufio.NewReader(conn) - var bb bytes.Buffer req, err := readRequest(br) require.NoError(t, err) require.Equal(t, base.Options, req.Method) - bb.Reset() - base.Response{ + byts, _ := base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Public": base.HeaderValue{strings.Join([]string{ @@ -319,19 +309,18 @@ func TestClientPublishParallel(t *testing.T) { string(base.Record), }, ", ")}, }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) require.NoError(t, err) require.Equal(t, base.Announce, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -358,36 +347,33 @@ func TestClientPublishParallel(t *testing.T) { th.InterleavedIDs = inTH.InterleavedIDs } - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Transport": th.Write(), }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) require.NoError(t, err) require.Equal(t, base.Record, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequestIgnoreFrames(br) require.NoError(t, err) require.Equal(t, base.Teardown, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) }() @@ -454,14 +440,12 @@ func TestClientPublishPauseSerial(t *testing.T) { require.NoError(t, err) defer conn.Close() br := bufio.NewReader(conn) - var bb bytes.Buffer req, err := readRequest(br) require.NoError(t, err) require.Equal(t, base.Options, req.Method) - bb.Reset() - base.Response{ + byts, _ := base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Public": base.HeaderValue{strings.Join([]string{ @@ -471,19 +455,18 @@ func TestClientPublishPauseSerial(t *testing.T) { string(base.Pause), }, ", ")}, }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) require.NoError(t, err) require.Equal(t, base.Announce, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -510,58 +493,53 @@ func TestClientPublishPauseSerial(t *testing.T) { th.InterleavedIDs = inTH.InterleavedIDs } - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Transport": th.Write(), }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) require.NoError(t, err) require.Equal(t, base.Record, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequestIgnoreFrames(br) require.NoError(t, err) require.Equal(t, base.Pause, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) require.NoError(t, err) require.Equal(t, base.Record, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequestIgnoreFrames(br) require.NoError(t, err) require.Equal(t, base.Teardown, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) }() @@ -618,14 +596,12 @@ func TestClientPublishPauseParallel(t *testing.T) { require.NoError(t, err) defer conn.Close() br := bufio.NewReader(conn) - var bb bytes.Buffer req, err := readRequest(br) require.NoError(t, err) require.Equal(t, base.Options, req.Method) - bb.Reset() - base.Response{ + byts, _ := base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Public": base.HeaderValue{strings.Join([]string{ @@ -635,19 +611,18 @@ func TestClientPublishPauseParallel(t *testing.T) { string(base.Pause), }, ", ")}, }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) require.NoError(t, err) require.Equal(t, base.Announce, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -674,36 +649,33 @@ func TestClientPublishPauseParallel(t *testing.T) { th.InterleavedIDs = inTH.InterleavedIDs } - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Transport": th.Write(), }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) require.NoError(t, err) require.Equal(t, base.Record, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequestIgnoreFrames(br) require.NoError(t, err) require.Equal(t, base.Pause, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) }() @@ -765,15 +737,13 @@ func TestClientPublishAutomaticProtocol(t *testing.T) { require.NoError(t, err) defer conn.Close() br := bufio.NewReader(conn) - var bb bytes.Buffer req, err := readRequest(br) require.NoError(t, err) require.Equal(t, base.Options, req.Method) require.Equal(t, mustParseURL("rtsp://localhost:8554/teststream"), req.URL) - bb.Reset() - base.Response{ + byts, _ := base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Public": base.HeaderValue{strings.Join([]string{ @@ -782,8 +752,8 @@ func TestClientPublishAutomaticProtocol(t *testing.T) { string(base.Record), }, ", ")}, }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -791,22 +761,20 @@ func TestClientPublishAutomaticProtocol(t *testing.T) { require.Equal(t, base.Announce, req.Method) require.Equal(t, mustParseURL("rtsp://localhost:8554/teststream"), req.URL) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) require.NoError(t, err) require.Equal(t, base.Setup, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusUnsupportedTransport, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -827,14 +795,13 @@ func TestClientPublishAutomaticProtocol(t *testing.T) { InterleavedIDs: &[2]int{0, 1}, } - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Transport": th.Write(), }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -842,11 +809,10 @@ func TestClientPublishAutomaticProtocol(t *testing.T) { require.Equal(t, base.Record, req.Method) require.Equal(t, mustParseURL("rtsp://localhost:8554/teststream"), req.URL) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) var f base.InterleavedFrame @@ -862,11 +828,10 @@ func TestClientPublishAutomaticProtocol(t *testing.T) { require.NoError(t, err) require.Equal(t, base.Teardown, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) }() @@ -900,14 +865,12 @@ func TestClientPublishRTCPReport(t *testing.T) { require.NoError(t, err) defer conn.Close() br := bufio.NewReader(conn) - var bb bytes.Buffer req, err := readRequest(br) require.NoError(t, err) require.Equal(t, base.Options, req.Method) - bb.Reset() - base.Response{ + byts, _ := base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Public": base.HeaderValue{strings.Join([]string{ @@ -916,19 +879,18 @@ func TestClientPublishRTCPReport(t *testing.T) { string(base.Record), }, ", ")}, }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) require.NoError(t, err) require.Equal(t, base.Announce, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -947,8 +909,7 @@ func TestClientPublishRTCPReport(t *testing.T) { require.NoError(t, err) defer l2.Close() - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Transport": headers.Transport{ @@ -961,19 +922,18 @@ func TestClientPublishRTCPReport(t *testing.T) { ServerPorts: &[2]int{34556, 34557}, }.Write(), }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) require.NoError(t, err) require.Equal(t, base.Record, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) buf := make([]byte, 2048) @@ -1004,11 +964,10 @@ func TestClientPublishRTCPReport(t *testing.T) { require.NoError(t, err) require.Equal(t, base.Teardown, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) }() @@ -1054,14 +1013,12 @@ func TestClientPublishIgnoreTCPRTPPackets(t *testing.T) { require.NoError(t, err) defer conn.Close() br := bufio.NewReader(conn) - var bb bytes.Buffer req, err := readRequest(br) require.NoError(t, err) require.Equal(t, base.Options, req.Method) - bb.Reset() - base.Response{ + byts, _ := base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Public": base.HeaderValue{strings.Join([]string{ @@ -1070,19 +1027,18 @@ func TestClientPublishIgnoreTCPRTPPackets(t *testing.T) { string(base.Record), }, ", ")}, }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) require.NoError(t, err) require.Equal(t, base.Announce, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -1102,52 +1058,47 @@ func TestClientPublishIgnoreTCPRTPPackets(t *testing.T) { InterleavedIDs: inTH.InterleavedIDs, } - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Transport": th.Write(), }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) require.NoError(t, err) require.Equal(t, base.Record, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) - bb.Reset() - base.InterleavedFrame{ + byts, _ = base.InterleavedFrame{ Channel: 0, Payload: testRTPPacketMarshaled, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) - bb.Reset() - base.InterleavedFrame{ + byts, _ = base.InterleavedFrame{ Channel: 1, Payload: testRTCPPacketMarshaled, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) require.NoError(t, err) require.Equal(t, base.Teardown, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) }() diff --git a/client_read_test.go b/client_read_test.go index efc1d4b2..82231216 100644 --- a/client_read_test.go +++ b/client_read_test.go @@ -60,14 +60,12 @@ func TestClientReadTracks(t *testing.T) { require.NoError(t, err) defer conn.Close() br := bufio.NewReader(conn) - var bb bytes.Buffer req, err := readRequest(br) require.NoError(t, err) require.Equal(t, base.Options, req.Method) - bb.Reset() - base.Response{ + byts, _ := base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Public": base.HeaderValue{strings.Join([]string{ @@ -76,8 +74,8 @@ func TestClientReadTracks(t *testing.T) { string(base.Play), }, ", ")}, }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -88,16 +86,15 @@ func TestClientReadTracks(t *testing.T) { tracks := Tracks{track1, track2, track3} tracks.setControls() - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Content-Type": base.HeaderValue{"application/sdp"}, "Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"}, }, Body: tracks.Write(false), - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) for i := 0; i < 3; i++ { @@ -120,14 +117,13 @@ func TestClientReadTracks(t *testing.T) { ServerPorts: &[2]int{34556 + i*2, 34557 + i*2}, } - bb.Reset() - base.Response{ + byts, _ := base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Transport": th.Write(), }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) } @@ -136,11 +132,10 @@ func TestClientReadTracks(t *testing.T) { require.Equal(t, base.Play, req.Method) require.Equal(t, mustParseURL("rtsp://localhost:8554/teststream/"), req.URL) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -148,11 +143,10 @@ func TestClientReadTracks(t *testing.T) { require.Equal(t, base.Teardown, req.Method) require.Equal(t, mustParseURL("rtsp://localhost:8554/teststream/"), req.URL) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) }() @@ -201,15 +195,13 @@ func TestClientRead(t *testing.T) { require.NoError(t, err) defer conn.Close() br := bufio.NewReader(conn) - var bb bytes.Buffer req, err := readRequest(br) require.NoError(t, err) require.Equal(t, base.Options, req.Method) require.Equal(t, mustParseURL(scheme+"://"+listenIP+":8554/test/stream?param=value"), req.URL) - bb.Reset() - base.Response{ + byts, _ := base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Public": base.HeaderValue{strings.Join([]string{ @@ -218,8 +210,8 @@ func TestClientRead(t *testing.T) { string(base.Play), }, ", ")}, }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -233,16 +225,15 @@ func TestClientRead(t *testing.T) { tracks := Tracks{track} tracks.setControls() - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Content-Type": base.HeaderValue{"application/sdp"}, "Content-Base": base.HeaderValue{scheme + "://" + listenIP + ":8554/test/stream?param=value/"}, }, Body: tracks.Write(false), - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -318,14 +309,13 @@ func TestClientRead(t *testing.T) { th.InterleavedIDs = &[2]int{0, 1} } - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Transport": th.Write(), }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -334,11 +324,10 @@ func TestClientRead(t *testing.T) { require.Equal(t, mustParseURL(scheme+"://"+listenIP+":8554/test/stream?param=value/"), req.URL) require.Equal(t, base.HeaderValue{"npt=0-"}, req.Header["Range"]) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) // server -> client (RTP) @@ -358,12 +347,11 @@ func TestClientRead(t *testing.T) { }) case "tcp", "tls": - bb.Reset() - base.InterleavedFrame{ + byts, _ := base.InterleavedFrame{ Channel: 0, Payload: testRTPPacketMarshaled, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) } @@ -399,11 +387,10 @@ func TestClientRead(t *testing.T) { require.Equal(t, base.Teardown, req.Method) require.Equal(t, mustParseURL(scheme+"://"+listenIP+":8554/test/stream?param=value/"), req.URL) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) }() @@ -522,15 +509,13 @@ func TestClientReadOversizedPacket(t *testing.T) { require.NoError(t, err) defer conn.Close() br := bufio.NewReader(conn) - var bb bytes.Buffer req, err := readRequest(br) require.NoError(t, err) require.Equal(t, base.Options, req.Method) require.Equal(t, mustParseURL("rtsp://localhost:8554/teststream"), req.URL) - bb.Reset() - base.Response{ + byts, _ := base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Public": base.HeaderValue{strings.Join([]string{ @@ -539,8 +524,8 @@ func TestClientReadOversizedPacket(t *testing.T) { string(base.Play), }, ", ")}, }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -554,16 +539,15 @@ func TestClientReadOversizedPacket(t *testing.T) { tracks := Tracks{track} tracks.setControls() - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Content-Type": base.HeaderValue{"application/sdp"}, "Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"}, }, Body: tracks.Write(false), - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -580,14 +564,13 @@ func TestClientReadOversizedPacket(t *testing.T) { InterleavedIDs: &[2]int{0, 1}, } - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Transport": th.Write(), }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -596,20 +579,18 @@ func TestClientReadOversizedPacket(t *testing.T) { require.Equal(t, mustParseURL("rtsp://localhost:8554/teststream/"), req.URL) require.Equal(t, base.HeaderValue{"npt=0-"}, req.Header["Range"]) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) - byts, _ := oversizedPacketRTPIn.Marshal() - bb.Reset() - base.InterleavedFrame{ + byts, _ = oversizedPacketRTPIn.Marshal() + byts, _ = base.InterleavedFrame{ Channel: 0, Payload: byts, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) }() @@ -653,14 +634,12 @@ func TestClientReadPartial(t *testing.T) { require.NoError(t, err) defer conn.Close() br := bufio.NewReader(conn) - var bb bytes.Buffer req, err := readRequest(br) require.NoError(t, err) require.Equal(t, base.Options, req.Method) - bb.Reset() - base.Response{ + byts, _ := base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Public": base.HeaderValue{strings.Join([]string{ @@ -669,8 +648,8 @@ func TestClientReadPartial(t *testing.T) { string(base.Play), }, ", ")}, }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -687,16 +666,15 @@ func TestClientReadPartial(t *testing.T) { tracks := Tracks{track1, track2} tracks.setControls() - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Content-Type": base.HeaderValue{"application/sdp"}, "Content-Base": base.HeaderValue{"rtsp://" + listenIP + ":8554/teststream/"}, }, Body: tracks.Write(false), - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -718,14 +696,13 @@ func TestClientReadPartial(t *testing.T) { InterleavedIDs: inTH.InterleavedIDs, } - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Transport": th.Write(), }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -733,19 +710,17 @@ func TestClientReadPartial(t *testing.T) { require.Equal(t, base.Play, req.Method) require.Equal(t, mustParseURL("rtsp://"+listenIP+":8554/teststream/"), req.URL) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) - bb.Reset() - base.InterleavedFrame{ + byts, _ = base.InterleavedFrame{ Channel: 0, Payload: testRTPPacketMarshaled, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -753,11 +728,10 @@ func TestClientReadPartial(t *testing.T) { require.Equal(t, base.Teardown, req.Method) require.Equal(t, mustParseURL("rtsp://"+listenIP+":8554/teststream/"), req.URL) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) }() @@ -808,14 +782,12 @@ func TestClientReadNoContentBase(t *testing.T) { require.NoError(t, err) defer conn.Close() br := bufio.NewReader(conn) - var bb bytes.Buffer req, err := readRequest(br) require.NoError(t, err) require.Equal(t, base.Options, req.Method) - bb.Reset() - base.Response{ + byts, _ := base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Public": base.HeaderValue{strings.Join([]string{ @@ -824,8 +796,8 @@ func TestClientReadNoContentBase(t *testing.T) { string(base.Play), }, ", ")}, }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -839,15 +811,14 @@ func TestClientReadNoContentBase(t *testing.T) { tracks := Tracks{track} tracks.setControls() - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Content-Type": base.HeaderValue{"application/sdp"}, }, Body: tracks.Write(false), - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -869,14 +840,13 @@ func TestClientReadNoContentBase(t *testing.T) { ServerPorts: &[2]int{34556, 34557}, } - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Transport": th.Write(), }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -884,11 +854,10 @@ func TestClientReadNoContentBase(t *testing.T) { require.Equal(t, base.Play, req.Method) require.Equal(t, mustParseURL("rtsp://localhost:8554/teststream"), req.URL) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -896,11 +865,10 @@ func TestClientReadNoContentBase(t *testing.T) { require.Equal(t, base.Teardown, req.Method) require.Equal(t, mustParseURL("rtsp://localhost:8554/teststream"), req.URL) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) }() @@ -934,14 +902,12 @@ func TestClientReadAnyPort(t *testing.T) { require.NoError(t, err) defer conn.Close() br := bufio.NewReader(conn) - var bb bytes.Buffer req, err := readRequest(br) require.NoError(t, err) require.Equal(t, base.Options, req.Method) - bb.Reset() - base.Response{ + byts, _ := base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Public": base.HeaderValue{strings.Join([]string{ @@ -950,8 +916,8 @@ func TestClientReadAnyPort(t *testing.T) { string(base.Play), }, ", ")}, }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -964,16 +930,15 @@ func TestClientReadAnyPort(t *testing.T) { tracks := Tracks{track} tracks.setControls() - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Content-Type": base.HeaderValue{"application/sdp"}, "Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"}, }, Body: tracks.Write(false), - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -992,8 +957,7 @@ func TestClientReadAnyPort(t *testing.T) { require.NoError(t, err) defer l1b.Close() - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Transport": headers.Transport{ @@ -1020,19 +984,18 @@ func TestClientReadAnyPort(t *testing.T) { }(), }.Write(), }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) require.NoError(t, err) require.Equal(t, base.Play, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) time.Sleep(500 * time.Millisecond) @@ -1098,14 +1061,12 @@ func TestClientReadAutomaticProtocol(t *testing.T) { require.NoError(t, err) defer conn.Close() br := bufio.NewReader(conn) - var bb bytes.Buffer req, err := readRequest(br) require.NoError(t, err) require.Equal(t, base.Options, req.Method) - bb.Reset() - base.Response{ + byts, _ := base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Public": base.HeaderValue{strings.Join([]string{ @@ -1114,8 +1075,8 @@ func TestClientReadAutomaticProtocol(t *testing.T) { string(base.Play), }, ", ")}, }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -1128,27 +1089,25 @@ func TestClientReadAutomaticProtocol(t *testing.T) { tracks := Tracks{track} tracks.setControls() - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Content-Type": base.HeaderValue{"application/sdp"}, "Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"}, }, Body: tracks.Write(false), - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) require.NoError(t, err) require.Equal(t, base.Setup, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusUnsupportedTransport, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -1160,8 +1119,7 @@ func TestClientReadAutomaticProtocol(t *testing.T) { require.NoError(t, err) require.Equal(t, headers.TransportProtocolTCP, inTH.Protocol) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Transport": headers.Transport{ @@ -1173,27 +1131,25 @@ func TestClientReadAutomaticProtocol(t *testing.T) { InterleavedIDs: &[2]int{0, 1}, }.Write(), }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) require.NoError(t, err) require.Equal(t, base.Play, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) - bb.Reset() - base.InterleavedFrame{ + byts, _ = base.InterleavedFrame{ Channel: 0, Payload: testRTPPacketMarshaled, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) }() @@ -1225,14 +1181,12 @@ func TestClientReadAutomaticProtocol(t *testing.T) { conn, err := l.Accept() require.NoError(t, err) br := bufio.NewReader(conn) - var bb bytes.Buffer req, err := readRequest(br) require.NoError(t, err) require.Equal(t, base.Options, req.Method) - bb.Reset() - base.Response{ + byts, _ := base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Public": base.HeaderValue{strings.Join([]string{ @@ -1241,8 +1195,8 @@ func TestClientReadAutomaticProtocol(t *testing.T) { string(base.Play), }, ", ")}, }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -1251,14 +1205,13 @@ func TestClientReadAutomaticProtocol(t *testing.T) { v := auth.NewValidator("myuser", "mypass", nil) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusUnauthorized, Header: base.Header{ "WWW-Authenticate": v.Header(), }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -1274,16 +1227,15 @@ func TestClientReadAutomaticProtocol(t *testing.T) { tracks := Tracks{track} tracks.setControls() - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Content-Type": base.HeaderValue{"application/sdp"}, "Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"}, }, Body: tracks.Write(false), - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -1305,36 +1257,33 @@ func TestClientReadAutomaticProtocol(t *testing.T) { ClientPorts: inTH.ClientPorts, } - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Transport": th.Write(), }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) require.NoError(t, err) require.Equal(t, base.Play, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) require.NoError(t, err) require.Equal(t, base.Teardown, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) conn.Close() @@ -1347,8 +1296,7 @@ func TestClientReadAutomaticProtocol(t *testing.T) { require.NoError(t, err) require.Equal(t, base.Options, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Public": base.HeaderValue{strings.Join([]string{ @@ -1357,24 +1305,23 @@ func TestClientReadAutomaticProtocol(t *testing.T) { string(base.Play), }, ", ")}, }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) require.NoError(t, err) require.Equal(t, base.Describe, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Content-Type": base.HeaderValue{"application/sdp"}, "Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"}, }, Body: tracks.Write(false), - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -1383,14 +1330,13 @@ func TestClientReadAutomaticProtocol(t *testing.T) { v = auth.NewValidator("myuser", "mypass", nil) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusUnauthorized, Header: base.Header{ "WWW-Authenticate": v.Header(), }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -1414,44 +1360,40 @@ func TestClientReadAutomaticProtocol(t *testing.T) { InterleavedIDs: inTH.InterleavedIDs, } - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Transport": th.Write(), }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) require.NoError(t, err) require.Equal(t, base.Play, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) - bb.Reset() - base.InterleavedFrame{ + byts, _ = base.InterleavedFrame{ Channel: 0, Payload: testRTPPacketMarshaled, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) require.NoError(t, err) require.Equal(t, base.Teardown, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) conn.Close() @@ -1488,14 +1430,12 @@ func TestClientReadDifferentInterleavedIDs(t *testing.T) { require.NoError(t, err) defer conn.Close() br := bufio.NewReader(conn) - var bb bytes.Buffer req, err := readRequest(br) require.NoError(t, err) require.Equal(t, base.Options, req.Method) - bb.Reset() - base.Response{ + byts, _ := base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Public": base.HeaderValue{strings.Join([]string{ @@ -1504,8 +1444,8 @@ func TestClientReadDifferentInterleavedIDs(t *testing.T) { string(base.Play), }, ", ")}, }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -1519,16 +1459,15 @@ func TestClientReadDifferentInterleavedIDs(t *testing.T) { tracks := Tracks{track1} tracks.setControls() - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Content-Type": base.HeaderValue{"application/sdp"}, "Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"}, }, Body: tracks.Write(false), - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -1549,14 +1488,13 @@ func TestClientReadDifferentInterleavedIDs(t *testing.T) { InterleavedIDs: &[2]int{2, 3}, } - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Transport": th.Write(), }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -1564,19 +1502,17 @@ func TestClientReadDifferentInterleavedIDs(t *testing.T) { require.Equal(t, base.Play, req.Method) require.Equal(t, mustParseURL("rtsp://localhost:8554/teststream/"), req.URL) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) - bb.Reset() - base.InterleavedFrame{ + byts, _ = base.InterleavedFrame{ Channel: 2, Payload: testRTPPacketMarshaled, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -1584,11 +1520,10 @@ func TestClientReadDifferentInterleavedIDs(t *testing.T) { require.Equal(t, base.Teardown, req.Method) require.Equal(t, mustParseURL("rtsp://localhost:8554/teststream/"), req.URL) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) }() @@ -1625,14 +1560,12 @@ func TestClientReadRedirect(t *testing.T) { conn, err := l.Accept() require.NoError(t, err) br := bufio.NewReader(conn) - var bb bytes.Buffer req, err := readRequest(br) require.NoError(t, err) require.Equal(t, base.Options, req.Method) - bb.Reset() - base.Response{ + byts, _ := base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Public": base.HeaderValue{strings.Join([]string{ @@ -1641,22 +1574,21 @@ func TestClientReadRedirect(t *testing.T) { string(base.Play), }, ", ")}, }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) require.NoError(t, err) require.Equal(t, base.Describe, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusMovedPermanently, Header: base.Header{ "Location": base.HeaderValue{"rtsp://localhost:8554/test"}, }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) conn.Close() @@ -1670,8 +1602,7 @@ func TestClientReadRedirect(t *testing.T) { require.NoError(t, err) require.Equal(t, base.Options, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Public": base.HeaderValue{strings.Join([]string{ @@ -1680,8 +1611,8 @@ func TestClientReadRedirect(t *testing.T) { string(base.Play), }, ", ")}, }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -1694,16 +1625,15 @@ func TestClientReadRedirect(t *testing.T) { tracks := Tracks{track} tracks.setControls() - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Content-Type": base.HeaderValue{"application/sdp"}, "Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"}, }, Body: tracks.Write(false), - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -1714,8 +1644,7 @@ func TestClientReadRedirect(t *testing.T) { err = th.Read(req.Header["Transport"]) require.NoError(t, err) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Transport": headers.Transport{ @@ -1728,19 +1657,18 @@ func TestClientReadRedirect(t *testing.T) { ServerPorts: &[2]int{34556, 34557}, }.Write(), }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) require.NoError(t, err) require.Equal(t, base.Play, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) time.Sleep(500 * time.Millisecond) @@ -1785,7 +1713,6 @@ func TestClientReadPause(t *testing.T) { require.NoError(t, err) defer l1.Close() } - var bb bytes.Buffer t := time.NewTicker(50 * time.Millisecond) defer t.Stop() @@ -1799,12 +1726,11 @@ func TestClientReadPause(t *testing.T) { Port: inTH.ClientPorts[0], }) } else { - bb.Reset() - base.InterleavedFrame{ + byts, _ := base.InterleavedFrame{ Channel: 0, Payload: testRTPPacketMarshaled, - }.Write(&bb) - conn.Write(bb.Bytes()) + }.Write() + conn.Write(byts) } case <-writerTerminate: @@ -1834,14 +1760,12 @@ func TestClientReadPause(t *testing.T) { require.NoError(t, err) defer conn.Close() br := bufio.NewReader(conn) - var bb bytes.Buffer req, err := readRequest(br) require.NoError(t, err) require.Equal(t, base.Options, req.Method) - bb.Reset() - base.Response{ + byts, _ := base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Public": base.HeaderValue{strings.Join([]string{ @@ -1850,8 +1774,8 @@ func TestClientReadPause(t *testing.T) { string(base.Play), }, ", ")}, }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -1864,16 +1788,15 @@ func TestClientReadPause(t *testing.T) { tracks := Tracks{track} tracks.setControls() - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Content-Type": base.HeaderValue{"application/sdp"}, "Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"}, }, Body: tracks.Write(false), - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -1900,25 +1823,23 @@ func TestClientReadPause(t *testing.T) { th.InterleavedIDs = inTH.InterleavedIDs } - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Transport": th.Write(), }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) require.NoError(t, err) require.Equal(t, base.Play, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) writerTerminate, writerDone := writeFrames(&inTH, conn, br) @@ -1930,22 +1851,20 @@ func TestClientReadPause(t *testing.T) { close(writerTerminate) <-writerDone - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) require.NoError(t, err) require.Equal(t, base.Play, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) writerTerminate, writerDone = writeFrames(&inTH, conn, br) @@ -1957,11 +1876,10 @@ func TestClientReadPause(t *testing.T) { close(writerTerminate) <-writerDone - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) }() @@ -2020,14 +1938,12 @@ func TestClientReadRTCPReport(t *testing.T) { require.NoError(t, err) defer conn.Close() br := bufio.NewReader(conn) - var bb bytes.Buffer req, err := readRequest(br) require.NoError(t, err) require.Equal(t, base.Options, req.Method) - bb.Reset() - base.Response{ + byts, _ := base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Public": base.HeaderValue{strings.Join([]string{ @@ -2036,8 +1952,8 @@ func TestClientReadRTCPReport(t *testing.T) { string(base.Play), }, ", ")}, }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -2051,16 +1967,15 @@ func TestClientReadRTCPReport(t *testing.T) { tracks := Tracks{track} tracks.setControls() - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Content-Type": base.HeaderValue{"application/sdp"}, "Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"}, }, Body: tracks.Write(false), - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -2079,8 +1994,7 @@ func TestClientReadRTCPReport(t *testing.T) { require.NoError(t, err) defer l2.Close() - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Transport": headers.Transport{ @@ -2093,19 +2007,18 @@ func TestClientReadRTCPReport(t *testing.T) { ClientPorts: inTH.ClientPorts, }.Write(), }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) require.NoError(t, err) require.Equal(t, base.Play, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) // skip firewall opening @@ -2124,7 +2037,7 @@ func TestClientReadRTCPReport(t *testing.T) { }, Payload: []byte{0x05, 0x02, 0x03, 0x04}, } - byts, _ := pkt.Marshal() + byts, _ = pkt.Marshal() _, err = l1.WriteTo(byts, &net.UDPAddr{ IP: net.ParseIP("127.0.0.1"), Port: inTH.ClientPorts[0], @@ -2171,11 +2084,10 @@ func TestClientReadRTCPReport(t *testing.T) { require.NoError(t, err) require.Equal(t, base.Teardown, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) }() @@ -2210,14 +2122,12 @@ func TestClientReadErrorTimeout(t *testing.T) { require.NoError(t, err) defer conn.Close() br := bufio.NewReader(conn) - var bb bytes.Buffer req, err := readRequest(br) require.NoError(t, err) require.Equal(t, base.Options, req.Method) - bb.Reset() - base.Response{ + byts, _ := base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Public": base.HeaderValue{strings.Join([]string{ @@ -2226,8 +2136,8 @@ func TestClientReadErrorTimeout(t *testing.T) { string(base.Play), }, ", ")}, }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -2240,16 +2150,15 @@ func TestClientReadErrorTimeout(t *testing.T) { tracks := Tracks{track} tracks.setControls() - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Content-Type": base.HeaderValue{"application/sdp"}, "Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"}, }, Body: tracks.Write(false), - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -2282,25 +2191,23 @@ func TestClientReadErrorTimeout(t *testing.T) { th.InterleavedIDs = inTH.InterleavedIDs } - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Transport": th.Write(), }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) require.NoError(t, err) require.Equal(t, base.Play, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) if transport == "udp" || transport == "auto" { @@ -2315,11 +2222,10 @@ func TestClientReadErrorTimeout(t *testing.T) { require.NoError(t, err) require.Equal(t, base.Teardown, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) }() @@ -2370,14 +2276,12 @@ func TestClientReadIgnoreTCPInvalidTrack(t *testing.T) { require.NoError(t, err) defer conn.Close() br := bufio.NewReader(conn) - var bb bytes.Buffer req, err := readRequest(br) require.NoError(t, err) require.Equal(t, base.Options, req.Method) - bb.Reset() - base.Response{ + byts, _ := base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Public": base.HeaderValue{strings.Join([]string{ @@ -2386,8 +2290,8 @@ func TestClientReadIgnoreTCPInvalidTrack(t *testing.T) { string(base.Play), }, ", ")}, }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -2400,16 +2304,15 @@ func TestClientReadIgnoreTCPInvalidTrack(t *testing.T) { tracks := Tracks{track} tracks.setControls() - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Content-Type": base.HeaderValue{"application/sdp"}, "Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"}, }, Body: tracks.Write(false), - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -2429,52 +2332,47 @@ func TestClientReadIgnoreTCPInvalidTrack(t *testing.T) { th.Protocol = headers.TransportProtocolTCP th.InterleavedIDs = inTH.InterleavedIDs - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Transport": th.Write(), }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) require.NoError(t, err) require.Equal(t, base.Play, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) - bb.Reset() - base.InterleavedFrame{ + byts, _ = base.InterleavedFrame{ Channel: 6, Payload: testRTPPacketMarshaled, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) - bb.Reset() - base.InterleavedFrame{ + byts, _ = base.InterleavedFrame{ Channel: 0, Payload: testRTPPacketMarshaled, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) require.NoError(t, err) require.Equal(t, base.Teardown, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) }() @@ -2511,14 +2409,12 @@ func TestClientReadSeek(t *testing.T) { require.NoError(t, err) defer conn.Close() br := bufio.NewReader(conn) - var bb bytes.Buffer req, err := readRequest(br) require.NoError(t, err) require.Equal(t, base.Options, req.Method) - bb.Reset() - base.Response{ + byts, _ := base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Public": base.HeaderValue{strings.Join([]string{ @@ -2527,8 +2423,8 @@ func TestClientReadSeek(t *testing.T) { string(base.Play), }, ", ")}, }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -2541,16 +2437,15 @@ func TestClientReadSeek(t *testing.T) { tracks := Tracks{track} tracks.setControls() - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Content-Type": base.HeaderValue{"application/sdp"}, "Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"}, }, Body: tracks.Write(false), - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -2570,14 +2465,13 @@ func TestClientReadSeek(t *testing.T) { InterleavedIDs: inTH.InterleavedIDs, } - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Transport": th.Write(), }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -2593,22 +2487,20 @@ func TestClientReadSeek(t *testing.T) { }, }, ra) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) require.NoError(t, err) require.Equal(t, base.Pause, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -2623,22 +2515,20 @@ func TestClientReadSeek(t *testing.T) { }, }, ra) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) require.NoError(t, err) require.Equal(t, base.Teardown, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) }() @@ -2695,14 +2585,12 @@ func TestClientReadKeepaliveFromSession(t *testing.T) { require.NoError(t, err) defer conn.Close() br := bufio.NewReader(conn) - var bb bytes.Buffer req, err := readRequest(br) require.NoError(t, err) require.Equal(t, base.Options, req.Method) - bb.Reset() - base.Response{ + byts, _ := base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Public": base.HeaderValue{strings.Join([]string{ @@ -2711,8 +2599,8 @@ func TestClientReadKeepaliveFromSession(t *testing.T) { string(base.Play), }, ", ")}, }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -2725,16 +2613,15 @@ func TestClientReadKeepaliveFromSession(t *testing.T) { tracks := Tracks{track} tracks.setControls() - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Content-Type": base.HeaderValue{"application/sdp"}, "Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"}, }, Body: tracks.Write(false), - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -2745,8 +2632,7 @@ func TestClientReadKeepaliveFromSession(t *testing.T) { err = inTH.Read(req.Header["Transport"]) require.NoError(t, err) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Transport": headers.Transport{ @@ -2766,19 +2652,18 @@ func TestClientReadKeepaliveFromSession(t *testing.T) { }(), }.Write(), }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) require.NoError(t, err) require.Equal(t, base.Play, req.Method) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) recv := make(chan struct{}) @@ -2788,11 +2673,10 @@ func TestClientReadKeepaliveFromSession(t *testing.T) { require.NoError(t, err) require.Equal(t, base.Options, req.Method) - bb.Reset() - base.Response{ + byts, _ := base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) }() @@ -2830,15 +2714,13 @@ func TestClientReadDifferentSource(t *testing.T) { require.NoError(t, err) defer conn.Close() br := bufio.NewReader(conn) - var bb bytes.Buffer req, err := readRequest(br) require.NoError(t, err) require.Equal(t, base.Options, req.Method) require.Equal(t, mustParseURL("rtsp://localhost:8554/test/stream?param=value"), req.URL) - bb.Reset() - base.Response{ + byts, _ := base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Public": base.HeaderValue{strings.Join([]string{ @@ -2847,8 +2729,8 @@ func TestClientReadDifferentSource(t *testing.T) { string(base.Play), }, ", ")}, }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -2862,16 +2744,15 @@ func TestClientReadDifferentSource(t *testing.T) { tracks := Tracks{track} tracks.setControls() - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Content-Type": base.HeaderValue{"application/sdp"}, "Content-Base": base.HeaderValue{"rtsp://localhost:8554/test/stream?param=value/"}, }, Body: tracks.Write(false), - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -2905,14 +2786,13 @@ func TestClientReadDifferentSource(t *testing.T) { require.NoError(t, err) defer l2.Close() - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Transport": th.Write(), }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -2921,11 +2801,10 @@ func TestClientReadDifferentSource(t *testing.T) { require.Equal(t, mustParseURL("rtsp://localhost:8554/test/stream?param=value/"), req.URL) require.Equal(t, base.HeaderValue{"npt=0-"}, req.Header["Range"]) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) // server -> client (RTP) @@ -2940,11 +2819,10 @@ func TestClientReadDifferentSource(t *testing.T) { require.Equal(t, base.Teardown, req.Method) require.Equal(t, mustParseURL("rtsp://localhost:8554/test/stream?param=value/"), req.URL) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) }() diff --git a/client_test.go b/client_test.go index 2cfa8950..98cce432 100644 --- a/client_test.go +++ b/client_test.go @@ -2,7 +2,6 @@ package gortsplib import ( "bufio" - "bytes" "crypto/tls" "net" "strings" @@ -94,15 +93,13 @@ func TestClientSession(t *testing.T) { conn, err := l.Accept() require.NoError(t, err) br := bufio.NewReader(conn) - var bb bytes.Buffer defer conn.Close() req, err := readRequest(br) require.NoError(t, err) require.Equal(t, base.Options, req.Method) - bb.Reset() - base.Response{ + byts, _ := base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Public": base.HeaderValue{strings.Join([]string{ @@ -110,8 +107,8 @@ func TestClientSession(t *testing.T) { }, ", ")}, "Session": base.HeaderValue{"123456"}, }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -126,16 +123,15 @@ func TestClientSession(t *testing.T) { tracks := Tracks{track} tracks.setControls() - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Content-Type": base.HeaderValue{"application/sdp"}, "Session": base.HeaderValue{"123456"}, }, Body: tracks.Write(false), - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) }() @@ -165,23 +161,21 @@ func TestClientAuth(t *testing.T) { conn, err := l.Accept() require.NoError(t, err) br := bufio.NewReader(conn) - var bb bytes.Buffer defer conn.Close() req, err := readRequest(br) require.NoError(t, err) require.Equal(t, base.Options, req.Method) - bb.Reset() - base.Response{ + byts, _ := base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Public": base.HeaderValue{strings.Join([]string{ string(base.Describe), }, ", ")}, }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -190,14 +184,13 @@ func TestClientAuth(t *testing.T) { v := auth.NewValidator("myuser", "mypass", nil) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusUnauthorized, Header: base.Header{ "WWW-Authenticate": v.Header(), }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -213,15 +206,14 @@ func TestClientAuth(t *testing.T) { tracks := Tracks{track} tracks.setControls() - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Content-Type": base.HeaderValue{"application/sdp"}, }, Body: tracks.Write(false), - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) }() @@ -252,22 +244,20 @@ func TestClientDescribeCharset(t *testing.T) { require.NoError(t, err) defer conn.Close() br := bufio.NewReader(conn) - var bb bytes.Buffer req, err := readRequest(br) require.NoError(t, err) require.Equal(t, base.Options, req.Method) - bb.Reset() - base.Response{ + byts, _ := base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Public": base.HeaderValue{strings.Join([]string{ string(base.Describe), }, ", ")}, }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) req, err = readRequest(br) @@ -278,16 +268,15 @@ func TestClientDescribeCharset(t *testing.T) { track1, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) require.NoError(t, err) - bb.Reset() - base.Response{ + byts, _ = base.Response{ StatusCode: base.StatusOK, Header: base.Header{ "Content-Type": base.HeaderValue{"application/sdp; charset=utf-8"}, "Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"}, }, Body: Tracks{track1}.Write(false), - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) }() diff --git a/pkg/base/body.go b/pkg/base/body.go index 8324ddd1..c9e5ee6b 100644 --- a/pkg/base/body.go +++ b/pkg/base/body.go @@ -35,11 +35,16 @@ func (b *body) read(header Header, rb *bufio.Reader) error { return nil } -func (b body) write(w io.Writer) error { - if len(b) == 0 { - return nil - } - - _, err := w.Write(b) - return err +func (b body) writeSize() int { + return len(b) +} + +func (b body) writeTo(buf []byte) int { + return copy(buf, b) +} + +func (b body) write() []byte { + buf := make([]byte, b.writeSize()) + b.writeTo(buf) + return buf } diff --git a/pkg/base/body_test.go b/pkg/base/body_test.go index a4645015..de04a01f 100644 --- a/pkg/base/body_test.go +++ b/pkg/base/body_test.go @@ -20,11 +20,6 @@ var casesBody = []struct { }, []byte{0x01, 0x02, 0x03, 0x04}, }, - { - "nil", - Header{}, - []byte(nil), - }, } func TestBodyRead(t *testing.T) { @@ -81,9 +76,8 @@ func TestBodyReadErrors(t *testing.T) { func TestBodyWrite(t *testing.T) { for _, ca := range casesBody { t.Run(ca.name, func(t *testing.T) { - var buf bytes.Buffer - body(ca.byts).write(&buf) - require.Equal(t, ca.byts, buf.Bytes()) + buf := body(ca.byts).write() + require.Equal(t, ca.byts, buf) }) } } diff --git a/pkg/base/header.go b/pkg/base/header.go index a2980b61..32f153cc 100644 --- a/pkg/base/header.go +++ b/pkg/base/header.go @@ -3,7 +3,6 @@ package base import ( "bufio" "fmt" - "io" "net/http" "sort" "strings" @@ -98,7 +97,7 @@ func (h *Header) read(rb *bufio.Reader) error { return nil } -func (h Header) write(w io.Writer) error { +func (h Header) writeSize() int { // sort headers by key // in order to obtain deterministic results keys := make([]string, len(h)) @@ -107,15 +106,43 @@ func (h Header) write(w io.Writer) error { } sort.Strings(keys) + n := 0 + for _, key := range keys { for _, val := range h[key] { - _, err := w.Write([]byte(key + ": " + val + "\r\n")) - if err != nil { - return err - } + n += len([]byte(key + ": " + val + "\r\n")) } } - _, err := w.Write([]byte("\r\n")) - return err + n += 2 + + return n +} + +func (h Header) writeTo(buf []byte) int { + // sort headers by key + // in order to obtain deterministic results + keys := make([]string, len(h)) + for key := range h { + keys = append(keys, key) + } + sort.Strings(keys) + + pos := 0 + + for _, key := range keys { + for _, val := range h[key] { + pos += copy(buf[pos:], []byte(key+": "+val+"\r\n")) + } + } + + pos += copy(buf[pos:], []byte("\r\n")) + + return pos +} + +func (h Header) write() []byte { + buf := make([]byte, h.writeSize()) + h.writeTo(buf) + return buf } diff --git a/pkg/base/header_test.go b/pkg/base/header_test.go index e8af434c..e58debb3 100644 --- a/pkg/base/header_test.go +++ b/pkg/base/header_test.go @@ -176,9 +176,8 @@ func TestHeaderReadErrors(t *testing.T) { func TestHeaderWrite(t *testing.T) { for _, ca := range casesHeader { t.Run(ca.name, func(t *testing.T) { - var buf bytes.Buffer - ca.header.write(&buf) - require.Equal(t, ca.enc, buf.Bytes()) + buf := ca.header.write() + require.Equal(t, ca.enc, buf) }) } } diff --git a/pkg/base/interleavedframe.go b/pkg/base/interleavedframe.go index 7f1594db..baa8dd00 100644 --- a/pkg/base/interleavedframe.go +++ b/pkg/base/interleavedframe.go @@ -105,16 +105,28 @@ func (f *InterleavedFrame) Read(maxPayloadSize int, br *bufio.Reader) error { return nil } -// Write writes an InterleavedFrame into a buffered writer. -func (f InterleavedFrame) Write(w io.Writer) error { - buf := []byte{0x24, byte(f.Channel), 0x00, 0x00} - binary.BigEndian.PutUint16(buf[2:], uint16(len(f.Payload))) - - _, err := w.Write(buf) - if err != nil { - return err - } - - _, err = w.Write(f.Payload) - return err +// WriteSize returns the size of an InterleavedFrame. +func (f InterleavedFrame) WriteSize() int { + return 4 + len(f.Payload) +} + +// WriteTo writes an InterleavedFrame. +func (f InterleavedFrame) WriteTo(buf []byte) (int, error) { + pos := 0 + + pos += copy(buf[pos:], []byte{0x24, byte(f.Channel)}) + + binary.BigEndian.PutUint16(buf[pos:], uint16(len(f.Payload))) + pos += 2 + + pos += copy(buf[pos:], f.Payload) + + return pos, nil +} + +// Write writes an InterleavedFrame. +func (f InterleavedFrame) Write() ([]byte, error) { + buf := make([]byte, f.WriteSize()) + _, err := f.WriteTo(buf) + return buf, err } diff --git a/pkg/base/interleavedframe_test.go b/pkg/base/interleavedframe_test.go index 047aa572..1c9bdcfe 100644 --- a/pkg/base/interleavedframe_test.go +++ b/pkg/base/interleavedframe_test.go @@ -82,9 +82,9 @@ func TestInterleavedFrameReadErrors(t *testing.T) { func TestInterleavedFrameWrite(t *testing.T) { for _, ca := range casesInterleavedFrame { t.Run(ca.name, func(t *testing.T) { - var buf bytes.Buffer - ca.dec.Write(&buf) - require.Equal(t, ca.enc, buf.Bytes()) + buf, err := ca.dec.Write() + require.NoError(t, err) + require.Equal(t, ca.enc, buf) }) } } diff --git a/pkg/base/request.go b/pkg/base/request.go index 7c57d71a..908c5796 100644 --- a/pkg/base/request.go +++ b/pkg/base/request.go @@ -3,9 +3,7 @@ package base import ( "bufio" - "bytes" "fmt" - "io" "strconv" ) @@ -117,29 +115,51 @@ func (req *Request) ReadIgnoreFrames(maxPayloadSize int, rb *bufio.Reader) error } } -// Write writes a request. -func (req Request) Write(w io.Writer) error { +// WriteSize returns the size of a Request. +func (req Request) WriteSize() int { + n := 0 + urStr := req.URL.CloneWithoutCredentials().String() - _, err := w.Write([]byte(string(req.Method) + " " + urStr + " " + rtspProtocol10 + "\r\n")) - if err != nil { - return err - } + n += len([]byte(string(req.Method) + " " + urStr + " " + rtspProtocol10 + "\r\n")) if len(req.Body) != 0 { req.Header["Content-Length"] = HeaderValue{strconv.FormatInt(int64(len(req.Body)), 10)} } - err = req.Header.write(w) - if err != nil { - return err + n += req.Header.writeSize() + + n += body(req.Body).writeSize() + + return n +} + +// WriteTo writes a Request. +func (req Request) WriteTo(buf []byte) (int, error) { + pos := 0 + + urStr := req.URL.CloneWithoutCredentials().String() + pos += copy(buf[pos:], []byte(string(req.Method)+" "+urStr+" "+rtspProtocol10+"\r\n")) + + if len(req.Body) != 0 { + req.Header["Content-Length"] = HeaderValue{strconv.FormatInt(int64(len(req.Body)), 10)} } - return body(req.Body).write(w) + pos += req.Header.writeTo(buf[pos:]) + + pos += body(req.Body).writeTo(buf[pos:]) + + return pos, nil +} + +// Write writes a Request. +func (req Request) Write() ([]byte, error) { + buf := make([]byte, req.WriteSize()) + _, err := req.WriteTo(buf) + return buf, err } // String implements fmt.Stringer. func (req Request) String() string { - var buf bytes.Buffer - req.Write(&buf) - return buf.String() + buf, _ := req.Write() + return string(buf) } diff --git a/pkg/base/request_test.go b/pkg/base/request_test.go index 673a9777..6e367be5 100644 --- a/pkg/base/request_test.go +++ b/pkg/base/request_test.go @@ -221,9 +221,9 @@ func TestRequestReadErrors(t *testing.T) { func TestRequestWrite(t *testing.T) { for _, ca := range casesRequest { t.Run(ca.name, func(t *testing.T) { - var buf bytes.Buffer - ca.req.Write(&buf) - require.Equal(t, ca.byts, buf.Bytes()) + buf, err := ca.req.Write() + require.NoError(t, err) + require.Equal(t, ca.byts, buf) }) } } diff --git a/pkg/base/response.go b/pkg/base/response.go index e745b08f..02fa3ea8 100644 --- a/pkg/base/response.go +++ b/pkg/base/response.go @@ -2,9 +2,7 @@ package base import ( "bufio" - "bytes" "fmt" - "io" "strconv" ) @@ -203,36 +201,65 @@ func (res *Response) ReadIgnoreFrames(maxPayloadSize int, rb *bufio.Reader) erro } } -// Write writes a Response. -func (res Response) Write(w io.Writer) error { +// WriteSize returns the size of a Response. +func (res Response) WriteSize() int { + n := 0 + if res.StatusMessage == "" { if status, ok := statusMessages[res.StatusCode]; ok { res.StatusMessage = status } } - _, err := w.Write([]byte(rtspProtocol10 + " " + + n += len([]byte(rtspProtocol10 + " " + strconv.FormatInt(int64(res.StatusCode), 10) + " " + res.StatusMessage + "\r\n")) - if err != nil { - return err - } if len(res.Body) != 0 { res.Header["Content-Length"] = HeaderValue{strconv.FormatInt(int64(len(res.Body)), 10)} } - err = res.Header.write(w) - if err != nil { - return err + n += res.Header.writeSize() + + n += body(res.Body).writeSize() + + return n +} + +// WriteTo writes a Response. +func (res Response) WriteTo(buf []byte) (int, error) { + if res.StatusMessage == "" { + if status, ok := statusMessages[res.StatusCode]; ok { + res.StatusMessage = status + } } - return body(res.Body).write(w) + pos := 0 + + pos += copy(buf[pos:], []byte(rtspProtocol10+" "+ + strconv.FormatInt(int64(res.StatusCode), 10)+" "+ + res.StatusMessage+"\r\n")) + + if len(res.Body) != 0 { + res.Header["Content-Length"] = HeaderValue{strconv.FormatInt(int64(len(res.Body)), 10)} + } + + pos += res.Header.writeTo(buf[pos:]) + + pos += body(res.Body).writeTo(buf[pos:]) + + return pos, nil +} + +// Write writes a Response. +func (res Response) Write() ([]byte, error) { + buf := make([]byte, res.WriteSize()) + _, err := res.WriteTo(buf) + return buf, err } // String implements fmt.Stringer. func (res Response) String() string { - var buf bytes.Buffer - res.Write(&buf) - return buf.String() + buf, _ := res.Write() + return string(buf) } diff --git a/pkg/base/response_test.go b/pkg/base/response_test.go index 5926b2de..2b53ef2a 100644 --- a/pkg/base/response_test.go +++ b/pkg/base/response_test.go @@ -178,9 +178,9 @@ func TestResponseReadErrors(t *testing.T) { func TestResponseWrite(t *testing.T) { for _, c := range casesResponse { t.Run(c.name, func(t *testing.T) { - var buf bytes.Buffer - c.res.Write(&buf) - require.Equal(t, c.byts, buf.Bytes()) + buf, err := c.res.Write() + require.NoError(t, err) + require.Equal(t, c.byts, buf) }) } } @@ -207,9 +207,9 @@ func TestResponseWriteAutoFillStatus(t *testing.T) { "\r\n", ) - var buf bytes.Buffer - res.Write(&buf) - require.Equal(t, byts, buf.Bytes()) + buf, err := res.Write() + require.NoError(t, err) + require.Equal(t, byts, buf) } func TestResponseReadIgnoreFrames(t *testing.T) { diff --git a/server_publish_test.go b/server_publish_test.go index bb488ba8..b361dcc2 100644 --- a/server_publish_test.go +++ b/server_publish_test.go @@ -2,7 +2,6 @@ package gortsplib import ( "bufio" - "bytes" "crypto/tls" "net" "testing" @@ -644,7 +643,6 @@ func TestServerPublish(t *testing.T) { return conn }() br := bufio.NewReader(conn) - var bb bytes.Buffer <-connOpened @@ -765,20 +763,18 @@ func TestServerPublish(t *testing.T) { Port: th.ServerPorts[1], }) } else { - bb.Reset() - base.InterleavedFrame{ + byts, _ := base.InterleavedFrame{ Channel: 0, Payload: testRTPPacketMarshaled, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) - bb.Reset() - base.InterleavedFrame{ + byts, _ = base.InterleavedFrame{ Channel: 1, Payload: testRTCPPacketMarshaled, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) } @@ -857,7 +853,6 @@ func TestServerPublishOversizedPacket(t *testing.T) { require.NoError(t, err) defer conn.Close() br := bufio.NewReader(conn) - var bb bytes.Buffer track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) require.NoError(t, err) @@ -917,12 +912,11 @@ func TestServerPublishOversizedPacket(t *testing.T) { require.Equal(t, base.StatusOK, res.StatusCode) byts, _ := oversizedPacketRTPIn.Marshal() - bb.Reset() - base.InterleavedFrame{ + byts, _ = base.InterleavedFrame{ Channel: 0, Payload: byts, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) <-packetRecv @@ -963,7 +957,6 @@ func TestServerPublishErrorInvalidProtocol(t *testing.T) { require.NoError(t, err) defer conn.Close() br := bufio.NewReader(conn) - var bb bytes.Buffer track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) require.NoError(t, err) @@ -1026,12 +1019,11 @@ func TestServerPublishErrorInvalidProtocol(t *testing.T) { require.NoError(t, err) require.Equal(t, base.StatusOK, res.StatusCode) - bb.Reset() - base.InterleavedFrame{ + byts, _ := base.InterleavedFrame{ Channel: 0, Payload: []byte{0x01, 0x02, 0x03, 0x04}, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) } diff --git a/server_read_test.go b/server_read_test.go index 9065e4db..fee7c476 100644 --- a/server_read_test.go +++ b/server_read_test.go @@ -2,7 +2,6 @@ package gortsplib import ( "bufio" - "bytes" "crypto/tls" "net" "strconv" @@ -359,7 +358,6 @@ func TestServerRead(t *testing.T) { return conn }() br := bufio.NewReader(conn) - var bb bytes.Buffer <-connOpened @@ -547,12 +545,11 @@ func TestServerRead(t *testing.T) { <-framesReceived default: - bb.Reset() - base.InterleavedFrame{ + byts, _ := base.InterleavedFrame{ Channel: 5, Payload: testRTCPPacketMarshaled, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) <-framesReceived } @@ -1128,7 +1125,6 @@ func TestServerReadPlayPausePause(t *testing.T) { require.NoError(t, err) defer conn.Close() br := bufio.NewReader(conn) - var bb bytes.Buffer res, err := writeReqReadRes(conn, br, base.Request{ Method: base.Setup, @@ -1167,32 +1163,30 @@ func TestServerReadPlayPausePause(t *testing.T) { require.NoError(t, err) require.Equal(t, base.StatusOK, res.StatusCode) - bb.Reset() - base.Request{ + byts, _ := base.Request{ Method: base.Pause, URL: mustParseURL("rtsp://localhost:8554/teststream"), Header: base.Header{ "CSeq": base.HeaderValue{"2"}, "Session": base.HeaderValue{sx.Session}, }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) res, err = readResIgnoreFrames(br) require.NoError(t, err) require.Equal(t, base.StatusOK, res.StatusCode) - bb.Reset() - base.Request{ + byts, _ = base.Request{ Method: base.Pause, URL: mustParseURL("rtsp://localhost:8554/teststream"), Header: base.Header{ "CSeq": base.HeaderValue{"2"}, "Session": base.HeaderValue{sx.Session}, }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) res, err = readResIgnoreFrames(br) diff --git a/server_test.go b/server_test.go index 6047f561..402d9f8d 100644 --- a/server_test.go +++ b/server_test.go @@ -2,7 +2,6 @@ package gortsplib import ( "bufio" - "bytes" "crypto/tls" "fmt" "net" @@ -24,9 +23,8 @@ func writeReqReadRes(conn net.Conn, br *bufio.Reader, req base.Request, ) (*base.Response, error) { - var bb bytes.Buffer - req.Write(&bb) - _, err := conn.Write(bb.Bytes()) + byts, _ := req.Write() + _, err := conn.Write(byts) if err != nil { return nil, err } @@ -1026,8 +1024,7 @@ func TestServerSessionClose(t *testing.T) { require.NoError(t, err) defer conn.Close() - var bb bytes.Buffer - base.Request{ + byts, _ := base.Request{ Method: base.Setup, URL: mustParseURL("rtsp://localhost:8554/teststream/trackID=0"), Header: base.Header{ @@ -1045,8 +1042,8 @@ func TestServerSessionClose(t *testing.T) { InterleavedIDs: &[2]int{0, 1}, }.Write(), }, - }.Write(&bb) - _, err = conn.Write(bb.Bytes()) + }.Write() + _, err = conn.Write(byts) require.NoError(t, err) <-sessionClosed diff --git a/serverconn.go b/serverconn.go index e2ad3bd8..854fe83b 100644 --- a/serverconn.go +++ b/serverconn.go @@ -2,7 +2,6 @@ package gortsplib import ( "bufio" - "bytes" "context" "crypto/tls" "errors" @@ -589,11 +588,10 @@ func (sc *ServerConn) handleRequestOuter(req *base.Request) error { h.OnResponse(sc, res) } - var buf bytes.Buffer - res.Write(&buf) + byts, _ := res.Write() sc.conn.SetWriteDeadline(time.Now().Add(sc.s.WriteTimeout)) - sc.conn.Write(buf.Bytes()) + sc.conn.Write(byts) return err } diff --git a/serversession.go b/serversession.go index 8ca15d2d..94820173 100644 --- a/serversession.go +++ b/serversession.go @@ -1,7 +1,6 @@ package gortsplib import ( - "bytes" "context" "fmt" "net" @@ -1182,25 +1181,23 @@ func (ss *ServerSession) runWriter() { rtcpFrames[trackID] = &base.InterleavedFrame{Channel: sst.tcpChannel + 1} } - var buf bytes.Buffer + buf := make([]byte, maxPacketSize+4) writeFunc = func(trackID int, isRTP bool, payload []byte) { if isRTP { f := rtpFrames[trackID] f.Payload = payload - buf.Reset() - f.Write(&buf) + n, _ := f.WriteTo(buf) ss.tcpConn.conn.SetWriteDeadline(time.Now().Add(ss.s.WriteTimeout)) - ss.tcpConn.conn.Write(buf.Bytes()) + ss.tcpConn.conn.Write(buf[:n]) } else { f := rtcpFrames[trackID] f.Payload = payload - buf.Reset() - f.Write(&buf) + n, _ := f.WriteTo(buf) ss.tcpConn.conn.SetWriteDeadline(time.Now().Add(ss.s.WriteTimeout)) - ss.tcpConn.conn.Write(buf.Bytes()) + ss.tcpConn.conn.Write(buf[:n]) } } }