[PATCH] Better URL decoding support
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. --- librtmp/parseurl.c | 73 +++++++++++++++++++++++++++++++++++++--------------- librtmp/rtmp.h | 1 + rtmpdump.c | 1 + rtmpgw.c | 47 --------------------------------- 4 files changed, 54 insertions(+), 68 deletions(-) diff --git a/librtmp/parseurl.c b/librtmp/parseurl.c index 57abfe7..07fbbb9 100644 --- a/librtmp/parseurl.c +++ b/librtmp/parseurl.c @@ -206,7 +206,7 @@ void RTMP_ParsePlaypath(AVal *in, AVal *out) { const char *playpath = in->av_val; const char *temp, *q, *ext = NULL; const char *ppstart = playpath; - char *streamname, *destptr, *p; + char *streamname, *destptr; int pplen = in->av_len; @@ -265,26 +265,57 @@ void RTMP_ParsePlaypath(AVal *in, AVal *out) { } } - for (p=(char *)ppstart; pplen >0;) { - /* skip extension */ - if (subExt && p == ext) { - p += 4; - pplen -= 4; - continue; - } - if (*p == '%') { - unsigned int c; - sscanf(p+1, "%02x", &c); - *destptr++ = c; - pplen -= 3; - p += 3; - } else { - *destptr++ = *p++; - pplen--; - } - } - *destptr = '\0'; + memcpy(destptr, ppstart, pplen * sizeof(char)); + destptr[pplen] = '\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
participants (5)
-
compn -
Howard Chu -
NhJm -
Steven Penny -
xspeed1989