[FFmpeg-devel] [PATCH] http: handle URLs with spaces

wm4 nfxjfg at googlemail.com
Fri Jan 31 15:35:22 CET 2014


This fixes making HTTP requests with URLs that contain spaces.

I'm not sure how much of the URL should be escaped in general, but
sending unescaped spaces as part of an URL is always invalid.

---

Not sure if this sufficient in general; maybe we should do more
complete escaping according to RFC 2396, but maybe there's the danger
of escaping valid syntax elements of an URL and changing its semantics.
RFC 2396 contains some wording that escaping normally can't be done
safely after the URL is constructed. Maybe someone who knows the
standard better can comment on this.

For now and purely practically speaking, this commit doesn't make
anything worse, even if it's not perfectly correct: spaces can never
work, because the request header uses spaces to separate URL and
other elements.

---
 libavformat/http.c | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/libavformat/http.c b/libavformat/http.c
index 69c4d6d..ae4c499 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -597,6 +597,27 @@ static int http_read_header(URLContext *h, int *new_location)
     return err;
 }
 
+static void escape_spaces(char *dst, size_t dst_size, const char *src)
+{
+    size_t src_pos = 0;
+    size_t dst_pos = 0;
+    if (dst_size < 1)
+        return;
+    while (dst_pos + 1 < dst_size && src[src_pos]) {
+        if (src[src_pos] == ' ') {
+            if (dst_pos + 3 >= dst_size)
+                break;
+            dst[dst_pos++] = '%';
+            dst[dst_pos++] = '2';
+            dst[dst_pos++] = '0';
+        } else {
+            dst[dst_pos++] = src[src_pos];
+        }
+        src_pos++;
+    }
+    dst[dst_pos] = '\0';
+}
+
 static int http_connect(URLContext *h, const char *path, const char *local_path,
                         const char *hoststr, const char *auth,
                         const char *proxyauth, int *new_location)
@@ -604,6 +625,7 @@ static int http_connect(URLContext *h, const char *path, const char *local_path,
     HTTPContext *s = h->priv_data;
     int post, err;
     char headers[4096] = "";
+    char url[MAX_URL_SIZE];
     char *authstr = NULL, *proxyauthstr = NULL;
     int64_t off = s->off;
     int len = 0;
@@ -697,6 +719,8 @@ static int http_connect(URLContext *h, const char *path, const char *local_path,
     if (s->headers)
         av_strlcpy(headers + len, s->headers, sizeof(headers) - len);
 
+    escape_spaces(url, sizeof(url), path);
+
     snprintf(s->buffer, sizeof(s->buffer),
              "%s %s HTTP/1.1\r\n"
              "%s"
@@ -705,7 +729,7 @@ static int http_connect(URLContext *h, const char *path, const char *local_path,
              "%s%s"
              "\r\n",
              method,
-             path,
+             url,
              post && s->chunked_post ? "Transfer-Encoding: chunked\r\n" : "",
              headers,
              authstr ? authstr : "",
-- 
1.8.5.2



More information about the ffmpeg-devel mailing list