[rtmpdump] r306 - in trunk: Makefile librtmp/Makefile librtmp/amf.h librtmp/parseurl.c librtmp/rtmp.c librtmp/rtmp.h parseurl.c parseurl.h rtmpdump.c rtmpgw.c
hyc
subversion at mplayerhq.hu
Mon Mar 8 14:34:11 CET 2010
Author: hyc
Date: Mon Mar 8 14:34:10 2010
New Revision: 306
Log:
C++ compat, move parseurl to librtmp
Added:
trunk/librtmp/parseurl.c
- copied, changed from r305, trunk/parseurl.c
Deleted:
trunk/parseurl.c
trunk/parseurl.h
Modified:
trunk/Makefile
trunk/librtmp/Makefile
trunk/librtmp/amf.h
trunk/librtmp/rtmp.c
trunk/librtmp/rtmp.h
trunk/rtmpdump.c
trunk/rtmpgw.c
Modified: trunk/Makefile
==============================================================================
--- trunk/Makefile Sat Mar 6 20:34:08 2010 (r305)
+++ trunk/Makefile Mon Mar 8 14:34:10 2010 (r306)
@@ -38,7 +38,7 @@ clean:
$(LIBRTMP):
@$(MAKE) -C librtmp all CC="$(CC)" CFLAGS="$(CFLAGS)"
-rtmpdump: rtmpdump.o parseurl.o $(LIBRTMP)
+rtmpdump: rtmpdump.o $(LIBRTMP)
$(CC) $(LDFLAGS) $^ -o $@$(EXT) $(LIBS)
rtmpsrv: rtmpsrv.o thread.o $(LIBRTMP)
@@ -47,10 +47,9 @@ rtmpsrv: rtmpsrv.o thread.o $(LIBRTMP)
rtmpsuck: rtmpsuck.o thread.o $(LIBRTMP)
$(CC) $(LDFLAGS) $^ -o $@$(EXT) $(SLIBS)
-rtmpgw: rtmpgw.o parseurl.o thread.o $(LIBRTMP)
+rtmpgw: rtmpgw.o thread.o $(LIBRTMP)
$(CC) $(LDFLAGS) $^ -o $@$(EXT) $(SLIBS)
-parseurl.o: parseurl.c parseurl.h Makefile
rtmpgw.o: rtmpgw.c librtmp/rtmp.h librtmp/log.h librtmp/amf.h Makefile
rtmpdump.o: rtmpdump.c librtmp/rtmp.h librtmp/log.h librtmp/amf.h Makefile
rtmpsrv.o: rtmpsrv.c librtmp/rtmp.h librtmp/log.h librtmp/amf.h Makefile
Modified: trunk/librtmp/Makefile
==============================================================================
--- trunk/librtmp/Makefile Sat Mar 6 20:34:08 2010 (r305)
+++ trunk/librtmp/Makefile Mon Mar 8 14:34:10 2010 (r306)
@@ -10,10 +10,11 @@ all: librtmp.a
clean:
rm -f *.o *.a
-librtmp.a: rtmp.o log.o amf.o hashswf.o
+librtmp.a: rtmp.o log.o amf.o hashswf.o parseurl.o
$(AR) rs $@ $?
log.o: log.c log.h Makefile
rtmp.o: rtmp.c rtmp.h handshake.h dh.h log.h amf.h Makefile
amf.o: amf.c amf.h bytes.h log.h Makefile
hashswf.o: hashswf.c http.h
+parseurl.o: parseurl.c
Modified: trunk/librtmp/amf.h
==============================================================================
--- trunk/librtmp/amf.h Sat Mar 6 20:34:08 2010 (r305)
+++ trunk/librtmp/amf.h Mon Mar 8 14:34:10 2010 (r306)
@@ -56,12 +56,14 @@ extern "C"
#define AVC(str) {str,sizeof(str)-1}
#define AVMATCH(a1,a2) ((a1)->av_len == (a2)->av_len && !memcmp((a1)->av_val,(a2)->av_val,(a1)->av_len))
+#ifndef __cplusplus
#undef bool
#undef true
#undef false
#define bool int
#define true 1
#define false 0
+#endif
struct AMFObjectProperty;
Copied and modified: trunk/librtmp/parseurl.c (from r305, trunk/parseurl.c)
==============================================================================
--- trunk/parseurl.c Sat Mar 6 20:34:08 2010 (r305, copy source)
+++ trunk/librtmp/parseurl.c Mon Mar 8 14:34:10 2010 (r306)
@@ -1,6 +1,6 @@
/* RTMPDump
* Copyright (C) 2009 Andrej Stepanchuk
- * Copyright (C) 2009 Howard Chu
+ * Copyright (C) 2009-2010 Howard Chu
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,153 +25,78 @@
#include <assert.h>
#include <ctype.h>
-#include "librtmp/log.h"
-#include "parseurl.h"
-
-#define RTMP_PROTOCOL_UNDEFINED -1
-#define RTMP_PROTOCOL_RTMP 0
-#define RTMP_PROTOCOL_RTMPT 1 // not yet supported
-#define RTMP_PROTOCOL_RTMPS 2 // not yet supported
-#define RTMP_PROTOCOL_RTMPE 3
-#define RTMP_PROTOCOL_RTMPTE 4 // not yet supported
-#define RTMP_PROTOCOL_RTMFP 5 // not yet supported
-
-char *str2lower(char *str, int len)
-{
- char *res = (char *)malloc(len+1);
- char *p;
-
- for(p=res; p<res+len; p++, str++) {
- *p = tolower(*str);
- }
-
- *p = 0;
-
- return res;
-}
-
-int chr2hex(char c)
-{
- if(c <= 57 && c >= 48)
- return c-48;
- else if(c <= 102 && c >= 97)
- return c-97+10;
- return -1;
-}
-
-int hex2bin(char *str, char **hex)
-{
- if(!str || !hex)
- return 0;
-
- int len = strlen(str);
-
- if(len % 2 != 0)
- return 0;
-
- int ret = len/2;
-
- *hex = (char *)malloc(ret);
- if((*hex)==0)
- return 0;
-
- char *hexptr = *hex;
- char *lwo = str2lower(str, len);
- char *lw = lwo;
-
- len /= 2;
-
- while(len) {
- int d1 = chr2hex(*lw); lw++;
- int d2 = chr2hex(*lw); lw++;
-
- if(d1<0 || d2<0) {
- free(*hex);
- free(lwo);
- *hex=NULL;
- return -1;
- }
-
- *hexptr = (unsigned char)(d1*16+d2);
- hexptr++;
- len--;
- }
-
- free(lwo);
- return ret;
-}
+#include "rtmp.h"
-int ParseUrl(char *url, int *protocol, char **host, unsigned int *port, char **playpath, char **app)
+bool RTMP_ParseURL(const char *url, int *protocol, char **host, unsigned int *port,
+ AVal *playpath, AVal *app)
{
- assert(url != 0 && protocol != 0 && host != 0 && port != 0 && playpath != 0 && app != 0);
+ char *p, *end, *col, *ques, *slash;
Log(LOGDEBUG, "Parsing...");
- *protocol = 0; // default: RTMP
+ *protocol = RTMP_PROTOCOL_RTMP;
+ playpath->av_len = 0;
+ playpath->av_val = NULL;
+ app->av_len = 0;
+ app->av_val = NULL;
// Old School Parsing
- char *lw = str2lower(url, 6);
- char *temp;
// look for usual :// pattern
- char *p = strstr(url, "://");
- int len = (int)(p-url);
- if(p == 0) {
- Log(LOGWARNING, "RTMP URL: No :// in url!");
- free(lw);
- return 0;
+ p = strstr(url, "://");
+ if(!p) {
+ Log(LOGERROR, "RTMP URL: No :// in url!");
+ return false;
}
+ {
+ int len = (int)(p-url);
- if(len == 4 && strncmp(lw, "rtmp", 4)==0)
+ if(len == 4 && strncasecmp(url, "rtmp", 4)==0)
*protocol = RTMP_PROTOCOL_RTMP;
- else if(len == 5 && strncmp(lw, "rtmpt", 5)==0)
+ else if(len == 5 && strncasecmp(url, "rtmpt", 5)==0)
*protocol = RTMP_PROTOCOL_RTMPT;
- else if(len == 5 && strncmp(lw, "rtmps", 5)==0)
+ else if(len == 5 && strncasecmp(url, "rtmps", 5)==0)
*protocol = RTMP_PROTOCOL_RTMPS;
- else if(len == 5 && strncmp(lw, "rtmpe", 5)==0)
+ else if(len == 5 && strncasecmp(url, "rtmpe", 5)==0)
*protocol = RTMP_PROTOCOL_RTMPE;
- else if(len == 5 && strncmp(lw, "rtmfp", 5)==0)
+ else if(len == 5 && strncasecmp(url, "rtmfp", 5)==0)
*protocol = RTMP_PROTOCOL_RTMFP;
- else if(len == 6 && strncmp(lw, "rtmpte", 6)==0)
+ else if(len == 6 && strncasecmp(url, "rtmpte", 6)==0)
*protocol = RTMP_PROTOCOL_RTMPTE;
else {
Log(LOGWARNING, "Unknown protocol!\n");
goto parsehost;
}
+ }
Log(LOGDEBUG, "Parsed protocol: %d", *protocol);
parsehost:
- free(lw);
-
// lets get the hostname
p+=3;
// check for sudden death
if(*p==0) {
Log(LOGWARNING, "No hostname in URL!");
- return 0;
+ return false;
}
- int iEnd = strlen(p);
- int iCol = iEnd+1;
- int iQues = iEnd+1;
- int iSlash = iEnd+1;
-
- if((temp=strstr(p, ":"))!=0)
- iCol = temp-p;
- if((temp=strstr(p, "?"))!=0)
- iQues = temp-p;
- if((temp=strstr(p, "/"))!=0)
- iSlash = temp-p;
-
- int min = iSlash < iEnd ? iSlash : iEnd+1;
- min = iQues < min ? iQues : min;
+ end = p + strlen(p);
+ col = strchr(p, ':');
+ ques = strchr(p, '?');
+ slash = strchr(p, '/');
- int hostlen = iCol < min ? iCol : min;
+ {
+ int hostlen;
+ if(col)
+ hostlen = col - p;
+ else if(slash)
+ hostlen = slash - p;
+ else
+ hostlen = end - p;
- if(min < 256) {
- *host = (char *)malloc((hostlen+1)*sizeof(char));
+ if(hostlen < 256) {
+ *host = malloc(hostlen+1);
strncpy(*host, p, hostlen);
(*host)[hostlen]=0;
@@ -180,90 +105,76 @@ parsehost:
Log(LOGWARNING, "Hostname exceeds 255 characters!");
}
- p+=hostlen; iEnd-=hostlen;
+ p+=hostlen;
+ }
// get the port number if available
if(*p == ':') {
- p++; iEnd--;
-
- int portlen = min-hostlen-1;
- if(portlen < 6) {
- char portstr[6];
- strncpy(portstr,p,portlen);
- portstr[portlen]=0;
-
- *port = atoi(portstr);
- if(*port == 0)
- *port = 1935;
-
- Log(LOGDEBUG, "Parsed port : %d", *port);
+ p++;
+ unsigned int p2 = atoi(p);
+ if(p2 > 65535) {
+ Log(LOGWARNING, "Invalid port number!");
} else {
- Log(LOGWARNING, "Port number is longer than 5 characters!");
+ if (p2 == 0)
+ p2 = 1935;
+ *port = p2;
}
-
- p+=portlen; iEnd-=portlen;
}
- if(*p != '/') {
+ if(!slash) {
Log(LOGWARNING, "No application or playpath in URL!");
- return 1;
+ return true;
}
- p++; iEnd--;
+ p = slash+1;
+ {
// parse application
//
// rtmp://host[:port]/app[/appinstance][/...]
// application = app[/appinstance]
- int iSlash2 = iEnd+1; // 2nd slash
- int iSlash3 = iEnd+1; // 3rd slash
-
- if((temp=strstr(p, "/"))!=0)
- iSlash2 = temp-p;
- if((temp=strstr(p, "?"))!=0)
- iQues = temp-p;
-
- if(iSlash2 < iEnd)
- if((temp=strstr(p+iSlash2+1, "/"))!=0)
- iSlash3 = temp-p;
+ char *slash2, *slash3 = NULL;
+ int applen, appnamelen;
- //Log(LOGDEBUG, "p:%s, iEnd: %d\niSlash : %d\niSlash2: %d\niSlash3: %d", p, iEnd, iSlash, iSlash2, iSlash3);
+ slash2 = strchr(p, '/');
+ if(slash2)
+ slash3 = strchr(slash2+1, '/');
- int applen = iEnd+1; // ondemand, pass all parameters as app
- int appnamelen = 8; // ondemand length
+ applen = end-p; // ondemand, pass all parameters as app
+ appnamelen = 8; // ondemand length
- if(iQues < iEnd && strstr(p, "slist=")) { // whatever it is, the '?' and slist= means we need to use everything as app and parse plapath from slist=
- appnamelen = iQues;
- applen = iEnd+1; // pass the parameters as well
+ if(ques && strstr(p, "slist=")) { // whatever it is, the '?' and slist= means we need to use everything as app and parse plapath from slist=
+ appnamelen = ques-p;
}
else if(strncmp(p, "ondemand/", 9)==0) {
// app = ondemand/foobar, only pass app=ondemand
applen = 8;
}
else { // app!=ondemand, so app is app[/appinstance]
- appnamelen = iSlash2 < iEnd ? iSlash2 : iEnd;
- if(iSlash3 < iEnd)
- appnamelen = iSlash3;
+ if(slash3)
+ appnamelen = slash3-p;
+ else if(slash2)
+ appnamelen = slash2-p;
applen = appnamelen;
}
- *app = (char *)malloc((applen+1)*sizeof(char));
- strncpy(*app, p, applen);
- (*app)[applen]=0;
- Log(LOGDEBUG, "Parsed app : %s", *app);
+ app->av_val = p;
+ app->av_len = applen;
+ Log(LOGDEBUG, "Parsed app : %.*s", applen, p);
p += appnamelen;
- iEnd -= appnamelen;
-
- if (*p == '/') {
- p += 1;
- iEnd -= 1;
}
- *playpath = ParsePlaypath(p);
+ if (*p == '/')
+ p++;
- return 1;
+ {
+ AVal av = {p, end-p};
+ RTMP_ParsePlaypath(&av, playpath);
+ }
+
+ return true;
}
/*
@@ -271,24 +182,25 @@ parsehost:
* URL, i.e. the part that comes after rtmp://host:port/app/
*
* Returns the stream name in a format understood by FMS. The name is
- * the playpath part of the URL with formating depending on the stream
+ * the playpath part of the URL with formatting depending on the stream
* type:
*
* mp4 streams: prepend "mp4:", remove extension
* mp3 streams: prepend "mp3:", remove extension
* flv streams: remove extension
*/
-char *ParsePlaypath(const char *playpath) {
- if (!playpath || !*playpath)
- return NULL;
-
+void RTMP_ParsePlaypath(AVal *in, AVal *out) {
int addMP4 = 0;
int addMP3 = 0;
int subExt = 0;
+ const char *playpath = in->av_val;
const char *temp, *q, *ext = NULL;
const char *ppstart = playpath;
- int pplen = strlen(playpath);
+ int pplen = in->av_len;
+
+ out->av_val = NULL;
+ out->av_len = 0;
if ((*ppstart == '?') &&
(temp=strstr(ppstart, "slist=")) != 0) {
@@ -323,7 +235,7 @@ char *ParsePlaypath(const char *playpath
char *streamname = (char *)malloc((pplen+4+1)*sizeof(char));
if (!streamname)
- return NULL;
+ return;
char *destptr = streamname, *p;
if (addMP4 && (strncmp(ppstart, "mp4:", 4) != 0)) {
@@ -353,5 +265,6 @@ char *ParsePlaypath(const char *playpath
}
*destptr = '\0';
- return streamname;
+ out->av_val = streamname;
+ out->av_len = destptr - streamname;
}
Modified: trunk/librtmp/rtmp.c
==============================================================================
--- trunk/librtmp/rtmp.c Sat Mar 6 20:34:08 2010 (r305)
+++ trunk/librtmp/rtmp.c Mon Mar 8 14:34:10 2010 (r306)
@@ -231,7 +231,7 @@ RTMP_SetupStream(RTMP * r,
if (pageUrl)
Log(LOGDEBUG, "pageUrl : %s", pageUrl->av_val);
if (app)
- Log(LOGDEBUG, "app : %s", app->av_val);
+ Log(LOGDEBUG, "app : %.*s", app->av_len, app->av_val);
if (auth)
Log(LOGDEBUG, "auth : %s", auth->av_val);
if (subscribepath)
@@ -282,14 +282,20 @@ RTMP_SetupStream(RTMP * r,
r->Link.socksport = 0;
}
-
- r->Link.tcUrl = *tcUrl;
- r->Link.swfUrl = *swfUrl;
- r->Link.pageUrl = *pageUrl;
- r->Link.app = *app;
- r->Link.auth = *auth;
- r->Link.flashVer = *flashVer;
- r->Link.subscribepath = *subscribepath;
+ if (tcUrl)
+ r->Link.tcUrl = *tcUrl;
+ if (swfUrl)
+ r->Link.swfUrl = *swfUrl;
+ if (pageUrl)
+ r->Link.pageUrl = *pageUrl;
+ if (app)
+ r->Link.app = *app;
+ if (auth)
+ r->Link.auth = *auth;
+ if (flashVer)
+ r->Link.flashVer = *flashVer;
+ if (subscribepath)
+ r->Link.subscribepath = *subscribepath;
r->Link.seekTime = dTime;
r->Link.length = dLength;
r->Link.bLiveStream = bLiveStream;
Modified: trunk/librtmp/rtmp.h
==============================================================================
--- trunk/librtmp/rtmp.h Sat Mar 6 20:34:08 2010 (r305)
+++ trunk/librtmp/rtmp.h Mon Mar 8 14:34:10 2010 (r306)
@@ -54,6 +54,10 @@
#include "log.h"
#include "amf.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#define RTMP_PROTOCOL_UNDEFINED -1
#define RTMP_PROTOCOL_RTMP 0
#define RTMP_PROTOCOL_RTMPT 1 // not yet supported
@@ -140,14 +144,15 @@ typedef struct RTMP_LNK
AVal flashVer;
AVal subscribepath;
AVal token;
- bool authflag;
+ AVal playpath0;
AMFObject extras;
double seekTime;
uint32_t length;
+ bool authflag;
bool bLiveStream;
- long int timeout; // number of seconds before connection times out
+ int timeout; // number of seconds before connection times out
const char *sockshost;
unsigned short socksport;
@@ -205,6 +210,9 @@ typedef struct RTMP
#define m_bTimedout m_sb.sb_timedout
} RTMP;
+bool RTMP_ParseURL(const char *url, int *protocol, char **host,
+ unsigned int *port, AVal *playpath, AVal *app);
+void RTMP_ParsePlaypath(AVal *in, AVal *out);
void RTMP_SetBufferMS(RTMP *r, int size);
void RTMP_UpdateBufferMS(RTMP *r);
@@ -265,4 +273,8 @@ void RTMP_DropRequest(RTMP *r, int i, bo
int RTMP_HashSWF(const char *url, unsigned int *size, unsigned char *hash, int age);
#endif
+#ifdef __cplusplus
+};
+#endif
+
#endif
Modified: trunk/rtmpdump.c
==============================================================================
--- trunk/rtmpdump.c Sat Mar 6 20:34:08 2010 (r305)
+++ trunk/rtmpdump.c Mon Mar 8 14:34:10 2010 (r306)
@@ -31,7 +31,6 @@
#include "librtmp/rtmp.h"
#include "librtmp/log.h"
-#include "parseurl.h"
#ifdef WIN32
#define fseeko fseeko64
@@ -99,6 +98,25 @@ sigIntHandler(int sig)
#endif
}
+#define HEX2BIN(a) (((a)&0x40)?((a)&0xf)+9:((a)&0xf))
+int hex2bin(char *str, char **hex)
+{
+ char *ptr;
+ int i, l = strlen(str);
+
+ if (l & 1)
+ return 0;
+
+ *hex = malloc(l/2);
+ ptr = *hex;
+ if (!ptr)
+ return 0;
+
+ for (i=0; i<l; i+=2)
+ *ptr++ = (HEX2BIN(str[i]) << 4) | HEX2BIN(str[i+1]);
+ return l/2;
+}
+
int
WriteHeader(char **buf, // target pointer, maybe preallocated
unsigned int len // length of buffer if preallocated
@@ -1485,15 +1503,14 @@ main(int argc, char **argv)
break;
case 'r':
{
- rtmpurl = optarg;
+ AVal parsedApp, parsedPlaypath;
char *parsedHost = 0;
unsigned int parsedPort = 0;
- char *parsedPlaypath = 0;
- char *parsedApp = 0;
int parsedProtocol = RTMP_PROTOCOL_UNDEFINED;
- if (!ParseUrl
+ rtmpurl = optarg;
+ if (!RTMP_ParseURL
(rtmpurl, &parsedProtocol, &parsedHost, &parsedPort,
&parsedPlaypath, &parsedApp))
{
@@ -1506,15 +1523,15 @@ main(int argc, char **argv)
hostname = parsedHost;
if (port == -1)
port = parsedPort;
- if (playpath.av_len == 0 && parsedPlaypath)
+ if (playpath.av_len == 0 && parsedPlaypath.av_len)
{
- STR2AVAL(playpath, parsedPlaypath);
+ playpath = parsedPlaypath;
}
if (protocol == RTMP_PROTOCOL_UNDEFINED)
protocol = parsedProtocol;
- if (app.av_len == 0 && parsedApp)
+ if (app.av_len == 0 && parsedApp.av_len)
{
- STR2AVAL(app, parsedApp);
+ app = parsedApp;
}
}
break;
Modified: trunk/rtmpgw.c
==============================================================================
--- trunk/rtmpgw.c Sat Mar 6 20:34:08 2010 (r305)
+++ trunk/rtmpgw.c Mon Mar 8 14:34:10 2010 (r306)
@@ -29,7 +29,6 @@
#include <assert.h>
#include "librtmp/rtmp.h"
-#include "parseurl.h"
#include "thread.h"
@@ -976,6 +975,25 @@ sigIntHandler(int sig)
signal(SIGINT, SIG_DFL);
}
+#define HEX2BIN(a) (((a)&0x40)?((a)&0xf)+9:((a)&0xf))
+int hex2bin(char *str, char **hex)
+{
+ char *ptr;
+ int i, l = strlen(str);
+
+ if (l & 1)
+ return 0;
+
+ *hex = malloc(l/2);
+ ptr = *hex;
+ if (!ptr)
+ return 0;
+
+ for (i=0; i<l; i+=2)
+ *ptr++ = (HEX2BIN(str[i]) << 4) | HEX2BIN(str[i+1]);
+ return l/2;
+}
+
// this will parse RTMP related options as needed
// excludes the following options: h, d, g
@@ -1081,13 +1099,12 @@ ParseOption(char opt, char *arg, RTMP_RE
{
req->rtmpurl = arg;
+ AVal parsedPlaypath, parsedApp;
char *parsedHost = 0;
unsigned int parsedPort = 0;
- char *parsedPlaypath = 0;
- char *parsedApp = 0;
int parsedProtocol = RTMP_PROTOCOL_UNDEFINED;
- if (!ParseUrl
+ if (!RTMP_ParseURL
(req->rtmpurl, &parsedProtocol, &parsedHost, &parsedPort,
&parsedPlaypath, &parsedApp))
{
@@ -1099,15 +1116,15 @@ ParseOption(char opt, char *arg, RTMP_RE
req->hostname = parsedHost;
if (req->rtmpport == -1)
req->rtmpport = parsedPort;
- if (req->playpath.av_len == 0 && parsedPlaypath)
+ if (req->playpath.av_len == 0 && parsedPlaypath.av_len)
{
- STR2AVAL(req->playpath, parsedPlaypath);
+ req->playpath = parsedPlaypath;
}
if (req->protocol == RTMP_PROTOCOL_UNDEFINED)
req->protocol = parsedProtocol;
- if (req->app.av_len == 0 && parsedApp)
+ if (req->app.av_len == 0 && parsedApp.av_len)
{
- STR2AVAL(req->app, parsedApp);
+ req->app = parsedApp;
}
}
break;
More information about the rtmpdump
mailing list