move URL into dedicated folder

This commit is contained in:
aler9
2022-06-05 01:27:19 +02:00
parent 45f5107ae3
commit 2fa3148a27
25 changed files with 123 additions and 102 deletions

View File

@@ -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 {

View File

@@ -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)

View File

@@ -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{}

View File

@@ -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)
} }

View File

@@ -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)
} }

View File

@@ -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)
} }

View File

@@ -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)
} }

View File

@@ -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)
} }

View File

@@ -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)
} }

View File

@@ -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)
} }

View File

@@ -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)
} }

View File

@@ -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
} }

View File

@@ -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 {

View File

@@ -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)
} }

View File

@@ -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

View File

@@ -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 {

View File

@@ -1,4 +1,4 @@
package base package url
import ( import (
"strings" "strings"

View File

@@ -1,4 +1,4 @@
package base package url
import ( import (
"testing" "testing"

View File

@@ -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 {

View File

@@ -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",
}, },
} { } {

View File

@@ -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",

View File

@@ -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,

View File

@@ -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,

View File

@@ -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
} }

View File

@@ -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",