Ported RTMP_ParseURL - still need to test

This commit is contained in:
saxon 2018-08-11 01:13:25 +09:30
parent e552384a42
commit 2e3dfab7e2
1 changed files with 177 additions and 4 deletions

View File

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