]> granicus.if.org Git - rtmpdump/commitdiff
C++ compat, move parseurl to librtmp
authorhyc <hyc@400ebc74-4327-4243-bc38-086b20814532>
Mon, 8 Mar 2010 13:34:10 +0000 (13:34 +0000)
committerhyc <hyc@400ebc74-4327-4243-bc38-086b20814532>
Mon, 8 Mar 2010 13:34:10 +0000 (13:34 +0000)
git-svn-id: svn://svn.mplayerhq.hu/rtmpdump/trunk@306 400ebc74-4327-4243-bc38-086b20814532

Makefile
librtmp/Makefile
librtmp/amf.h
librtmp/parseurl.c [new file with mode: 0644]
librtmp/rtmp.c
librtmp/rtmp.h
parseurl.c [deleted file]
parseurl.h [deleted file]
rtmpdump.c
rtmpgw.c

index 9febe9372b61564567508e6855d5e76faf751b24..d9bf1f513fa383726f7646da810dd4169ffd7034 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -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
index 759cab98efa0cffa89f4e6aaa3a14b1ec36b2fcf..a7145599e75dee9b8344d40bdd7ae10e057427a1 100644 (file)
@@ -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
index 9b3db8e1e7cb6f7eaa6663fa5c1f9067eb8e52ee..59e63455f39c8977d23276af253f79120f14d697 100644 (file)
@@ -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;
 
diff --git a/librtmp/parseurl.c b/librtmp/parseurl.c
new file mode 100644 (file)
index 0000000..6e1b238
--- /dev/null
@@ -0,0 +1,270 @@
+/*  RTMPDump
+ *  Copyright (C) 2009 Andrej Stepanchuk
+ *  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
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program 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
+ *  along with RTMPDump; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <assert.h>
+#include <ctype.h>
+
+#include "rtmp.h"
+
+bool RTMP_ParseURL(const char *url, int *protocol, char **host, unsigned int *port,
+       AVal *playpath, AVal *app)
+{
+       char *p, *end, *col, *ques, *slash;
+
+       Log(LOGDEBUG, "Parsing...");
+
+       *protocol = RTMP_PROTOCOL_RTMP;
+       playpath->av_len = 0;
+       playpath->av_val = NULL;
+       app->av_len = 0;
+       app->av_val = NULL;
+
+       // Old School Parsing
+
+       // look for usual :// pattern
+       p = strstr(url, "://");
+       if(!p) {
+               Log(LOGERROR, "RTMP URL: No :// in url!");
+               return false;
+       }
+       {
+       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 {
+               Log(LOGWARNING, "Unknown protocol!\n");
+               goto parsehost;
+       }
+       }
+
+       Log(LOGDEBUG, "Parsed protocol: %d", *protocol);
+
+parsehost:
+       // lets get the hostname
+       p+=3;
+
+       // check for sudden death
+       if(*p==0) {
+               Log(LOGWARNING, "No hostname in URL!");
+               return false;
+       }
+
+       end   = p + strlen(p);
+       col   = strchr(p, ':');
+       ques  = strchr(p, '?');
+       slash = strchr(p, '/');
+
+       {
+       int hostlen;
+       if(col)
+               hostlen = col - p;
+       else if(slash)
+               hostlen = slash - p;
+       else
+               hostlen = end - p;
+
+       if(hostlen < 256) {
+               *host = malloc(hostlen+1);
+               strncpy(*host, p, hostlen);
+               (*host)[hostlen]=0;
+
+               Log(LOGDEBUG, "Parsed host    : %s", *host);
+       } else {
+               Log(LOGWARNING, "Hostname exceeds 255 characters!");
+       }
+
+       p+=hostlen;
+       }
+
+       // get the port number if available
+       if(*p == ':') {
+               p++;
+               unsigned int p2 = atoi(p);
+               if(p2 > 65535) {
+                       Log(LOGWARNING, "Invalid port number!");
+               } else {
+                       if (p2 == 0)
+                               p2 = 1935;
+                       *port = p2;
+               }
+       }
+
+       if(!slash) {
+               Log(LOGWARNING, "No application or playpath in URL!");
+               return true;
+       }
+       p = slash+1;
+
+       {
+       // parse application
+       //
+       // rtmp://host[:port]/app[/appinstance][/...]
+       // application = app[/appinstance]
+
+       char *slash2, *slash3 = NULL;
+       int applen, appnamelen;
+
+       slash2 = strchr(p, '/');
+       if(slash2)
+               slash3 = strchr(slash2+1, '/');
+
+       applen = end-p; // ondemand, pass all parameters as app
+       appnamelen = 8; // ondemand length
+
+       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]
+               if(slash3)
+                       appnamelen = slash3-p;
+               else if(slash2)
+                       appnamelen = slash2-p;
+
+               applen = appnamelen;
+       }
+
+       app->av_val = p;
+       app->av_len = applen;
+       Log(LOGDEBUG, "Parsed app     : %.*s", applen, p);
+
+       p += appnamelen;
+       }
+
+       if (*p == '/')
+               p++;
+
+       {
+       AVal av = {p, end-p};
+       RTMP_ParsePlaypath(&av, playpath);
+       }
+
+       return true;
+}
+
+/*
+ * Extracts playpath from RTMP URL. playpath is the file part of the
+ * 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 formatting depending on the stream
+ * type:
+ *
+ * mp4 streams: prepend "mp4:", remove extension
+ * mp3 streams: prepend "mp3:", remove extension
+ * flv streams: remove extension
+ */
+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 = in->av_len;
+
+       out->av_val = NULL;
+       out->av_len = 0;
+
+       if ((*ppstart == '?') &&
+           (temp=strstr(ppstart, "slist=")) != 0) {
+               ppstart = temp+6;
+               pplen = strlen(ppstart);
+
+               temp = strchr(ppstart, '&');
+               if (temp) {
+                       pplen = temp-ppstart;
+               }
+       }
+
+       q = strchr(ppstart, '?');
+       if (pplen >= 4) {
+               if (q)
+                       ext = q-4;
+               else
+                       ext = &ppstart[pplen-4];
+               if ((strncmp(ext, ".f4v", 4) == 0) ||
+                   (strncmp(ext, ".mp4", 4) == 0)) {
+                       addMP4 = 1;
+                       subExt = 1;
+               // Only remove .flv from rtmp URL, not slist params
+               } else if ((ppstart == playpath) &&
+                   (strncmp(ext, ".flv", 4) == 0)) {
+                       subExt = 1;
+               } else if (strncmp(ext, ".mp3", 4) == 0) {
+                       addMP3 = 1;
+                       subExt = 1;
+               }
+       }
+
+       char *streamname = (char *)malloc((pplen+4+1)*sizeof(char));
+       if (!streamname)
+               return;
+
+       char *destptr = streamname, *p;
+       if (addMP4 && (strncmp(ppstart, "mp4:", 4) != 0)) {
+               strcpy(destptr, "mp4:");
+               destptr += 4;
+       } else if (addMP3 && (strncmp(ppstart, "mp3:", 4) != 0)) {
+               strcpy(destptr, "mp3:");
+               destptr += 4;
+       }
+
+       for (p=(char *)ppstart; pplen >0;) {
+               /* skip extension */
+               if (subExt && p == ext) {
+                       p += 4;
+                       pplen -= 4;
+               }
+               if (*p == '%') {
+                       int c;
+                       sscanf(p+1, "%02x", &c);
+                       *destptr++ = c;
+                       pplen -= 3;
+                       p += 3;
+               } else {
+                       *destptr++ = *p++;
+                       pplen--;
+               }
+       }
+       *destptr = '\0';
+
+       out->av_val = streamname;
+       out->av_len = destptr - streamname;
+}
index 2b1084fdf81bb6a9b271239ca85eb4f6d30ed2cc..34ee05dfcbd3df6576ea8ef8e9a267ebd658e8e7 100644 (file)
@@ -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;
index cc243e077c8bd502c779bbec99de9e52c1e807c5..8bb9cebbc5c4a4ebec322d028e899593dd75ee59 100644 (file)
 #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, bool freeit);
 int RTMP_HashSWF(const char *url, unsigned int *size, unsigned char *hash, int age);
 #endif
 
+#ifdef __cplusplus
+};
+#endif
+
 #endif
diff --git a/parseurl.c b/parseurl.c
deleted file mode 100644 (file)
index d662fe7..0000000
+++ /dev/null
@@ -1,357 +0,0 @@
-/*  RTMPDump
- *  Copyright (C) 2009 Andrej Stepanchuk
- *  Copyright (C) 2009 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
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program 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
- *  along with RTMPDump; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#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;
-}
-
-int ParseUrl(char *url, int *protocol, char **host, unsigned int *port, char **playpath, char **app)
-{
-       assert(url != 0 && protocol != 0 && host != 0 && port != 0 && playpath != 0 && app != 0);
-
-       Log(LOGDEBUG, "Parsing...");
-
-       *protocol = 0; // default: RTMP
-
-       // 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;
-       }
-
-       if(len == 4 && strncmp(lw, "rtmp", 4)==0)
-               *protocol = RTMP_PROTOCOL_RTMP;
-       else if(len == 5 && strncmp(lw, "rtmpt", 5)==0)
-               *protocol = RTMP_PROTOCOL_RTMPT;
-       else if(len == 5 && strncmp(lw, "rtmps", 5)==0)
-               *protocol = RTMP_PROTOCOL_RTMPS;
-       else if(len == 5 && strncmp(lw, "rtmpe", 5)==0)
-               *protocol = RTMP_PROTOCOL_RTMPE;
-       else if(len == 5 && strncmp(lw, "rtmfp", 5)==0)
-               *protocol = RTMP_PROTOCOL_RTMFP;
-       else if(len == 6 && strncmp(lw, "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;
-       }
-
-       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;
-
-       int hostlen = iCol < min ? iCol : min;
-
-       if(min < 256) {
-               *host = (char *)malloc((hostlen+1)*sizeof(char));
-               strncpy(*host, p, hostlen);
-               (*host)[hostlen]=0;
-
-               Log(LOGDEBUG, "Parsed host    : %s", *host);
-       } else {
-               Log(LOGWARNING, "Hostname exceeds 255 characters!");
-       }
-
-       p+=hostlen; iEnd-=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);
-               } else {
-                       Log(LOGWARNING, "Port number is longer than 5 characters!");
-               }
-
-               p+=portlen; iEnd-=portlen;
-       }
-
-       if(*p != '/') {
-               Log(LOGWARNING, "No application or playpath in URL!");
-               return 1;
-       }
-       p++; iEnd--;
-
-       // 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;
-
-       //Log(LOGDEBUG, "p:%s, iEnd: %d\niSlash : %d\niSlash2: %d\niSlash3: %d", p, iEnd, iSlash, iSlash2, iSlash3);
-
-       int applen = iEnd+1; // ondemand, pass all parameters as app
-       int 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
-       }
-       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;
-
-               applen = appnamelen;
-       }
-
-       *app = (char *)malloc((applen+1)*sizeof(char));
-       strncpy(*app, p, applen);
-       (*app)[applen]=0;
-       Log(LOGDEBUG, "Parsed app     : %s", *app);
-
-       p += appnamelen;
-       iEnd -= appnamelen;
-
-       if (*p == '/') {
-               p += 1;
-               iEnd -= 1;
-       }
-
-       *playpath = ParsePlaypath(p);
-
-        return 1;
-}
-
-/*
- * Extracts playpath from RTMP URL. playpath is the file part of the
- * 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
- * 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;
-
-       int addMP4 = 0;
-       int addMP3 = 0;
-       int subExt = 0;
-       const char *temp, *q, *ext = NULL;
-       const char *ppstart = playpath;
-
-       int pplen = strlen(playpath);
-
-       if ((*ppstart == '?') &&
-           (temp=strstr(ppstart, "slist=")) != 0) {
-               ppstart = temp+6;
-               pplen = strlen(ppstart);
-
-               temp = strchr(ppstart, '&');
-               if (temp) {
-                       pplen = temp-ppstart;
-               }
-       }
-
-       q = strchr(ppstart, '?');
-       if (pplen >= 4) {
-               if (q)
-                       ext = q-4;
-               else
-                       ext = &ppstart[pplen-4];
-               if ((strncmp(ext, ".f4v", 4) == 0) ||
-                   (strncmp(ext, ".mp4", 4) == 0)) {
-                       addMP4 = 1;
-                       subExt = 1;
-               // Only remove .flv from rtmp URL, not slist params
-               } else if ((ppstart == playpath) &&
-                   (strncmp(ext, ".flv", 4) == 0)) {
-                       subExt = 1;
-               } else if (strncmp(ext, ".mp3", 4) == 0) {
-                       addMP3 = 1;
-                       subExt = 1;
-               }
-       }
-
-       char *streamname = (char *)malloc((pplen+4+1)*sizeof(char));
-       if (!streamname)
-               return NULL;
-
-       char *destptr = streamname, *p;
-       if (addMP4 && (strncmp(ppstart, "mp4:", 4) != 0)) {
-               strcpy(destptr, "mp4:");
-               destptr += 4;
-       } else if (addMP3 && (strncmp(ppstart, "mp3:", 4) != 0)) {
-               strcpy(destptr, "mp3:");
-               destptr += 4;
-       }
-
-       for (p=(char *)ppstart; pplen >0;) {
-               /* skip extension */
-               if (subExt && p == ext) {
-                       p += 4;
-                       pplen -= 4;
-               }
-               if (*p == '%') {
-                       int c;
-                       sscanf(p+1, "%02x", &c);
-                       *destptr++ = c;
-                       pplen -= 3;
-                       p += 3;
-               } else {
-                       *destptr++ = *p++;
-                       pplen--;
-               }
-       }
-       *destptr = '\0';
-
-       return streamname;
-}
diff --git a/parseurl.h b/parseurl.h
deleted file mode 100644 (file)
index bf5d9f3..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef _PARSEURL_H_
-#define _PARSEURL_H_
-/*  RTMPDump
- *  Copyright (C) 2009 Andrej Stepanchuk
- *  Copyright (C) 2009 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
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program 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
- *  along with RTMPDump; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-int hex2bin(char *str, char **hex);
-int ParseUrl(char *url, int *protocol, char **host, unsigned int *port, char **playpath, char **app);
-char *ParsePlaypath(const char *playpath);
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
index 21aa54f5d5fb6068a939951f52e545e1b62e35a9..84d33059a4d4ac52bbd00701d5d419ea8aec1575 100644 (file)
@@ -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;
index 2232af32a868511e97598426c90c7d950909488d..f7847f1157d897602953bc92d5b902d47f506e70 100644 (file)
--- a/rtmpgw.c
+++ b/rtmpgw.c
@@ -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_REQUEST * req)
       {
        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_REQUEST * req)
              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;