[rtmpdump] [PATCH v2] Better URL decoding support

Steven Penny svnpenn at gmail.com
Thu Oct 25 06:31:19 CEST 2012


Currently RtmpDump has limited URL decoding support. If you use Bastien’s patch
as shown here
http://lists.mplayerhq.hu/pipermail/rtmpdump/2012-September/002093.html
You can pass encoded characters like this

  rtmpdump -o a.flv -i "rtmp://server.com/app playpath=foobar\0a"

Where "\0a" will be decoded as a newline.

Also the Playpath can be decoded using an unpatched RtmpDump, as long as it is
part of the "-r" parameter and properly parsed. Example

  rtmpdump -o a.flv -r rtmp://server.com/app/foobar%0a

Where "%0a" will be decoded as a newline. This presents two problems. One, many
times RtmpDump is unable to correctly parse the Playpath, mixing it with the
"app". Two, if you explicitly state the Playpath with "-y", you lose the URL
decoding support. I have simply moved the URL decoding function that Howard
wrote to parseurl.c and declared it in rtmp.h, so that it can be used across the
project. This patch also address concerns here
http://lists.mplayerhq.hu/pipermail/rtmpdump/2012-October/002112.html
---
 librtmp/parseurl.c |   62 ++++++++++++++++++++++++++++++++++++++++++---------
 librtmp/rtmp.h     |    1 +
 rtmpdump.c         |    1 +
 rtmpgw.c           |   47 ---------------------------------------
 4 files changed, 53 insertions(+), 58 deletions(-)

diff --git a/librtmp/parseurl.c b/librtmp/parseurl.c
index 57abfe7..aef1f3a 100644
--- a/librtmp/parseurl.c
+++ b/librtmp/parseurl.c
@@ -272,19 +272,59 @@ void RTMP_ParsePlaypath(AVal *in, AVal *out) {
 			pplen -= 4;
 			continue;
 		}
-		if (*p == '%') {
-			unsigned int c;
-			sscanf(p+1, "%02x", &c);
-			*destptr++ = c;
-			pplen -= 3;
-			p += 3;
-		} else {
-			*destptr++ = *p++;
-			pplen--;
-		}
+		*destptr++ = *p++;
+		pplen--;
 	}
 	*destptr = '\0';
+	http_unescape(streamname);
 
 	out->av_val = streamname;
-	out->av_len = destptr - streamname;
+	out->av_len = strlen(streamname);
+}
+
+/* inplace http unescape. This is possible .. strlen(unescaped_string)  <= strlen(esacped_string) */
+void
+http_unescape(char *data)
+{
+  char hex[3];
+  char *stp;
+  int src_x = 0;
+  int dst_x = 0;
+
+  int length = (int) strlen(data);
+  hex[2] = 0;
+
+  while (src_x < length)
+    {
+      if (strncmp(data + src_x, "%", 1) == 0 && src_x + 2 < length)
+	{
+	  //
+	  // Since we encountered a '%' we know this is an escaped character
+	  //
+	  hex[0] = data[src_x + 1];
+	  hex[1] = data[src_x + 2];
+	  data[dst_x] = (char) strtol(hex, &stp, 16);
+	  dst_x += 1;
+	  src_x += 3;
+	}
+      else if (src_x != dst_x)
+	{
+	  //
+	  // This doesn't need to be unescaped. If we didn't unescape anything previously
+	  // there is no need to copy the string either
+	  //
+	  data[dst_x] = data[src_x];
+	  src_x += 1;
+	  dst_x += 1;
+	}
+      else
+	{
+	  //
+	  // This doesn't need to be unescaped, however we need to copy the string
+	  //
+	  src_x += 1;
+	  dst_x += 1;
+	}
+    }
+  data[dst_x] = '\0';
 }
diff --git a/librtmp/rtmp.h b/librtmp/rtmp.h
index bd85a17..242a536 100644
--- a/librtmp/rtmp.h
+++ b/librtmp/rtmp.h
@@ -285,6 +285,7 @@ extern "C"
 		     unsigned int *port, AVal *playpath, AVal *app);
 
   void RTMP_ParsePlaypath(AVal *in, AVal *out);
+  void http_unescape(char *data);
   void RTMP_SetBufferMS(RTMP *r, int size);
   void RTMP_UpdateBufferMS(RTMP *r);
 
diff --git a/rtmpdump.c b/rtmpdump.c
index e52f7d4..a6cbdfd 100644
--- a/rtmpdump.c
+++ b/rtmpdump.c
@@ -963,6 +963,7 @@ main(int argc, char **argv)
 	    }
 	  break;
 	case 'y':
+	  http_unescape(optarg);
 	  STR2AVAL(playpath, optarg);
 	  break;
 	case 'Y':
diff --git a/rtmpgw.c b/rtmpgw.c
index 0cf56bb..50b8c2a 100644
--- a/rtmpgw.c
+++ b/rtmpgw.c
@@ -220,53 +220,6 @@ FILE *netstackdump = NULL;
 FILE *netstackdump_read = NULL;
 #endif
 
-/* inplace http unescape. This is possible .. strlen(unescaped_string)  <= strlen(esacped_string) */
-void
-http_unescape(char *data)
-{
-  char hex[3];
-  char *stp;
-  int src_x = 0;
-  int dst_x = 0;
-
-  int length = (int) strlen(data);
-  hex[2] = 0;
-
-  while (src_x < length)
-    {
-      if (strncmp(data + src_x, "%", 1) == 0 && src_x + 2 < length)
-	{
-	  //
-	  // Since we encountered a '%' we know this is an escaped character
-	  //
-	  hex[0] = data[src_x + 1];
-	  hex[1] = data[src_x + 2];
-	  data[dst_x] = (char) strtol(hex, &stp, 16);
-	  dst_x += 1;
-	  src_x += 3;
-	}
-      else if (src_x != dst_x)
-	{
-	  //
-	  // This doesn't need to be unescaped. If we didn't unescape anything previously
-	  // there is no need to copy the string either
-	  //
-	  data[dst_x] = data[src_x];
-	  src_x += 1;
-	  dst_x += 1;
-	}
-      else
-	{
-	  //
-	  // This doesn't need to be unescaped, however we need to copy the string
-	  //
-	  src_x += 1;
-	  dst_x += 1;
-	}
-    }
-  data[dst_x] = '\0';
-}
-
 TFTYPE
 controlServerThread(void *unused)
 {
-- 
1.7.9



More information about the rtmpdump mailing list