mirror of
https://github.com/aler9/gortsplib
synced 2025-10-05 15:16:51 +08:00
move URL into dedicated folder
This commit is contained in:
45
client.go
45
client.go
@@ -32,16 +32,17 @@ import (
|
|||||||
"github.com/aler9/gortsplib/pkg/rtcpsender"
|
"github.com/aler9/gortsplib/pkg/rtcpsender"
|
||||||
"github.com/aler9/gortsplib/pkg/rtph264"
|
"github.com/aler9/gortsplib/pkg/rtph264"
|
||||||
"github.com/aler9/gortsplib/pkg/sdp"
|
"github.com/aler9/gortsplib/pkg/sdp"
|
||||||
|
"github.com/aler9/gortsplib/pkg/url"
|
||||||
)
|
)
|
||||||
|
|
||||||
func isAnyPort(p int) bool {
|
func isAnyPort(p int) bool {
|
||||||
return p == 0 || p == 1
|
return p == 0 || p == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func findBaseURL(sd *sdp.SessionDescription, res *base.Response, u *base.URL) (*base.URL, error) {
|
func findBaseURL(sd *sdp.SessionDescription, res *base.Response, u *url.URL) (*url.URL, error) {
|
||||||
// use global control attribute
|
// use global control attribute
|
||||||
if control, ok := sd.Attribute("control"); ok && control != "*" {
|
if control, ok := sd.Attribute("control"); ok && control != "*" {
|
||||||
ret, err := base.ParseURL(control)
|
ret, err := url.Parse(control)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("invalid control attribute: '%v'", control)
|
return nil, fmt.Errorf("invalid control attribute: '%v'", control)
|
||||||
}
|
}
|
||||||
@@ -58,7 +59,7 @@ func findBaseURL(sd *sdp.SessionDescription, res *base.Response, u *base.URL) (*
|
|||||||
return nil, fmt.Errorf("invalid Content-Base: '%v'", cb)
|
return nil, fmt.Errorf("invalid Content-Base: '%v'", cb)
|
||||||
}
|
}
|
||||||
|
|
||||||
ret, err := base.ParseURL(cb[0])
|
ret, err := url.Parse(cb[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("invalid Content-Base: '%v'", cb)
|
return nil, fmt.Errorf("invalid Content-Base: '%v'", cb)
|
||||||
}
|
}
|
||||||
@@ -111,17 +112,17 @@ func (s clientState) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type optionsReq struct {
|
type optionsReq struct {
|
||||||
url *base.URL
|
url *url.URL
|
||||||
res chan clientRes
|
res chan clientRes
|
||||||
}
|
}
|
||||||
|
|
||||||
type describeReq struct {
|
type describeReq struct {
|
||||||
url *base.URL
|
url *url.URL
|
||||||
res chan clientRes
|
res chan clientRes
|
||||||
}
|
}
|
||||||
|
|
||||||
type announceReq struct {
|
type announceReq struct {
|
||||||
url *base.URL
|
url *url.URL
|
||||||
tracks Tracks
|
tracks Tracks
|
||||||
res chan clientRes
|
res chan clientRes
|
||||||
}
|
}
|
||||||
@@ -129,7 +130,7 @@ type announceReq struct {
|
|||||||
type setupReq struct {
|
type setupReq struct {
|
||||||
forPlay bool
|
forPlay bool
|
||||||
track Track
|
track Track
|
||||||
baseURL *base.URL
|
baseURL *url.URL
|
||||||
rtpPort int
|
rtpPort int
|
||||||
rtcpPort int
|
rtcpPort int
|
||||||
res chan clientRes
|
res chan clientRes
|
||||||
@@ -150,7 +151,7 @@ type pauseReq struct {
|
|||||||
|
|
||||||
type clientRes struct {
|
type clientRes struct {
|
||||||
tracks Tracks
|
tracks Tracks
|
||||||
baseURL *base.URL
|
baseURL *url.URL
|
||||||
res *base.Response
|
res *base.Response
|
||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
@@ -256,8 +257,8 @@ type Client struct {
|
|||||||
cseq int
|
cseq int
|
||||||
optionsSent bool
|
optionsSent bool
|
||||||
useGetParameter bool
|
useGetParameter bool
|
||||||
lastDescribeURL *base.URL
|
lastDescribeURL *url.URL
|
||||||
baseURL *base.URL
|
baseURL *url.URL
|
||||||
effectiveTransport *Transport
|
effectiveTransport *Transport
|
||||||
tracks []*clientTrack
|
tracks []*clientTrack
|
||||||
tcpTracksByChannel map[int]int
|
tcpTracksByChannel map[int]int
|
||||||
@@ -373,7 +374,7 @@ func (c *Client) Start(scheme string, host string) error {
|
|||||||
|
|
||||||
// StartReading connects to the address and starts reading all tracks.
|
// StartReading connects to the address and starts reading all tracks.
|
||||||
func (c *Client) StartReading(address string) error {
|
func (c *Client) StartReading(address string) error {
|
||||||
u, err := base.ParseURL(address)
|
u, err := url.Parse(address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -405,7 +406,7 @@ func (c *Client) StartReadingAndWait(address string) error {
|
|||||||
|
|
||||||
// StartPublishing connects to the address and starts publishing the tracks.
|
// StartPublishing connects to the address and starts publishing the tracks.
|
||||||
func (c *Client) StartPublishing(address string, tracks Tracks) error {
|
func (c *Client) StartPublishing(address string, tracks Tracks) error {
|
||||||
u, err := base.ParseURL(address)
|
u, err := url.Parse(address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -1159,7 +1160,7 @@ func (c *Client) do(req *base.Request, skipResponse bool, allowFrames bool) (*ba
|
|||||||
return &res, nil
|
return &res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) doOptions(u *base.URL) (*base.Response, error) {
|
func (c *Client) doOptions(u *url.URL) (*base.Response, error) {
|
||||||
err := c.checkState(map[clientState]struct{}{
|
err := c.checkState(map[clientState]struct{}{
|
||||||
clientStateInitial: {},
|
clientStateInitial: {},
|
||||||
clientStatePrePlay: {},
|
clientStatePrePlay: {},
|
||||||
@@ -1206,7 +1207,7 @@ func (c *Client) doOptions(u *base.URL) (*base.Response, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Options writes an OPTIONS request and reads a response.
|
// Options writes an OPTIONS request and reads a response.
|
||||||
func (c *Client) Options(u *base.URL) (*base.Response, error) {
|
func (c *Client) Options(u *url.URL) (*base.Response, error) {
|
||||||
cres := make(chan clientRes)
|
cres := make(chan clientRes)
|
||||||
select {
|
select {
|
||||||
case c.options <- optionsReq{url: u, res: cres}:
|
case c.options <- optionsReq{url: u, res: cres}:
|
||||||
@@ -1218,7 +1219,7 @@ func (c *Client) Options(u *base.URL) (*base.Response, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) doDescribe(u *base.URL) (Tracks, *base.URL, *base.Response, error) {
|
func (c *Client) doDescribe(u *url.URL) (Tracks, *url.URL, *base.Response, error) {
|
||||||
err := c.checkState(map[clientState]struct{}{
|
err := c.checkState(map[clientState]struct{}{
|
||||||
clientStateInitial: {},
|
clientStateInitial: {},
|
||||||
clientStatePrePlay: {},
|
clientStatePrePlay: {},
|
||||||
@@ -1247,7 +1248,7 @@ func (c *Client) doDescribe(u *base.URL) (Tracks, *base.URL, *base.Response, err
|
|||||||
len(res.Header["Location"]) == 1 {
|
len(res.Header["Location"]) == 1 {
|
||||||
c.reset()
|
c.reset()
|
||||||
|
|
||||||
ru, err := base.ParseURL(res.Header["Location"][0])
|
ru, err := url.Parse(res.Header["Location"][0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
@@ -1293,7 +1294,7 @@ func (c *Client) doDescribe(u *base.URL) (Tracks, *base.URL, *base.Response, err
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Describe writes a DESCRIBE request and reads a Response.
|
// Describe writes a DESCRIBE request and reads a Response.
|
||||||
func (c *Client) Describe(u *base.URL) (Tracks, *base.URL, *base.Response, error) {
|
func (c *Client) Describe(u *url.URL) (Tracks, *url.URL, *base.Response, error) {
|
||||||
cres := make(chan clientRes)
|
cres := make(chan clientRes)
|
||||||
select {
|
select {
|
||||||
case c.describe <- describeReq{url: u, res: cres}:
|
case c.describe <- describeReq{url: u, res: cres}:
|
||||||
@@ -1305,7 +1306,7 @@ func (c *Client) Describe(u *base.URL) (Tracks, *base.URL, *base.Response, error
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) doAnnounce(u *base.URL, tracks Tracks) (*base.Response, error) {
|
func (c *Client) doAnnounce(u *url.URL, tracks Tracks) (*base.Response, error) {
|
||||||
err := c.checkState(map[clientState]struct{}{
|
err := c.checkState(map[clientState]struct{}{
|
||||||
clientStateInitial: {},
|
clientStateInitial: {},
|
||||||
})
|
})
|
||||||
@@ -1340,7 +1341,7 @@ func (c *Client) doAnnounce(u *base.URL, tracks Tracks) (*base.Response, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Announce writes an ANNOUNCE request and reads a Response.
|
// Announce writes an ANNOUNCE request and reads a Response.
|
||||||
func (c *Client) Announce(u *base.URL, tracks Tracks) (*base.Response, error) {
|
func (c *Client) Announce(u *url.URL, tracks Tracks) (*base.Response, error) {
|
||||||
cres := make(chan clientRes)
|
cres := make(chan clientRes)
|
||||||
select {
|
select {
|
||||||
case c.announce <- announceReq{url: u, tracks: tracks, res: cres}:
|
case c.announce <- announceReq{url: u, tracks: tracks, res: cres}:
|
||||||
@@ -1355,7 +1356,7 @@ func (c *Client) Announce(u *base.URL, tracks Tracks) (*base.Response, error) {
|
|||||||
func (c *Client) doSetup(
|
func (c *Client) doSetup(
|
||||||
forPlay bool,
|
forPlay bool,
|
||||||
track Track,
|
track Track,
|
||||||
baseURL *base.URL,
|
baseURL *url.URL,
|
||||||
rtpPort int,
|
rtpPort int,
|
||||||
rtcpPort int,
|
rtcpPort int,
|
||||||
) (*base.Response, error) {
|
) (*base.Response, error) {
|
||||||
@@ -1667,7 +1668,7 @@ func (c *Client) doSetup(
|
|||||||
func (c *Client) Setup(
|
func (c *Client) Setup(
|
||||||
forPlay bool,
|
forPlay bool,
|
||||||
track Track,
|
track Track,
|
||||||
baseURL *base.URL,
|
baseURL *url.URL,
|
||||||
rtpPort int,
|
rtpPort int,
|
||||||
rtcpPort int,
|
rtcpPort int,
|
||||||
) (*base.Response, error) {
|
) (*base.Response, error) {
|
||||||
@@ -1757,7 +1758,7 @@ func (c *Client) Play(ra *headers.Range) (*base.Response, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetupAndPlay setups and play the given tracks.
|
// SetupAndPlay setups and play the given tracks.
|
||||||
func (c *Client) SetupAndPlay(tracks Tracks, baseURL *base.URL) error {
|
func (c *Client) SetupAndPlay(tracks Tracks, baseURL *url.URL) error {
|
||||||
for _, t := range tracks {
|
for _, t := range tracks {
|
||||||
_, err := c.Setup(true, t, baseURL, 0, 0)
|
_, err := c.Setup(true, t, baseURL, 0, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@@ -19,6 +19,7 @@ import (
|
|||||||
"github.com/aler9/gortsplib/pkg/auth"
|
"github.com/aler9/gortsplib/pkg/auth"
|
||||||
"github.com/aler9/gortsplib/pkg/base"
|
"github.com/aler9/gortsplib/pkg/base"
|
||||||
"github.com/aler9/gortsplib/pkg/headers"
|
"github.com/aler9/gortsplib/pkg/headers"
|
||||||
|
"github.com/aler9/gortsplib/pkg/url"
|
||||||
)
|
)
|
||||||
|
|
||||||
func mergeBytes(vals ...[]byte) []byte {
|
func mergeBytes(vals ...[]byte) []byte {
|
||||||
@@ -749,7 +750,7 @@ func TestClientReadPartial(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
u, err := base.ParseURL("rtsp://" + listenIP + ":8554/teststream")
|
u, err := url.Parse("rtsp://" + listenIP + ":8554/teststream")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = c.Start(u.Scheme, u.Host)
|
err = c.Start(u.Scheme, u.Host)
|
||||||
@@ -2610,7 +2611,7 @@ func TestClientReadSeek(t *testing.T) {
|
|||||||
}(),
|
}(),
|
||||||
}
|
}
|
||||||
|
|
||||||
u, err := base.ParseURL("rtsp://localhost:8554/teststream")
|
u, err := url.Parse("rtsp://localhost:8554/teststream")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = c.Start(u.Scheme, u.Host)
|
err = c.Start(u.Scheme, u.Host)
|
||||||
|
@@ -11,10 +11,11 @@ import (
|
|||||||
|
|
||||||
"github.com/aler9/gortsplib/pkg/auth"
|
"github.com/aler9/gortsplib/pkg/auth"
|
||||||
"github.com/aler9/gortsplib/pkg/base"
|
"github.com/aler9/gortsplib/pkg/base"
|
||||||
|
"github.com/aler9/gortsplib/pkg/url"
|
||||||
)
|
)
|
||||||
|
|
||||||
func mustParseURL(s string) *base.URL {
|
func mustParseURL(s string) *url.URL {
|
||||||
u, err := base.ParseURL(s)
|
u, err := url.Parse(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@@ -63,7 +64,7 @@ func TestClientTLSSetServerName(t *testing.T) {
|
|||||||
require.EqualError(t, err, "remote error: tls: bad certificate")
|
require.EqualError(t, err, "remote error: tls: bad certificate")
|
||||||
}()
|
}()
|
||||||
|
|
||||||
u, err := base.ParseURL("rtsps://localhost:8554/stream")
|
u, err := url.Parse("rtsps://localhost:8554/stream")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
c := Client{
|
c := Client{
|
||||||
@@ -135,7 +136,7 @@ func TestClientSession(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
u, err := base.ParseURL("rtsp://localhost:8554/stream")
|
u, err := url.Parse("rtsp://localhost:8554/stream")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
c := Client{}
|
c := Client{}
|
||||||
@@ -217,7 +218,7 @@ func TestClientAuth(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
u, err := base.ParseURL("rtsp://myuser:mypass@localhost:8554/stream")
|
u, err := url.Parse("rtsp://myuser:mypass@localhost:8554/stream")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
c := Client{}
|
c := Client{}
|
||||||
@@ -280,7 +281,7 @@ func TestClientDescribeCharset(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
u, err := base.ParseURL("rtsp://localhost:8554/teststream")
|
u, err := url.Parse("rtsp://localhost:8554/teststream")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
c := Client{}
|
c := Client{}
|
||||||
@@ -294,7 +295,7 @@ func TestClientDescribeCharset(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestClientClose(t *testing.T) {
|
func TestClientClose(t *testing.T) {
|
||||||
u, err := base.ParseURL("rtsp://localhost:8554/teststream")
|
u, err := url.Parse("rtsp://localhost:8554/teststream")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
c := Client{}
|
c := Client{}
|
||||||
@@ -352,7 +353,7 @@ func TestClientCloseDuringRequest(t *testing.T) {
|
|||||||
<-releaseConn
|
<-releaseConn
|
||||||
}()
|
}()
|
||||||
|
|
||||||
u, err := base.ParseURL("rtsp://localhost:8554/teststream")
|
u, err := url.Parse("rtsp://localhost:8554/teststream")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
c := Client{}
|
c := Client{}
|
||||||
|
@@ -4,7 +4,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/aler9/gortsplib"
|
"github.com/aler9/gortsplib"
|
||||||
"github.com/aler9/gortsplib/pkg/base"
|
"github.com/aler9/gortsplib/pkg/url"
|
||||||
)
|
)
|
||||||
|
|
||||||
// This example shows how to
|
// This example shows how to
|
||||||
@@ -14,7 +14,7 @@ import (
|
|||||||
func main() {
|
func main() {
|
||||||
c := gortsplib.Client{}
|
c := gortsplib.Client{}
|
||||||
|
|
||||||
u, err := base.ParseURL("rtsp://localhost:8554/mypath")
|
u, err := url.Parse("rtsp://localhost:8554/mypath")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@@ -4,8 +4,8 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/aler9/gortsplib"
|
"github.com/aler9/gortsplib"
|
||||||
"github.com/aler9/gortsplib/pkg/base"
|
|
||||||
"github.com/aler9/gortsplib/pkg/rtpaac"
|
"github.com/aler9/gortsplib/pkg/rtpaac"
|
||||||
|
"github.com/aler9/gortsplib/pkg/url"
|
||||||
)
|
)
|
||||||
|
|
||||||
// This example shows how to
|
// This example shows how to
|
||||||
@@ -17,7 +17,7 @@ func main() {
|
|||||||
c := gortsplib.Client{}
|
c := gortsplib.Client{}
|
||||||
|
|
||||||
// parse URL
|
// parse URL
|
||||||
u, err := base.ParseURL("rtsp://localhost:8554/mystream")
|
u, err := url.Parse("rtsp://localhost:8554/mystream")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@@ -9,7 +9,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/aler9/gortsplib"
|
"github.com/aler9/gortsplib"
|
||||||
"github.com/aler9/gortsplib/pkg/base"
|
"github.com/aler9/gortsplib/pkg/url"
|
||||||
)
|
)
|
||||||
|
|
||||||
// This example shows how to
|
// This example shows how to
|
||||||
@@ -42,7 +42,7 @@ func main() {
|
|||||||
c := gortsplib.Client{}
|
c := gortsplib.Client{}
|
||||||
|
|
||||||
// parse URL
|
// parse URL
|
||||||
u, err := base.ParseURL("rtsp://localhost:8554/mystream")
|
u, err := url.Parse("rtsp://localhost:8554/mystream")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/aler9/gortsplib"
|
"github.com/aler9/gortsplib"
|
||||||
"github.com/aler9/gortsplib/pkg/base"
|
"github.com/aler9/gortsplib/pkg/url"
|
||||||
)
|
)
|
||||||
|
|
||||||
// This example shows how to
|
// This example shows how to
|
||||||
@@ -14,7 +14,7 @@ func main() {
|
|||||||
c := gortsplib.Client{}
|
c := gortsplib.Client{}
|
||||||
|
|
||||||
// parse URL
|
// parse URL
|
||||||
u, err := base.ParseURL("rtsp://localhost:8554/mystream")
|
u, err := url.Parse("rtsp://localhost:8554/mystream")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@@ -4,7 +4,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/aler9/gortsplib"
|
"github.com/aler9/gortsplib"
|
||||||
"github.com/aler9/gortsplib/pkg/base"
|
"github.com/aler9/gortsplib/pkg/url"
|
||||||
)
|
)
|
||||||
|
|
||||||
// This example shows how to
|
// This example shows how to
|
||||||
@@ -19,7 +19,7 @@ func main() {
|
|||||||
c := gortsplib.Client{}
|
c := gortsplib.Client{}
|
||||||
|
|
||||||
// parse URL
|
// parse URL
|
||||||
u, err := base.ParseURL("rtsp://localhost:8554/mystream")
|
u, err := url.Parse("rtsp://localhost:8554/mystream")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@@ -4,7 +4,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/aler9/gortsplib"
|
"github.com/aler9/gortsplib"
|
||||||
"github.com/aler9/gortsplib/pkg/base"
|
"github.com/aler9/gortsplib/pkg/url"
|
||||||
)
|
)
|
||||||
|
|
||||||
// This example shows how to
|
// This example shows how to
|
||||||
@@ -24,7 +24,7 @@ func main() {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
u, err := base.ParseURL("rtsp://myserver/mypath")
|
u, err := url.Parse("rtsp://myserver/mypath")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@@ -4,7 +4,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/aler9/gortsplib"
|
"github.com/aler9/gortsplib"
|
||||||
"github.com/aler9/gortsplib/pkg/base"
|
"github.com/aler9/gortsplib/pkg/url"
|
||||||
)
|
)
|
||||||
|
|
||||||
// This example shows how to
|
// This example shows how to
|
||||||
@@ -15,7 +15,7 @@ func main() {
|
|||||||
reader := gortsplib.Client{}
|
reader := gortsplib.Client{}
|
||||||
|
|
||||||
// parse source URL
|
// parse source URL
|
||||||
sourceURL, err := base.ParseURL("rtsp://localhost:8554/mystream")
|
sourceURL, err := url.Parse("rtsp://localhost:8554/mystream")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@@ -7,10 +7,11 @@ import (
|
|||||||
|
|
||||||
"github.com/aler9/gortsplib/pkg/base"
|
"github.com/aler9/gortsplib/pkg/base"
|
||||||
"github.com/aler9/gortsplib/pkg/headers"
|
"github.com/aler9/gortsplib/pkg/headers"
|
||||||
|
"github.com/aler9/gortsplib/pkg/url"
|
||||||
)
|
)
|
||||||
|
|
||||||
func mustParseURL(s string) *base.URL {
|
func mustParseURL(s string) *url.URL {
|
||||||
u, err := base.ParseURL(s)
|
u, err := url.Parse(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@@ -8,6 +8,7 @@ import (
|
|||||||
|
|
||||||
"github.com/aler9/gortsplib/pkg/base"
|
"github.com/aler9/gortsplib/pkg/base"
|
||||||
"github.com/aler9/gortsplib/pkg/headers"
|
"github.com/aler9/gortsplib/pkg/headers"
|
||||||
|
"github.com/aler9/gortsplib/pkg/url"
|
||||||
)
|
)
|
||||||
|
|
||||||
func stringsReverseIndex(s, substr string) int {
|
func stringsReverseIndex(s, substr string) int {
|
||||||
@@ -19,7 +20,7 @@ func stringsReverseIndex(s, substr string) int {
|
|||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateAltURL(req *base.Request) (*base.URL, bool) {
|
func generateAltURL(req *base.Request) (*url.URL, bool) {
|
||||||
if req.Method != base.Setup {
|
if req.Method != base.Setup {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
@@ -34,7 +35,7 @@ func generateAltURL(req *base.Request) (*base.URL, bool) {
|
|||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
ur, _ := base.ParseURL(req.URL.Scheme + "://" + req.URL.Host + "/" + pathAndQuery[:i+1])
|
ur, _ := url.Parse(req.URL.Scheme + "://" + req.URL.Host + "/" + pathAndQuery[:i+1])
|
||||||
return ur, true
|
return ur, true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -7,6 +7,10 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
rtspMaxContentLength = 128 * 1024
|
||||||
|
)
|
||||||
|
|
||||||
type body []byte
|
type body []byte
|
||||||
|
|
||||||
func (b *body) read(header Header, rb *bufio.Reader) error {
|
func (b *body) read(header Header, rb *bufio.Reader) error {
|
||||||
|
@@ -5,6 +5,8 @@ import (
|
|||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/aler9/gortsplib/pkg/url"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -37,7 +39,7 @@ type Request struct {
|
|||||||
Method Method
|
Method Method
|
||||||
|
|
||||||
// request url
|
// request url
|
||||||
URL *URL
|
URL *url.URL
|
||||||
|
|
||||||
// map of header values
|
// map of header values
|
||||||
Header Header
|
Header Header
|
||||||
@@ -64,7 +66,7 @@ func (req *Request) Read(rb *bufio.Reader) error {
|
|||||||
}
|
}
|
||||||
rawURL := string(byts[:len(byts)-1])
|
rawURL := string(byts[:len(byts)-1])
|
||||||
|
|
||||||
ur, err := ParseURL(rawURL)
|
ur, err := url.Parse(rawURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("invalid URL (%v)", rawURL)
|
return fmt.Errorf("invalid URL (%v)", rawURL)
|
||||||
}
|
}
|
||||||
|
@@ -6,8 +6,18 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/aler9/gortsplib/pkg/url"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func mustParseURL(s string) *url.URL {
|
||||||
|
u, err := url.Parse(s)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
var casesRequest = []struct {
|
var casesRequest = []struct {
|
||||||
name string
|
name string
|
||||||
byts []byte
|
byts []byte
|
||||||
|
@@ -5,10 +5,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
rtspMaxContentLength = 128 * 1024
|
|
||||||
)
|
|
||||||
|
|
||||||
func readByteEqual(rb *bufio.Reader, cmp byte) error {
|
func readByteEqual(rb *bufio.Reader, cmp byte) error {
|
||||||
byt, err := rb.ReadByte()
|
byt, err := rb.ReadByte()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
package base
|
package url
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
@@ -1,4 +1,4 @@
|
|||||||
package base
|
package url
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
@@ -1,4 +1,5 @@
|
|||||||
package base
|
// Package url contains the URL structure.
|
||||||
|
package url
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -14,8 +15,8 @@ type URL url.URL
|
|||||||
|
|
||||||
var escapeRegexp = regexp.MustCompile(`^(.+?)://(.*?)@(.*?)/(.*?)$`)
|
var escapeRegexp = regexp.MustCompile(`^(.+?)://(.*?)@(.*?)/(.*?)$`)
|
||||||
|
|
||||||
// ParseURL parses a RTSP URL.
|
// Parse parses a RTSP URL.
|
||||||
func ParseURL(s string) (*URL, error) {
|
func Parse(s string) (*URL, error) {
|
||||||
// https://github.com/golang/go/issues/30611
|
// https://github.com/golang/go/issues/30611
|
||||||
m := escapeRegexp.FindStringSubmatch(s)
|
m := escapeRegexp.FindStringSubmatch(s)
|
||||||
if m != nil {
|
if m != nil {
|
@@ -1,4 +1,4 @@
|
|||||||
package base
|
package url
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/url"
|
"net/url"
|
||||||
@@ -7,8 +7,8 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func mustParseURL(s string) *URL {
|
func mustParse(s string) *URL {
|
||||||
u, err := ParseURL(s)
|
u, err := Parse(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@@ -33,7 +33,7 @@ func TestURLParse(t *testing.T) {
|
|||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
t.Run(ca.name, func(t *testing.T) {
|
t.Run(ca.name, func(t *testing.T) {
|
||||||
u, err := ParseURL(ca.enc)
|
u, err := Parse(ca.enc)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, ca.u, u)
|
require.Equal(t, ca.u, u)
|
||||||
})
|
})
|
||||||
@@ -68,14 +68,14 @@ func TestURLParseErrors(t *testing.T) {
|
|||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
t.Run(ca.name, func(t *testing.T) {
|
t.Run(ca.name, func(t *testing.T) {
|
||||||
_, err := ParseURL(ca.enc)
|
_, err := Parse(ca.enc)
|
||||||
require.EqualError(t, err, ca.err)
|
require.EqualError(t, err, ca.err)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestURLClone(t *testing.T) {
|
func TestURLClone(t *testing.T) {
|
||||||
u := mustParseURL("rtsp://localhost:8554/test/stream")
|
u := mustParse("rtsp://localhost:8554/test/stream")
|
||||||
u2 := u.Clone()
|
u2 := u.Clone()
|
||||||
u.Host = "otherhost"
|
u.Host = "otherhost"
|
||||||
|
|
||||||
@@ -98,23 +98,23 @@ func TestURLRTSPPathAndQuery(t *testing.T) {
|
|||||||
b string
|
b string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
mustParseURL("rtsp://localhost:8554/teststream/trackID=1"),
|
mustParse("rtsp://localhost:8554/teststream/trackID=1"),
|
||||||
"teststream/trackID=1",
|
"teststream/trackID=1",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
mustParseURL("rtsp://localhost:8554/test/stream/trackID=1"),
|
mustParse("rtsp://localhost:8554/test/stream/trackID=1"),
|
||||||
"test/stream/trackID=1",
|
"test/stream/trackID=1",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
mustParseURL("rtsp://192.168.1.99:554/test?user=tmp&password=BagRep1&channel=1&stream=0.sdp/trackID=1"),
|
mustParse("rtsp://192.168.1.99:554/test?user=tmp&password=BagRep1&channel=1&stream=0.sdp/trackID=1"),
|
||||||
"test?user=tmp&password=BagRep1&channel=1&stream=0.sdp/trackID=1",
|
"test?user=tmp&password=BagRep1&channel=1&stream=0.sdp/trackID=1",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
mustParseURL("rtsp://192.168.1.99:554/te!st?user=tmp&password=BagRep1!&channel=1&stream=0.sdp/trackID=1"),
|
mustParse("rtsp://192.168.1.99:554/te!st?user=tmp&password=BagRep1!&channel=1&stream=0.sdp/trackID=1"),
|
||||||
"te!st?user=tmp&password=BagRep1!&channel=1&stream=0.sdp/trackID=1",
|
"te!st?user=tmp&password=BagRep1!&channel=1&stream=0.sdp/trackID=1",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
mustParseURL("rtsp://192.168.1.99:554/user=tmp&password=BagRep1!&channel=1&stream=0.sdp/trackID=1"),
|
mustParse("rtsp://192.168.1.99:554/user=tmp&password=BagRep1!&channel=1&stream=0.sdp/trackID=1"),
|
||||||
"user=tmp&password=BagRep1!&channel=1&stream=0.sdp/trackID=1",
|
"user=tmp&password=BagRep1!&channel=1&stream=0.sdp/trackID=1",
|
||||||
},
|
},
|
||||||
} {
|
} {
|
@@ -17,6 +17,7 @@ import (
|
|||||||
|
|
||||||
"github.com/aler9/gortsplib/pkg/base"
|
"github.com/aler9/gortsplib/pkg/base"
|
||||||
"github.com/aler9/gortsplib/pkg/headers"
|
"github.com/aler9/gortsplib/pkg/headers"
|
||||||
|
"github.com/aler9/gortsplib/pkg/url"
|
||||||
)
|
)
|
||||||
|
|
||||||
func multicastCapableIP(t *testing.T) string {
|
func multicastCapableIP(t *testing.T) string {
|
||||||
@@ -1737,7 +1738,7 @@ func TestServerReadAdditionalInfos(t *testing.T) {
|
|||||||
rtpInfo, ssrcs := getInfos()
|
rtpInfo, ssrcs := getInfos()
|
||||||
require.Equal(t, &headers.RTPInfo{
|
require.Equal(t, &headers.RTPInfo{
|
||||||
&headers.RTPInfoEntry{
|
&headers.RTPInfoEntry{
|
||||||
URL: (&base.URL{
|
URL: (&url.URL{
|
||||||
Scheme: "rtsp",
|
Scheme: "rtsp",
|
||||||
Host: "localhost:8554",
|
Host: "localhost:8554",
|
||||||
Path: "/teststream/trackID=0",
|
Path: "/teststream/trackID=0",
|
||||||
@@ -1771,7 +1772,7 @@ func TestServerReadAdditionalInfos(t *testing.T) {
|
|||||||
rtpInfo, ssrcs = getInfos()
|
rtpInfo, ssrcs = getInfos()
|
||||||
require.Equal(t, &headers.RTPInfo{
|
require.Equal(t, &headers.RTPInfo{
|
||||||
&headers.RTPInfoEntry{
|
&headers.RTPInfoEntry{
|
||||||
URL: (&base.URL{
|
URL: (&url.URL{
|
||||||
Scheme: "rtsp",
|
Scheme: "rtsp",
|
||||||
Host: "localhost:8554",
|
Host: "localhost:8554",
|
||||||
Path: "/teststream/trackID=0",
|
Path: "/teststream/trackID=0",
|
||||||
@@ -1783,7 +1784,7 @@ func TestServerReadAdditionalInfos(t *testing.T) {
|
|||||||
Timestamp: (*rtpInfo)[0].Timestamp,
|
Timestamp: (*rtpInfo)[0].Timestamp,
|
||||||
},
|
},
|
||||||
&headers.RTPInfoEntry{
|
&headers.RTPInfoEntry{
|
||||||
URL: (&base.URL{
|
URL: (&url.URL{
|
||||||
Scheme: "rtsp",
|
Scheme: "rtsp",
|
||||||
Host: "localhost:8554",
|
Host: "localhost:8554",
|
||||||
Path: "/teststream/trackID=1",
|
Path: "/teststream/trackID=1",
|
||||||
|
@@ -7,7 +7,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/url"
|
gourl "net/url"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -16,6 +16,7 @@ import (
|
|||||||
"github.com/aler9/gortsplib/pkg/base"
|
"github.com/aler9/gortsplib/pkg/base"
|
||||||
"github.com/aler9/gortsplib/pkg/liberrors"
|
"github.com/aler9/gortsplib/pkg/liberrors"
|
||||||
"github.com/aler9/gortsplib/pkg/rtph264"
|
"github.com/aler9/gortsplib/pkg/rtph264"
|
||||||
|
"github.com/aler9/gortsplib/pkg/url"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getSessionID(header base.Header) string {
|
func getSessionID(header base.Header) string {
|
||||||
@@ -443,7 +444,7 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) {
|
|||||||
}, liberrors.ErrServerInvalidPath{}
|
}, liberrors.ErrServerInvalidPath{}
|
||||||
}
|
}
|
||||||
|
|
||||||
path, query := base.PathSplitQuery(pathAndQuery)
|
path, query := url.PathSplitQuery(pathAndQuery)
|
||||||
|
|
||||||
res, stream, err := h.OnDescribe(&ServerHandlerOnDescribeCtx{
|
res, stream, err := h.OnDescribe(&ServerHandlerOnDescribeCtx{
|
||||||
Conn: sc,
|
Conn: sc,
|
||||||
@@ -465,7 +466,7 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) {
|
|||||||
// to return a SDP that contains a multicast address.
|
// to return a SDP that contains a multicast address.
|
||||||
multicast := false
|
multicast := false
|
||||||
if sc.s.MulticastIPRange != "" {
|
if sc.s.MulticastIPRange != "" {
|
||||||
if q, err := url.ParseQuery(query); err == nil {
|
if q, err := gourl.ParseQuery(query); err == nil {
|
||||||
if _, ok := q["vlcmulticast"]; ok {
|
if _, ok := q["vlcmulticast"]; ok {
|
||||||
multicast = true
|
multicast = true
|
||||||
}
|
}
|
||||||
@@ -530,7 +531,7 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) {
|
|||||||
}, liberrors.ErrServerInvalidPath{}
|
}, liberrors.ErrServerInvalidPath{}
|
||||||
}
|
}
|
||||||
|
|
||||||
path, query := base.PathSplitQuery(pathAndQuery)
|
path, query := url.PathSplitQuery(pathAndQuery)
|
||||||
|
|
||||||
return h.OnGetParameter(&ServerHandlerOnGetParameterCtx{
|
return h.OnGetParameter(&ServerHandlerOnGetParameterCtx{
|
||||||
Conn: sc,
|
Conn: sc,
|
||||||
@@ -549,7 +550,7 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) {
|
|||||||
}, liberrors.ErrServerInvalidPath{}
|
}, liberrors.ErrServerInvalidPath{}
|
||||||
}
|
}
|
||||||
|
|
||||||
path, query := base.PathSplitQuery(pathAndQuery)
|
path, query := url.PathSplitQuery(pathAndQuery)
|
||||||
|
|
||||||
return h.OnSetParameter(&ServerHandlerOnSetParameterCtx{
|
return h.OnSetParameter(&ServerHandlerOnSetParameterCtx{
|
||||||
Conn: sc,
|
Conn: sc,
|
||||||
|
@@ -20,6 +20,7 @@ import (
|
|||||||
"github.com/aler9/gortsplib/pkg/ringbuffer"
|
"github.com/aler9/gortsplib/pkg/ringbuffer"
|
||||||
"github.com/aler9/gortsplib/pkg/rtcpreceiver"
|
"github.com/aler9/gortsplib/pkg/rtcpreceiver"
|
||||||
"github.com/aler9/gortsplib/pkg/rtph264"
|
"github.com/aler9/gortsplib/pkg/rtph264"
|
||||||
|
"github.com/aler9/gortsplib/pkg/url"
|
||||||
)
|
)
|
||||||
|
|
||||||
func stringsReverseIndex(s, substr string) int {
|
func stringsReverseIndex(s, substr string) int {
|
||||||
@@ -32,14 +33,14 @@ func stringsReverseIndex(s, substr string) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func setupGetTrackIDPathQuery(
|
func setupGetTrackIDPathQuery(
|
||||||
url *base.URL,
|
u *url.URL,
|
||||||
thMode *headers.TransportMode,
|
thMode *headers.TransportMode,
|
||||||
announcedTracks []*ServerSessionAnnouncedTrack,
|
announcedTracks []*ServerSessionAnnouncedTrack,
|
||||||
setuppedPath *string,
|
setuppedPath *string,
|
||||||
setuppedQuery *string,
|
setuppedQuery *string,
|
||||||
setuppedBaseURL *base.URL,
|
setuppedBaseURL *url.URL,
|
||||||
) (int, string, string, error) {
|
) (int, string, string, error) {
|
||||||
pathAndQuery, ok := url.RTSPPathAndQuery()
|
pathAndQuery, ok := u.RTSPPathAndQuery()
|
||||||
if !ok {
|
if !ok {
|
||||||
return 0, "", "", liberrors.ErrServerInvalidPath{}
|
return 0, "", "", liberrors.ErrServerInvalidPath{}
|
||||||
}
|
}
|
||||||
@@ -56,7 +57,7 @@ func setupGetTrackIDPathQuery(
|
|||||||
}
|
}
|
||||||
pathAndQuery = pathAndQuery[:len(pathAndQuery)-1]
|
pathAndQuery = pathAndQuery[:len(pathAndQuery)-1]
|
||||||
|
|
||||||
path, query := base.PathSplitQuery(pathAndQuery)
|
path, query := url.PathSplitQuery(pathAndQuery)
|
||||||
|
|
||||||
// we assume it's track 0
|
// we assume it's track 0
|
||||||
return 0, path, query, nil
|
return 0, path, query, nil
|
||||||
@@ -69,7 +70,7 @@ func setupGetTrackIDPathQuery(
|
|||||||
trackID := int(tmp)
|
trackID := int(tmp)
|
||||||
pathAndQuery = pathAndQuery[:i]
|
pathAndQuery = pathAndQuery[:i]
|
||||||
|
|
||||||
path, query := base.PathSplitQuery(pathAndQuery)
|
path, query := url.PathSplitQuery(pathAndQuery)
|
||||||
|
|
||||||
if setuppedPath != nil && (path != *setuppedPath || query != *setuppedQuery) {
|
if setuppedPath != nil && (path != *setuppedPath || query != *setuppedQuery) {
|
||||||
return 0, "", "", fmt.Errorf("can't setup tracks with different paths")
|
return 0, "", "", fmt.Errorf("can't setup tracks with different paths")
|
||||||
@@ -79,8 +80,8 @@ func setupGetTrackIDPathQuery(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for trackID, track := range announcedTracks {
|
for trackID, track := range announcedTracks {
|
||||||
u, _ := track.track.url(setuppedBaseURL)
|
u2, _ := track.track.url(setuppedBaseURL)
|
||||||
if u.String() == url.String() {
|
if u2.String() == u.String() {
|
||||||
return trackID, *setuppedPath, *setuppedQuery, nil
|
return trackID, *setuppedPath, *setuppedQuery, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -170,7 +171,7 @@ type ServerSession struct {
|
|||||||
setuppedTracks map[int]*ServerSessionSetuppedTrack
|
setuppedTracks map[int]*ServerSessionSetuppedTrack
|
||||||
tcpTracksByChannel map[int]int
|
tcpTracksByChannel map[int]int
|
||||||
setuppedTransport *Transport
|
setuppedTransport *Transport
|
||||||
setuppedBaseURL *base.URL // publish
|
setuppedBaseURL *url.URL // publish
|
||||||
setuppedStream *ServerStream // read
|
setuppedStream *ServerStream // read
|
||||||
setuppedPath *string
|
setuppedPath *string
|
||||||
setuppedQuery *string
|
setuppedQuery *string
|
||||||
@@ -488,7 +489,7 @@ func (ss *ServerSession) handleRequest(sc *ServerConn, req *base.Request) (*base
|
|||||||
}, liberrors.ErrServerInvalidPath{}
|
}, liberrors.ErrServerInvalidPath{}
|
||||||
}
|
}
|
||||||
|
|
||||||
path, query := base.PathSplitQuery(pathAndQuery)
|
path, query := url.PathSplitQuery(pathAndQuery)
|
||||||
|
|
||||||
ct, ok := req.Header["Content-Type"]
|
ct, ok := req.Header["Content-Type"]
|
||||||
if !ok || len(ct) != 1 {
|
if !ok || len(ct) != 1 {
|
||||||
@@ -815,7 +816,7 @@ func (ss *ServerSession) handleRequest(sc *ServerConn, req *base.Request) (*base
|
|||||||
// path can end with a slash due to Content-Base, remove it
|
// path can end with a slash due to Content-Base, remove it
|
||||||
pathAndQuery = strings.TrimSuffix(pathAndQuery, "/")
|
pathAndQuery = strings.TrimSuffix(pathAndQuery, "/")
|
||||||
|
|
||||||
path, query := base.PathSplitQuery(pathAndQuery)
|
path, query := url.PathSplitQuery(pathAndQuery)
|
||||||
|
|
||||||
if ss.State() == ServerSessionStatePrePlay &&
|
if ss.State() == ServerSessionStatePrePlay &&
|
||||||
path != *ss.setuppedPath {
|
path != *ss.setuppedPath {
|
||||||
@@ -899,7 +900,7 @@ func (ss *ServerSession) handleRequest(sc *ServerConn, req *base.Request) (*base
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
u := &base.URL{
|
u := &url.URL{
|
||||||
Scheme: req.URL.Scheme,
|
Scheme: req.URL.Scheme,
|
||||||
User: req.URL.User,
|
User: req.URL.User,
|
||||||
Host: req.URL.Host,
|
Host: req.URL.Host,
|
||||||
@@ -947,7 +948,7 @@ func (ss *ServerSession) handleRequest(sc *ServerConn, req *base.Request) (*base
|
|||||||
// path can end with a slash due to Content-Base, remove it
|
// path can end with a slash due to Content-Base, remove it
|
||||||
pathAndQuery = strings.TrimSuffix(pathAndQuery, "/")
|
pathAndQuery = strings.TrimSuffix(pathAndQuery, "/")
|
||||||
|
|
||||||
path, query := base.PathSplitQuery(pathAndQuery)
|
path, query := url.PathSplitQuery(pathAndQuery)
|
||||||
|
|
||||||
if path != *ss.setuppedPath {
|
if path != *ss.setuppedPath {
|
||||||
return &base.Response{
|
return &base.Response{
|
||||||
@@ -1042,7 +1043,7 @@ func (ss *ServerSession) handleRequest(sc *ServerConn, req *base.Request) (*base
|
|||||||
// path can end with a slash due to Content-Base, remove it
|
// path can end with a slash due to Content-Base, remove it
|
||||||
pathAndQuery = strings.TrimSuffix(pathAndQuery, "/")
|
pathAndQuery = strings.TrimSuffix(pathAndQuery, "/")
|
||||||
|
|
||||||
path, query := base.PathSplitQuery(pathAndQuery)
|
path, query := url.PathSplitQuery(pathAndQuery)
|
||||||
|
|
||||||
res, err := ss.s.Handler.(ServerHandlerOnPause).OnPause(&ServerHandlerOnPauseCtx{
|
res, err := ss.s.Handler.(ServerHandlerOnPause).OnPause(&ServerHandlerOnPauseCtx{
|
||||||
Session: ss,
|
Session: ss,
|
||||||
@@ -1133,7 +1134,7 @@ func (ss *ServerSession) handleRequest(sc *ServerConn, req *base.Request) (*base
|
|||||||
}, liberrors.ErrServerInvalidPath{}
|
}, liberrors.ErrServerInvalidPath{}
|
||||||
}
|
}
|
||||||
|
|
||||||
path, query := base.PathSplitQuery(pathAndQuery)
|
path, query := url.PathSplitQuery(pathAndQuery)
|
||||||
|
|
||||||
return h.OnGetParameter(&ServerHandlerOnGetParameterCtx{
|
return h.OnGetParameter(&ServerHandlerOnGetParameterCtx{
|
||||||
Session: ss,
|
Session: ss,
|
||||||
|
10
track.go
10
track.go
@@ -7,7 +7,7 @@ import (
|
|||||||
|
|
||||||
psdp "github.com/pion/sdp/v3"
|
psdp "github.com/pion/sdp/v3"
|
||||||
|
|
||||||
"github.com/aler9/gortsplib/pkg/base"
|
"github.com/aler9/gortsplib/pkg/url"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Track is a RTSP track.
|
// Track is a RTSP track.
|
||||||
@@ -25,7 +25,7 @@ type Track interface {
|
|||||||
MediaDescription() *psdp.MediaDescription
|
MediaDescription() *psdp.MediaDescription
|
||||||
|
|
||||||
clone() Track
|
clone() Track
|
||||||
url(*base.URL) (*base.URL, error)
|
url(*url.URL) (*url.URL, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTrackFromMediaDescription(md *psdp.MediaDescription) (Track, error) {
|
func newTrackFromMediaDescription(md *psdp.MediaDescription) (Track, error) {
|
||||||
@@ -98,7 +98,7 @@ func (t *trackBase) SetControl(c string) {
|
|||||||
t.control = c
|
t.control = c
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *trackBase) url(contentBase *base.URL) (*base.URL, error) {
|
func (t *trackBase) url(contentBase *url.URL) (*url.URL, error) {
|
||||||
if contentBase == nil {
|
if contentBase == nil {
|
||||||
return nil, fmt.Errorf("Content-Base header not provided")
|
return nil, fmt.Errorf("Content-Base header not provided")
|
||||||
}
|
}
|
||||||
@@ -112,7 +112,7 @@ func (t *trackBase) url(contentBase *base.URL) (*base.URL, error) {
|
|||||||
|
|
||||||
// control attribute contains an absolute path
|
// control attribute contains an absolute path
|
||||||
if strings.HasPrefix(control, "rtsp://") {
|
if strings.HasPrefix(control, "rtsp://") {
|
||||||
ur, err := base.ParseURL(control)
|
ur, err := url.Parse(control)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -132,6 +132,6 @@ func (t *trackBase) url(contentBase *base.URL) (*base.URL, error) {
|
|||||||
strURL += "/"
|
strURL += "/"
|
||||||
}
|
}
|
||||||
|
|
||||||
ur, _ := base.ParseURL(strURL + control)
|
ur, _ := url.Parse(strURL + control)
|
||||||
return ur, nil
|
return ur, nil
|
||||||
}
|
}
|
||||||
|
@@ -6,7 +6,7 @@ import (
|
|||||||
psdp "github.com/pion/sdp/v3"
|
psdp "github.com/pion/sdp/v3"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/aler9/gortsplib/pkg/base"
|
"github.com/aler9/gortsplib/pkg/url"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestTrackNewFromMediaDescription(t *testing.T) {
|
func TestTrackNewFromMediaDescription(t *testing.T) {
|
||||||
@@ -662,8 +662,8 @@ func TestTrackURL(t *testing.T) {
|
|||||||
for _, ca := range []struct {
|
for _, ca := range []struct {
|
||||||
name string
|
name string
|
||||||
sdp []byte
|
sdp []byte
|
||||||
baseURL *base.URL
|
baseURL *url.URL
|
||||||
ur *base.URL
|
ur *url.URL
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
"missing control",
|
"missing control",
|
||||||
|
Reference in New Issue
Block a user