mirror of https://bitbucket.org/ausocean/av.git
Ported RTMP_ParseURL - still need to test
This commit is contained in:
parent
e552384a42
commit
2e3dfab7e2
181
rtmp/rtmp.go
181
rtmp/rtmp.go
|
@ -66,6 +66,7 @@ import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/chamaken/cgolmnl/inet"
|
"github.com/chamaken/cgolmnl/inet"
|
||||||
|
@ -597,10 +598,10 @@ func C_RTMP_SetupURL(r *C.RTMP, u string) int32 {
|
||||||
// AVal *playpath, AVal *app);
|
// AVal *playpath, AVal *app);
|
||||||
// parseurl.c +33
|
// parseurl.c +33
|
||||||
func C_RTMP_ParseURL(url *byte, protocol *int32, host *C.AVal, port *uint32,
|
func C_RTMP_ParseURL(url *byte, protocol *int32, host *C.AVal, port *uint32,
|
||||||
playpath *C.AVal, app *C.AVal) {
|
playpath *C.AVal, app *C.AVal) int {
|
||||||
|
|
||||||
var p, end, col, ques, slash *byte
|
var p, end, col, ques, slash *byte
|
||||||
|
// TODO: use our logger here
|
||||||
// RTMP_Log(RTMP_LOGDEBUG, "Parsing...");
|
// RTMP_Log(RTMP_LOGDEBUG, "Parsing...");
|
||||||
|
|
||||||
*protocol = RTMP_PROTOCOL_RTMP
|
*protocol = RTMP_PROTOCOL_RTMP
|
||||||
|
@ -610,8 +611,174 @@ func C_RTMP_ParseURL(url *byte, protocol *int32, host *C.AVal, port *uint32,
|
||||||
app.av_len = 0
|
app.av_len = 0
|
||||||
app.av_val = nil
|
app.av_val = nil
|
||||||
|
|
||||||
p = str
|
p = strstr(url, goStrToCStr("://"))
|
||||||
|
|
||||||
|
if p == nil {
|
||||||
|
// TODO: use our logger here
|
||||||
|
log.Println("RTMP URL: No :// in url!")
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
NOTE: the following code nees to be ported if we're using anything other than
|
||||||
|
rtmp!
|
||||||
|
{
|
||||||
|
int len = (int)(p-url);
|
||||||
|
|
||||||
|
if(len == 4 && strncasecmp(url, "rtmp", 4)==0)
|
||||||
|
*protocol = RTMP_PROTOCOL_RTMP;
|
||||||
|
else if(len == 5 && strncasecmp(url, "rtmpt", 5)==0)
|
||||||
|
*protocol = RTMP_PROTOCOL_RTMPT;
|
||||||
|
else if(len == 5 && strncasecmp(url, "rtmps", 5)==0)
|
||||||
|
*protocol = RTMP_PROTOCOL_RTMPS;
|
||||||
|
else if(len == 5 && strncasecmp(url, "rtmpe", 5)==0)
|
||||||
|
*protocol = RTMP_PROTOCOL_RTMPE;
|
||||||
|
else if(len == 5 && strncasecmp(url, "rtmfp", 5)==0)
|
||||||
|
*protocol = RTMP_PROTOCOL_RTMFP;
|
||||||
|
else if(len == 6 && strncasecmp(url, "rtmpte", 6)==0)
|
||||||
|
*protocol = RTMP_PROTOCOL_RTMPTE;
|
||||||
|
else if(len == 6 && strncasecmp(url, "rtmpts", 6)==0)
|
||||||
|
*protocol = RTMP_PROTOCOL_RTMPTS;
|
||||||
|
else {
|
||||||
|
RTMP_Log(RTMP_LOGWARNING, "Unknown protocol!\n");
|
||||||
|
goto parsehost;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
// TODO: implement new logger here
|
||||||
|
// RTMP_Log(RTMP_LOGDEBUG, "Parsed protocol: %d", *protocol);
|
||||||
|
|
||||||
|
// Get the hostname
|
||||||
|
p = (*byte)(incBytePtr(unsafe.Pointer(p), 3))
|
||||||
|
|
||||||
|
// check for sudden death
|
||||||
|
if *p == 0 {
|
||||||
|
// TODO: use new logger here
|
||||||
|
// RTMP_Log(RTMP_LOGWARNING, "No hostname in URL!");
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
end = (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(p)) + uintptr(strlen(p))))
|
||||||
|
col = strchr(p, ':')
|
||||||
|
ques = strchr(p, '?')
|
||||||
|
slash = strchr(p, '/')
|
||||||
|
|
||||||
|
{
|
||||||
|
var hostlen int32
|
||||||
|
if slash != nil {
|
||||||
|
hostlen = int32(uintptr(unsafe.Pointer(slash)) - uintptr(unsafe.Pointer(p)))
|
||||||
|
} else {
|
||||||
|
hostlen = int32(uintptr(unsafe.Pointer(end)) - uintptr(unsafe.Pointer(p)))
|
||||||
|
}
|
||||||
|
if col != nil && int32(uintptr(unsafe.Pointer(col))-uintptr(unsafe.Pointer(p))) < hostlen {
|
||||||
|
hostlen = int32(uintptr(unsafe.Pointer(col)) - uintptr(unsafe.Pointer(p)))
|
||||||
|
}
|
||||||
|
|
||||||
|
if hostlen < 256 {
|
||||||
|
host.av_val = (*C.char)(unsafe.Pointer(p))
|
||||||
|
host.av_len = C.int(hostlen)
|
||||||
|
// TODO: use new logger with this
|
||||||
|
//RTMP_Log(RTMP_LOGDEBUG, "Parsed host : %.*s", hostlen, host->av_val);
|
||||||
|
} else {
|
||||||
|
// TODO: use new logger with this
|
||||||
|
// RTMP_Log(RTMP_LOGWARNING, "Hostname exceeds 255 characters!");
|
||||||
|
}
|
||||||
|
|
||||||
|
p = (*byte)(incBytePtr(unsafe.Pointer(p), int(hostlen)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// get port number if available
|
||||||
|
if *p == ':' {
|
||||||
|
var p2 uint32
|
||||||
|
p = (*byte)(incBytePtr(unsafe.Pointer(p), 1))
|
||||||
|
tmp, _ := strconv.Atoi(cStrToGoStr(p))
|
||||||
|
p2 = uint32(tmp)
|
||||||
|
if p2 > 65535 {
|
||||||
|
// TODO: use new logger with this
|
||||||
|
// RTMP_Log(RTMP_LOGWARNING, "Invalid port number!");
|
||||||
|
} else {
|
||||||
|
*port = p2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if slash == nil {
|
||||||
|
// TODO: use new logger
|
||||||
|
// RTMP_Log(RTMP_LOGWARNING, "No application or playpath in URL!");
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
p = (*byte)(incBytePtr(unsafe.Pointer(slash), 1))
|
||||||
|
|
||||||
|
{
|
||||||
|
/* parse application
|
||||||
|
*
|
||||||
|
* rtmp://host[:port]/app[/appinstance][/...]
|
||||||
|
* application = app[/appinstance]
|
||||||
|
*/
|
||||||
|
|
||||||
|
var slash2 *byte
|
||||||
|
var slash3 *byte = nil
|
||||||
|
var slash4 *byte = nil
|
||||||
|
var applen, appnamelen int32
|
||||||
|
|
||||||
|
slash2 = strchr(p, '/')
|
||||||
|
|
||||||
|
if slash2 != nil {
|
||||||
|
slash3 = strchr((*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(slash2))+
|
||||||
|
uintptr(1))), '/')
|
||||||
|
}
|
||||||
|
if slash3 != nil {
|
||||||
|
slash4 = strchr((*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(slash3))+
|
||||||
|
uintptr(1))), '/')
|
||||||
|
}
|
||||||
|
|
||||||
|
// ondemand, pass all parameters as app
|
||||||
|
applen = int32(uintptr(unsafe.Pointer(end)) - uintptr(unsafe.Pointer(p)))
|
||||||
|
appnamelen = applen
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case ques != nil && strstr(p, goStrToCStr("slist=")) != nil:
|
||||||
|
appnamelen = int32(uintptr(unsafe.Pointer(ques)) - uintptr(unsafe.Pointer(p)))
|
||||||
|
case strings.Compare(cStrToGoStr(p)[:9], "ondemand/") == 0:
|
||||||
|
/* app = ondemand/foobar, only pass app=ondemand */
|
||||||
|
applen = 8
|
||||||
|
appnamelen = 8
|
||||||
|
default:
|
||||||
|
switch {
|
||||||
|
case slash4 != nil:
|
||||||
|
appnamelen = int32(uintptr(unsafe.Pointer(slash4)) - uintptr(
|
||||||
|
unsafe.Pointer(p)))
|
||||||
|
case slash3 != nil:
|
||||||
|
appnamelen = int32(uintptr(unsafe.Pointer(slash3)) - uintptr(
|
||||||
|
unsafe.Pointer(p)))
|
||||||
|
case slash2 != nil:
|
||||||
|
appnamelen = int32(uintptr(unsafe.Pointer(slash2)) - uintptr(
|
||||||
|
unsafe.Pointer(p)))
|
||||||
|
}
|
||||||
|
|
||||||
|
applen = appnamelen
|
||||||
|
}
|
||||||
|
|
||||||
|
app.av_val = (*C.char)(unsafe.Pointer(p))
|
||||||
|
app.av_len = C.int(applen)
|
||||||
|
// TODO: use new logging here
|
||||||
|
// RTMP_Log(RTMP_LOGDEBUG, "Parsed app : %.*s", applen, p);
|
||||||
|
|
||||||
|
p = (*byte)(incBytePtr(unsafe.Pointer(p), int(appnamelen)))
|
||||||
|
}
|
||||||
|
|
||||||
|
if *p == '/' {
|
||||||
|
p = (*byte)(incBytePtr(unsafe.Pointer(p), 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
if int(uintptr(unsafe.Pointer(end))-uintptr(unsafe.Pointer(p))) != 0 {
|
||||||
|
var av C.AVal
|
||||||
|
av.av_val = (*C.char)(unsafe.Pointer(p))
|
||||||
|
av.av_len = C.int(uintptr(unsafe.Pointer(end)) - uintptr(unsafe.Pointer(p)))
|
||||||
|
// TODO: port THis
|
||||||
|
C.RTMP_ParsePlaypath(&av, playpath)
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
// void SocksSetup(RTMP *r, C.AVal* sockshost);
|
// void SocksSetup(RTMP *r, C.AVal* sockshost);
|
||||||
|
@ -2330,10 +2497,15 @@ func goStrToCStr(str string) *byte {
|
||||||
for i := 0; i < l; i++ {
|
for i := 0; i < l; i++ {
|
||||||
slice[i] = *indxBytePtr(ptr, i)
|
slice[i] = *indxBytePtr(ptr, i)
|
||||||
}
|
}
|
||||||
slice[l] = '\000'
|
slice[l] = '\x00'
|
||||||
return &slice[0]
|
return &slice[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: need a test in rtmp_test.go
|
||||||
|
func cStrToGoStr(cStr *byte) string {
|
||||||
|
return string(ptrToSlice(unsafe.Pointer(cStr), int(strlen(cStr))))
|
||||||
|
}
|
||||||
|
|
||||||
// Duplicates a string given as a byte pointer
|
// Duplicates a string given as a byte pointer
|
||||||
func strdup(str *byte) *byte {
|
func strdup(str *byte) *byte {
|
||||||
length := strlen(str)
|
length := strlen(str)
|
||||||
|
@ -2374,6 +2546,7 @@ func strchr(str *byte, val byte) *byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: need a test in rtmp_test.go
|
||||||
// Porting: http://www.ai.mit.edu/projects/im/cam8/cam8/working/CAMlib/tcl/compat/strstr.c
|
// Porting: http://www.ai.mit.edu/projects/im/cam8/cam8/working/CAMlib/tcl/compat/strstr.c
|
||||||
func strstr(str *byte, substring *byte) *byte {
|
func strstr(str *byte, substring *byte) *byte {
|
||||||
var a, b *byte
|
var a, b *byte
|
||||||
|
|
Loading…
Reference in New Issue