1 Star 0 Fork 0

我还是我 / gortsplib

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
client_test.go 11.99 KB
一键复制 编辑 原始数据 按行查看 历史
Alessandro Ros 提交于 2023-11-07 16:51 . move url.URL into base.URL (#459)
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542
package gortsplib
import (
"crypto/tls"
"net"
"strings"
"testing"
"github.com/stretchr/testify/require"
"github.com/bluenviron/gortsplib/v4/pkg/auth"
"github.com/bluenviron/gortsplib/v4/pkg/base"
"github.com/bluenviron/gortsplib/v4/pkg/conn"
"github.com/bluenviron/gortsplib/v4/pkg/description"
)
func mustParseURL(s string) *base.URL {
u, err := base.ParseURL(s)
if err != nil {
panic(err)
}
return u
}
func TestClientURLToAddress(t *testing.T) {
for _, ca := range []struct {
name string
url string
addr string
}{
{
"rtsp ipv6 with port",
"rtsp://[::1]:8888/path",
"[::1]:8888",
},
{
"rtsp ipv6 without port",
"rtsp://[::1]/path",
"[::1]:554",
},
{
"rtsps without port",
"rtsps://2.2.2.2/path",
"2.2.2.2:322",
},
} {
t.Run(ca.name, func(t *testing.T) {
addr := canonicalAddr(mustParseURL(ca.url))
require.Equal(t, ca.addr, addr)
})
}
}
func TestClientTLSSetServerName(t *testing.T) {
l, err := net.Listen("tcp", "localhost:8554")
require.NoError(t, err)
defer l.Close()
serverDone := make(chan struct{})
defer func() { <-serverDone }()
go func() {
defer close(serverDone)
nconn, err := l.Accept()
require.NoError(t, err)
defer nconn.Close()
cert, err := tls.X509KeyPair(serverCert, serverKey)
require.NoError(t, err)
tnconn := tls.Server(nconn, &tls.Config{
Certificates: []tls.Certificate{cert},
InsecureSkipVerify: true,
VerifyConnection: func(cs tls.ConnectionState) error {
require.Equal(t, "localhost", cs.ServerName)
return nil
},
})
err = tnconn.Handshake()
require.EqualError(t, err, "remote error: tls: bad certificate")
}()
u, err := base.ParseURL("rtsps://localhost:8554/stream")
require.NoError(t, err)
c := Client{
TLSConfig: &tls.Config{},
}
err = c.Start(u.Scheme, u.Host)
require.NoError(t, err)
defer c.Close()
_, err = c.Options(u)
require.Error(t, err)
<-serverDone
}
func TestClientClose(t *testing.T) {
u, err := base.ParseURL("rtsp://localhost:8554/teststream")
require.NoError(t, err)
c := Client{}
err = c.Start(u.Scheme, u.Host)
require.NoError(t, err)
c.Close()
_, err = c.Options(u)
require.EqualError(t, err, "terminated")
_, _, err = c.Describe(u)
require.EqualError(t, err, "terminated")
_, err = c.Announce(u, nil)
require.EqualError(t, err, "terminated")
_, err = c.Setup(nil, nil, 0, 0)
require.EqualError(t, err, "terminated")
_, err = c.Play(nil)
require.EqualError(t, err, "terminated")
_, err = c.Record()
require.EqualError(t, err, "terminated")
_, err = c.Pause()
require.EqualError(t, err, "terminated")
}
func TestClientCloseDuringRequest(t *testing.T) {
l, err := net.Listen("tcp", "localhost:8554")
require.NoError(t, err)
defer l.Close()
requestReceived := make(chan struct{})
releaseConn := make(chan struct{})
serverDone := make(chan struct{})
defer func() { <-serverDone }()
go func() {
defer close(serverDone)
nconn, err := l.Accept()
require.NoError(t, err)
defer nconn.Close()
conn := conn.NewConn(nconn)
req, err := conn.ReadRequest()
require.NoError(t, err)
require.Equal(t, base.Options, req.Method)
close(requestReceived)
<-releaseConn
}()
u, err := base.ParseURL("rtsp://localhost:8554/teststream")
require.NoError(t, err)
c := Client{}
err = c.Start(u.Scheme, u.Host)
require.NoError(t, err)
optionsDone := make(chan struct{})
go func() {
defer close(optionsDone)
_, err := c.Options(u)
require.Error(t, err)
}()
<-requestReceived
c.Close()
<-optionsDone
close(releaseConn)
}
func TestClientSession(t *testing.T) {
l, err := net.Listen("tcp", "localhost:8554")
require.NoError(t, err)
defer l.Close()
serverDone := make(chan struct{})
defer func() { <-serverDone }()
go func() {
defer close(serverDone)
nconn, err := l.Accept()
require.NoError(t, err)
conn := conn.NewConn(nconn)
defer nconn.Close()
req, err := conn.ReadRequest()
require.NoError(t, err)
require.Equal(t, base.Options, req.Method)
err = conn.WriteResponse(&base.Response{
StatusCode: base.StatusOK,
Header: base.Header{
"Public": base.HeaderValue{strings.Join([]string{
string(base.Describe),
}, ", ")},
"Session": base.HeaderValue{"123456"},
},
})
require.NoError(t, err)
req, err = conn.ReadRequest()
require.NoError(t, err)
require.Equal(t, base.Describe, req.Method)
require.Equal(t, base.HeaderValue{"123456"}, req.Header["Session"])
medias := []*description.Media{testH264Media}
err = conn.WriteResponse(&base.Response{
StatusCode: base.StatusOK,
Header: base.Header{
"Content-Type": base.HeaderValue{"application/sdp"},
"Session": base.HeaderValue{"123456"},
},
Body: mediasToSDP(medias),
})
require.NoError(t, err)
}()
u, err := base.ParseURL("rtsp://localhost:8554/stream")
require.NoError(t, err)
c := Client{}
err = c.Start(u.Scheme, u.Host)
require.NoError(t, err)
defer c.Close()
_, _, err = c.Describe(u)
require.NoError(t, err)
}
func TestClientAuth(t *testing.T) {
l, err := net.Listen("tcp", "localhost:8554")
require.NoError(t, err)
defer l.Close()
serverDone := make(chan struct{})
defer func() { <-serverDone }()
go func() {
defer close(serverDone)
nconn, err := l.Accept()
require.NoError(t, err)
conn := conn.NewConn(nconn)
defer nconn.Close()
req, err := conn.ReadRequest()
require.NoError(t, err)
require.Equal(t, base.Options, req.Method)
err = conn.WriteResponse(&base.Response{
StatusCode: base.StatusOK,
Header: base.Header{
"Public": base.HeaderValue{strings.Join([]string{
string(base.Describe),
}, ", ")},
},
})
require.NoError(t, err)
req, err = conn.ReadRequest()
require.NoError(t, err)
require.Equal(t, base.Describe, req.Method)
nonce, err := auth.GenerateNonce()
require.NoError(t, err)
err = conn.WriteResponse(&base.Response{
StatusCode: base.StatusUnauthorized,
Header: base.Header{
"WWW-Authenticate": auth.GenerateWWWAuthenticate(nil, "IPCAM", nonce),
},
})
require.NoError(t, err)
req, err = conn.ReadRequest()
require.NoError(t, err)
require.Equal(t, base.Describe, req.Method)
err = auth.Validate(req, "myuser", "mypass", nil, nil, "IPCAM", nonce)
require.NoError(t, err)
medias := []*description.Media{testH264Media}
err = conn.WriteResponse(&base.Response{
StatusCode: base.StatusOK,
Header: base.Header{
"Content-Type": base.HeaderValue{"application/sdp"},
},
Body: mediasToSDP(medias),
})
require.NoError(t, err)
}()
u, err := base.ParseURL("rtsp://myuser:mypass@localhost:8554/stream")
require.NoError(t, err)
c := Client{}
err = c.Start(u.Scheme, u.Host)
require.NoError(t, err)
defer c.Close()
_, _, err = c.Describe(u)
require.NoError(t, err)
}
func TestClientCSeq(t *testing.T) {
for _, ca := range []string{
"different cseq",
"space at the end",
} {
t.Run(ca, func(t *testing.T) {
l, err := net.Listen("tcp", "localhost:8554")
require.NoError(t, err)
defer l.Close()
serverDone := make(chan struct{})
defer func() { <-serverDone }()
go func() {
defer close(serverDone)
nconn, err := l.Accept()
require.NoError(t, err)
defer nconn.Close()
conn := conn.NewConn(nconn)
req, err := conn.ReadRequest()
require.NoError(t, err)
require.Equal(t, base.Options, req.Method)
switch ca {
case "different cseq":
err = conn.WriteResponse(&base.Response{
StatusCode: base.StatusOK,
Header: base.Header{
"Public": base.HeaderValue{strings.Join([]string{
string(base.Describe),
}, ", ")},
"CSeq": base.HeaderValue{"150"},
},
})
require.NoError(t, err)
err = conn.WriteResponse(&base.Response{
StatusCode: base.StatusOK,
Header: base.Header{
"Public": base.HeaderValue{strings.Join([]string{
string(base.Describe),
}, ", ")},
"CSeq": req.Header["CSeq"],
},
})
require.NoError(t, err)
case "space at the end":
err = conn.WriteResponse(&base.Response{
StatusCode: base.StatusOK,
Header: base.Header{
"Public": base.HeaderValue{strings.Join([]string{
string(base.Describe),
}, ", ")},
"CSeq": base.HeaderValue{req.Header["CSeq"][0] + " "},
},
})
require.NoError(t, err)
}
}()
u, err := base.ParseURL("rtsp://localhost:8554/teststream")
require.NoError(t, err)
c := Client{}
err = c.Start(u.Scheme, u.Host)
require.NoError(t, err)
defer c.Close()
_, err = c.Options(u)
require.NoError(t, err)
})
}
}
func TestClientDescribeCharset(t *testing.T) {
l, err := net.Listen("tcp", "localhost:8554")
require.NoError(t, err)
defer l.Close()
serverDone := make(chan struct{})
defer func() { <-serverDone }()
go func() {
defer close(serverDone)
nconn, err := l.Accept()
require.NoError(t, err)
defer nconn.Close()
conn := conn.NewConn(nconn)
req, err := conn.ReadRequest()
require.NoError(t, err)
require.Equal(t, base.Options, req.Method)
err = conn.WriteResponse(&base.Response{
StatusCode: base.StatusOK,
Header: base.Header{
"Public": base.HeaderValue{strings.Join([]string{
string(base.Describe),
}, ", ")},
},
})
require.NoError(t, err)
req, err = conn.ReadRequest()
require.NoError(t, err)
require.Equal(t, base.Describe, req.Method)
require.Equal(t, mustParseURL("rtsp://localhost:8554/teststream"), req.URL)
medias := []*description.Media{testH264Media}
err = conn.WriteResponse(&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: mediasToSDP(medias),
})
require.NoError(t, err)
}()
u, err := base.ParseURL("rtsp://localhost:8554/teststream")
require.NoError(t, err)
c := Client{}
err = c.Start(u.Scheme, u.Host)
require.NoError(t, err)
defer c.Close()
_, _, err = c.Describe(u)
require.NoError(t, err)
}
func TestClientReplyToServerRequest(t *testing.T) {
for _, ca := range []string{"after response", "before response"} {
t.Run(ca, func(t *testing.T) {
l, err := net.Listen("tcp", "localhost:8554")
require.NoError(t, err)
defer l.Close()
serverDone := make(chan struct{})
go func() {
defer close(serverDone)
nconn, err := l.Accept()
require.NoError(t, err)
conn := conn.NewConn(nconn)
defer nconn.Close()
req, err := conn.ReadRequest()
require.NoError(t, err)
require.Equal(t, base.Options, req.Method)
if ca == "after response" {
err = conn.WriteResponse(&base.Response{
StatusCode: base.StatusOK,
Header: base.Header{
"Public": base.HeaderValue{strings.Join([]string{
string(base.Describe),
}, ", ")},
},
})
require.NoError(t, err)
err = conn.WriteRequest(&base.Request{
Method: base.Options,
URL: nil,
Header: base.Header{
"CSeq": base.HeaderValue{"4"},
},
})
require.NoError(t, err)
res, err := conn.ReadResponse()
require.NoError(t, err)
require.Equal(t, base.StatusOK, res.StatusCode)
require.Equal(t, "4", res.Header["CSeq"][0])
} else {
err = conn.WriteRequest(&base.Request{
Method: base.Options,
URL: nil,
Header: base.Header{
"CSeq": base.HeaderValue{"4"},
},
})
require.NoError(t, err)
res, err := conn.ReadResponse()
require.NoError(t, err)
require.Equal(t, base.StatusOK, res.StatusCode)
require.Equal(t, "4", res.Header["CSeq"][0])
err = conn.WriteResponse(&base.Response{
StatusCode: base.StatusOK,
Header: base.Header{
"Public": base.HeaderValue{strings.Join([]string{
string(base.Describe),
}, ", ")},
},
})
require.NoError(t, err)
}
}()
u, err := base.ParseURL("rtsp://localhost:8554/stream")
require.NoError(t, err)
c := Client{}
err = c.Start(u.Scheme, u.Host)
require.NoError(t, err)
defer c.Close()
_, err = c.Options(u)
require.NoError(t, err)
<-serverDone
})
}
}
Go
1
https://gitee.com/likunde_admin/gortsplib.git
git@gitee.com:likunde_admin/gortsplib.git
likunde_admin
gortsplib
gortsplib
main

搜索帮助

53164aa7 5694891 3bd8fe86 5694891