mirror of
				https://github.com/aler9/gortsplib
				synced 2025-10-31 18:42:40 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			106 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			106 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package base
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"net/url"
 | |
| 	"regexp"
 | |
| 	"strings"
 | |
| )
 | |
| 
 | |
| // URL is a RTSP URL.
 | |
| // This is basically an HTTP URL with some additional functions to handle
 | |
| // control attributes.
 | |
| type URL url.URL
 | |
| 
 | |
| var escapeRegexp = regexp.MustCompile(`^(.+?)://(.*?)@(.*?)/(.*?)$`)
 | |
| 
 | |
| // ParseURL parses a RTSP URL.
 | |
| func ParseURL(s string) (*URL, error) {
 | |
| 	// https://github.com/golang/go/issues/30611
 | |
| 	m := escapeRegexp.FindStringSubmatch(s)
 | |
| 	if m != nil {
 | |
| 		m[3] = strings.ReplaceAll(m[3], "%25", "%")
 | |
| 		m[3] = strings.ReplaceAll(m[3], "%", "%25")
 | |
| 		s = m[1] + "://" + m[2] + "@" + m[3] + "/" + m[4]
 | |
| 	}
 | |
| 
 | |
| 	u, err := url.Parse(s)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	if u.Scheme != "rtsp" && u.Scheme != "rtsps" {
 | |
| 		return nil, fmt.Errorf("unsupported scheme '%s'", u.Scheme)
 | |
| 	}
 | |
| 
 | |
| 	if u.Opaque != "" {
 | |
| 		return nil, fmt.Errorf("URLs with opaque data are not supported")
 | |
| 	}
 | |
| 
 | |
| 	if u.Fragment != "" {
 | |
| 		return nil, fmt.Errorf("URLs with fragments are not supported")
 | |
| 	}
 | |
| 
 | |
| 	return (*URL)(u), nil
 | |
| }
 | |
| 
 | |
| // String implements fmt.Stringer.
 | |
| func (u *URL) String() string {
 | |
| 	return (*url.URL)(u).String()
 | |
| }
 | |
| 
 | |
| // Clone clones a URL.
 | |
| func (u *URL) Clone() *URL {
 | |
| 	return (*URL)(&url.URL{
 | |
| 		Scheme:     u.Scheme,
 | |
| 		User:       u.User,
 | |
| 		Host:       u.Host,
 | |
| 		Path:       u.Path,
 | |
| 		RawPath:    u.RawPath,
 | |
| 		ForceQuery: u.ForceQuery,
 | |
| 		RawQuery:   u.RawQuery,
 | |
| 	})
 | |
| }
 | |
| 
 | |
| // CloneWithoutCredentials clones a URL without its credentials.
 | |
| func (u *URL) CloneWithoutCredentials() *URL {
 | |
| 	return (*URL)(&url.URL{
 | |
| 		Scheme:     u.Scheme,
 | |
| 		Host:       u.Host,
 | |
| 		Path:       u.Path,
 | |
| 		RawPath:    u.RawPath,
 | |
| 		ForceQuery: u.ForceQuery,
 | |
| 		RawQuery:   u.RawQuery,
 | |
| 	})
 | |
| }
 | |
| 
 | |
| // RTSPPathAndQuery returns the path and query of a RTSP URL.
 | |
| func (u *URL) RTSPPathAndQuery() (string, bool) {
 | |
| 	var pathAndQuery string
 | |
| 	if u.RawPath != "" {
 | |
| 		pathAndQuery = u.RawPath
 | |
| 	} else {
 | |
| 		pathAndQuery = u.Path
 | |
| 	}
 | |
| 	if u.RawQuery != "" {
 | |
| 		pathAndQuery += "?" + u.RawQuery
 | |
| 	}
 | |
| 
 | |
| 	return pathAndQuery, true
 | |
| }
 | |
| 
 | |
| // Hostname returns u.Host, stripping any valid port number if present.
 | |
| //
 | |
| // If the result is enclosed in square brackets, as literal IPv6 addresses are,
 | |
| // the square brackets are removed from the result.
 | |
| func (u *URL) Hostname() string {
 | |
| 	return (*url.URL)(u).Hostname()
 | |
| }
 | |
| 
 | |
| // Port returns the port part of u.Host, without the leading colon.
 | |
| //
 | |
| // If u.Host doesn't contain a valid numeric port, Port returns an empty string.
 | |
| func (u *URL) Port() string {
 | |
| 	return (*url.URL)(u).Port()
 | |
| }
 | 
