2018-08-24 03:55:36 +03:00
|
|
|
/*
|
|
|
|
NAME
|
|
|
|
parseurl.go
|
|
|
|
|
|
|
|
DESCRIPTION
|
|
|
|
See Readme.md
|
|
|
|
|
|
|
|
AUTHOR
|
2018-09-07 06:00:25 +03:00
|
|
|
Dan Kortschak <dan@ausocean.org>
|
2018-08-24 03:55:36 +03:00
|
|
|
Saxon Nelson-Milton <saxon@ausocean.org>
|
2019-01-11 02:57:41 +03:00
|
|
|
Alan Noble <alan@ausocean.org>
|
2018-08-24 03:55:36 +03:00
|
|
|
|
|
|
|
LICENSE
|
2019-01-11 02:57:41 +03:00
|
|
|
parseurl.go is Copyright (C) 2017-2019 the Australian Ocean Lab (AusOcean)
|
2018-08-24 03:55:36 +03:00
|
|
|
|
|
|
|
It is free software: you can redistribute it and/or modify them
|
|
|
|
under the terms of the GNU General Public License as published by the
|
|
|
|
Free Software Foundation, either version 3 of the License, or (at your
|
|
|
|
option) any later version.
|
|
|
|
|
|
|
|
It is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
|
|
for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
2018-08-30 14:01:19 +03:00
|
|
|
along with revid in gpl.txt. If not, see http://www.gnu.org/licenses.
|
2018-08-24 03:55:36 +03:00
|
|
|
|
2018-08-30 14:01:19 +03:00
|
|
|
Derived from librtmp under the GNU Lesser General Public License 2.1
|
|
|
|
Copyright (C) 2005-2008 Team XBMC http://www.xbmc.org
|
|
|
|
Copyright (C) 2008-2009 Andrej Stepanchuk
|
|
|
|
Copyright (C) 2009-2010 Howard Chu
|
2018-08-24 03:55:36 +03:00
|
|
|
*/
|
2018-08-24 00:34:01 +03:00
|
|
|
package rtmp
|
|
|
|
|
2018-08-24 03:03:05 +03:00
|
|
|
import (
|
2018-09-07 06:00:25 +03:00
|
|
|
"net/url"
|
|
|
|
"path"
|
2018-08-24 03:03:05 +03:00
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
2019-01-07 10:30:42 +03:00
|
|
|
// parseURL parses an RTMP URL (ok, technically it is lexing).
|
|
|
|
func parseURL(addr string) (protocol int32, host string, port uint16, app, playpath string, err error) {
|
2018-09-07 06:00:25 +03:00
|
|
|
u, err := url.Parse(addr)
|
|
|
|
if err != nil {
|
2019-01-06 01:50:32 +03:00
|
|
|
return protocol, host, port, app, playpath, err
|
2018-08-24 00:34:01 +03:00
|
|
|
}
|
|
|
|
|
2018-09-07 06:00:25 +03:00
|
|
|
switch u.Scheme {
|
|
|
|
case "rtmp":
|
2019-01-11 02:57:41 +03:00
|
|
|
protocol = protoRTMP
|
2018-09-07 06:00:25 +03:00
|
|
|
case "rtmpt":
|
2019-01-11 02:57:41 +03:00
|
|
|
protocol = protoRTMPT
|
2018-09-07 06:00:25 +03:00
|
|
|
case "rtmps":
|
2019-01-11 02:57:41 +03:00
|
|
|
protocol = protoRTMPS
|
2018-09-07 06:00:25 +03:00
|
|
|
case "rtmpe":
|
2019-01-11 02:57:41 +03:00
|
|
|
protocol = protoRTMPE
|
2018-09-07 06:00:25 +03:00
|
|
|
case "rtmfp":
|
2019-01-11 02:57:41 +03:00
|
|
|
protocol = protoRTMFP
|
2018-09-07 06:00:25 +03:00
|
|
|
case "rtmpte":
|
2019-01-11 02:57:41 +03:00
|
|
|
protocol = protoRTMPTE
|
2018-09-07 06:00:25 +03:00
|
|
|
case "rtmpts":
|
2019-01-11 02:57:41 +03:00
|
|
|
protocol = protoRTMPTS
|
2018-09-07 06:00:25 +03:00
|
|
|
default:
|
2019-01-06 01:50:32 +03:00
|
|
|
return protocol, host, port, app, playpath, errUnknownScheme
|
2018-08-24 00:34:01 +03:00
|
|
|
}
|
|
|
|
|
2018-09-07 14:10:46 +03:00
|
|
|
host = u.Host
|
2018-09-07 06:00:25 +03:00
|
|
|
if p := u.Port(); p != "" {
|
|
|
|
pi, err := strconv.Atoi(p)
|
2018-09-07 00:31:59 +03:00
|
|
|
if err != nil {
|
2019-01-06 01:50:32 +03:00
|
|
|
return protocol, host, port, app, playpath, err
|
2018-09-07 00:31:59 +03:00
|
|
|
}
|
2018-09-07 06:00:25 +03:00
|
|
|
port = uint16(pi)
|
2018-08-24 00:34:01 +03:00
|
|
|
}
|
|
|
|
|
2018-09-07 06:00:25 +03:00
|
|
|
if !path.IsAbs(u.Path) {
|
2019-01-06 01:50:32 +03:00
|
|
|
return protocol, host, port, app, playpath, nil
|
2018-08-24 00:34:01 +03:00
|
|
|
}
|
2019-03-13 09:55:47 +03:00
|
|
|
|
2018-09-07 06:00:25 +03:00
|
|
|
elems := strings.SplitN(u.Path[1:], "/", 3)
|
2018-09-07 14:10:46 +03:00
|
|
|
app = elems[0]
|
2019-03-13 09:55:47 +03:00
|
|
|
if len(elems[len(elems)-1]) == 0 {
|
|
|
|
elems = elems[:len(elems)-1]
|
|
|
|
}
|
|
|
|
if app == "" || len(elems) < 2 {
|
2019-01-20 02:29:28 +03:00
|
|
|
return protocol, host, port, app, playpath, errInvalidURL
|
|
|
|
}
|
2019-03-13 09:55:47 +03:00
|
|
|
|
|
|
|
playpath = path.Join(elems[1:]...)
|
|
|
|
switch ext := path.Ext(playpath); ext {
|
|
|
|
case ".f4v", ".mp4":
|
|
|
|
playpath = playpath[:len(playpath)-len(ext)]
|
|
|
|
if !strings.HasPrefix(playpath, "mp4:") {
|
|
|
|
playpath = "mp4:" + playpath
|
2018-09-07 06:00:25 +03:00
|
|
|
}
|
2019-03-13 09:55:47 +03:00
|
|
|
case ".mp3":
|
|
|
|
playpath = playpath[:len(playpath)-len(ext)]
|
|
|
|
if !strings.HasPrefix(playpath, "mp3:") {
|
|
|
|
playpath = "mp3:" + playpath
|
2018-09-07 06:00:25 +03:00
|
|
|
}
|
2019-03-13 09:55:47 +03:00
|
|
|
case ".flv":
|
|
|
|
playpath = playpath[:len(playpath)-len(ext)]
|
|
|
|
}
|
|
|
|
if u.RawQuery != "" {
|
|
|
|
playpath += "?" + u.RawQuery
|
2018-08-24 00:34:01 +03:00
|
|
|
}
|
|
|
|
|
2019-01-21 03:27:40 +03:00
|
|
|
switch {
|
|
|
|
case port != 0:
|
|
|
|
case (protocol & featureSSL) != 0:
|
|
|
|
return protocol, host, port, app, playpath, errUnimplemented // port = 433
|
|
|
|
case (protocol & featureHTTP) != 0:
|
|
|
|
port = 80
|
|
|
|
default:
|
|
|
|
port = 1935
|
2019-01-20 06:03:44 +03:00
|
|
|
}
|
2019-01-21 03:27:40 +03:00
|
|
|
|
2019-01-06 01:50:32 +03:00
|
|
|
return protocol, host, port, app, playpath, nil
|
2018-08-24 00:34:01 +03:00
|
|
|
}
|