[vlc-commits] https: fix receiving multiple cookies (fixes #16181)

Rémi Denis-Courmont git at videolan.org
Mon Dec 21 21:47:01 CET 2015


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Mon Dec 21 22:46:40 2015 +0200| [a9984c5b502860b3491a9e21b4de74c875e9d0d0] | committer: Rémi Denis-Courmont

https: fix receiving multiple cookies (fixes #16181)

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=a9984c5b502860b3491a9e21b4de74c875e9d0d0
---

 modules/access/http/connmgr.c   |   30 +++++-------------------
 modules/access/http/connmgr.h   |    4 +---
 modules/access/http/file_test.c |   19 ++++++++--------
 modules/access/http/message.c   |   48 +++++++++++++++++++++++++++++++++++++++
 modules/access/http/message.h   |    7 ++++++
 modules/access/http/resource.c  |    3 +--
 6 files changed, 73 insertions(+), 38 deletions(-)

diff --git a/modules/access/http/connmgr.c b/modules/access/http/connmgr.c
index 3893b12..d0c0435 100644
--- a/modules/access/http/connmgr.c
+++ b/modules/access/http/connmgr.c
@@ -25,7 +25,6 @@
 #include <assert.h>
 #include <vlc_common.h>
 #include <vlc_tls.h>
-#include <vlc_http.h>
 #include <vlc_interrupt.h>
 #include "transport.h"
 #include "conn.h"
@@ -135,7 +134,7 @@ struct vlc_http_mgr
 {
     vlc_object_t *obj;
     vlc_tls_creds_t *creds;
-    vlc_http_cookie_jar_t *jar;
+    struct vlc_http_cookie_jar_t *jar;
     struct vlc_http_conn *conn;
     bool use_h2c;
 };
@@ -272,23 +271,10 @@ struct vlc_http_msg *vlc_http_mgr_request(struct vlc_http_mgr *mgr, bool https,
     return (https ? vlc_https_request : vlc_http_request)(mgr, host, port, m);
 }
 
-int vlc_http_mgr_send_cookies(struct vlc_http_mgr *mgr, bool https,
-                              const char *host, const char *path,
+int vlc_http_mgr_send_cookies(struct vlc_http_mgr *mgr,
                               struct vlc_http_msg *req)
 {
-    int ret = 0;
-
-    if (mgr->jar != NULL)
-    {
-        char *cookies = vlc_http_cookies_fetch(mgr->jar, https, host, path);
-        if (cookies != NULL)
-        {
-            msg_Dbg(mgr->obj, "retrieved cookies: %s", cookies);
-            ret = vlc_http_msg_add_header(req, "Cookie", "%s", cookies);
-            free(cookies);
-        }
-    }
-    return ret;
+    return mgr->jar != NULL ? vlc_http_msg_add_cookies(req, mgr->jar) : 0;
 }
 
 void vlc_http_mgr_recv_cookies(struct vlc_http_mgr *mgr, bool https,
@@ -296,16 +282,12 @@ void vlc_http_mgr_recv_cookies(struct vlc_http_mgr *mgr, bool https,
                                const struct vlc_http_msg *resp)
 {
     if (mgr->jar != NULL)
-    {   /* FIXME: fold multiple Set-Cookies headers with ';' */
-        const char *cookies = vlc_http_msg_get_header(resp, "Set-Cookie");
-        if (cookies != NULL
-         && vlc_http_cookies_store(mgr->jar, cookies, https, host, path))
-            msg_Dbg(mgr->obj, "stored cookie: %s", cookies);
-    }
+        vlc_http_msg_get_cookies(resp, mgr->jar, https, host, path);
 }
 
 struct vlc_http_mgr *vlc_http_mgr_create(vlc_object_t *obj,
-                                         vlc_http_cookie_jar_t *jar, bool h2c)
+                                         struct vlc_http_cookie_jar_t *jar,
+                                         bool h2c)
 {
     struct vlc_http_mgr *mgr = malloc(sizeof (*mgr));
     if (unlikely(mgr == NULL))
diff --git a/modules/access/http/connmgr.h b/modules/access/http/connmgr.h
index efe4e5b..81d8a34 100644
--- a/modules/access/http/connmgr.h
+++ b/modules/access/http/connmgr.h
@@ -25,9 +25,7 @@ struct vlc_http_cookie_jar_t;
 struct vlc_http_msg *vlc_http_mgr_request(struct vlc_http_mgr *mgr, bool https,
                                           const char *host, unsigned port,
                                           const struct vlc_http_msg *req);
-int vlc_http_mgr_send_cookies(struct vlc_http_mgr *mgr, bool https,
-                              const char *host, const char *path,
-                              struct vlc_http_msg *req);
+int vlc_http_mgr_send_cookies(struct vlc_http_mgr *, struct vlc_http_msg *);
 void vlc_http_mgr_recv_cookies(struct vlc_http_mgr *mgr, bool https,
                                const char *host, const char *path,
                                const struct vlc_http_msg *resp);
diff --git a/modules/access/http/file_test.c b/modules/access/http/file_test.c
index d3e347d..c1ed791 100644
--- a/modules/access/http/file_test.c
+++ b/modules/access/http/file_test.c
@@ -30,6 +30,7 @@
 #include <string.h>
 
 #include <vlc_common.h>
+#include <vlc_http.h>
 #include "file.h"
 #include "message.h"
 
@@ -40,11 +41,15 @@ static const char *replies[2] = { NULL, NULL };
 static uintmax_t offset = 0;
 static bool etags = false;
 
+static vlc_http_cookie_jar_t *jar;
+
 int main(void)
 {
     struct vlc_http_file *f;
     char *str;
 
+    jar = vlc_http_cookies_new();
+
     /* Request failure test */
     f = vlc_http_file_create(NULL, url, ua, NULL);
     assert(f != NULL);
@@ -205,6 +210,7 @@ int main(void)
     assert(f != NULL);
     vlc_http_file_destroy(f);
 
+    vlc_http_cookies_destroy(jar);
     return 0;
 }
 
@@ -320,25 +326,20 @@ struct vlc_http_msg *vlc_http_mgr_request(struct vlc_http_mgr *mgr, bool https,
     return vlc_http_stream_read_headers(&stream);
 }
 
-int vlc_http_mgr_send_cookies(struct vlc_http_mgr *mgr, bool https,
-                              const char *host, const char *path,
+int vlc_http_mgr_send_cookies(struct vlc_http_mgr *mgr,
                               struct vlc_http_msg *req)
 {
-    assert(https);
-    assert(!strcmp(host, "www.example.com"));
-    assert(!strcmp(path, "/dir/file.ext?a=b"));
     assert(mgr == NULL);
-    (void) req;
-    return 0;
+    return vlc_http_msg_add_cookies(req, jar);
 }
 
 void vlc_http_mgr_recv_cookies(struct vlc_http_mgr *mgr, bool https,
                                const char *host, const char *path,
                                const struct vlc_http_msg *resp)
 {
+    assert(mgr == NULL);
     assert(https);
     assert(!strcmp(host, "www.example.com"));
     assert(!strcmp(path, "/dir/file.ext?a=b"));
-    assert(mgr == NULL);
-    (void) resp;
+    vlc_http_msg_get_cookies(resp, jar, https, host, path);
 }
diff --git a/modules/access/http/message.c b/modules/access/http/message.c
index 33b500b..c2f61c0 100644
--- a/modules/access/http/message.c
+++ b/modules/access/http/message.c
@@ -31,6 +31,7 @@
 #include <time.h>
 
 #include <vlc_common.h>
+#include <vlc_http.h>
 #include "message.h"
 #include "h2frame.h"
 
@@ -794,3 +795,50 @@ uintmax_t vlc_http_msg_get_size(const struct vlc_http_msg *m)
     errno = EINVAL;
     return -1;
 }
+
+void vlc_http_msg_get_cookies(const struct vlc_http_msg *m,
+                              vlc_http_cookie_jar_t *jar, bool secure,
+                              const char *host, const char *path)
+{
+    for (unsigned i = 0; i < m->count; i++)
+        if (!strcasecmp(m->headers[i][0], "Set-Cookie"))
+            vlc_http_cookies_store(jar, m->headers[i][1], secure, host, path);
+}
+
+int vlc_http_msg_add_cookies(struct vlc_http_msg *m,
+                             vlc_http_cookie_jar_t *jar)
+{
+    char *host, *cookies;
+    int val = 0;
+    bool secure;
+
+    if (m->scheme == NULL || m->authority == NULL || m->path == NULL)
+    {
+        errno = EINVAL;
+        return -1;
+    }
+
+    if (!strcasecmp(m->scheme, "https"))
+        secure = true;
+    else if (!strcasecmp(m->scheme, "http"))
+        secure = false;
+    else
+        return 0;
+
+    if (m->authority[0] == '[')
+        host = strndup(m->authority + 1, strcspn(m->authority + 1, "]"));
+    else
+        host = strndup(m->authority, strcspn(m->authority, ":"));
+    if (unlikely(host == NULL))
+        return -1;
+
+    cookies = vlc_http_cookies_fetch(jar, secure, host, m->path);
+    free(host);
+
+    if (cookies != NULL)
+    {
+        val = vlc_http_msg_add_header(m, "Cookie", cookies);
+        free(cookies);
+    }
+    return val;
+}
diff --git a/modules/access/http/message.h b/modules/access/http/message.h
index b514e85..6e19a91 100644
--- a/modules/access/http/message.h
+++ b/modules/access/http/message.h
@@ -22,6 +22,7 @@
 
 struct vlc_http_msg;
 struct block_t;
+struct vlc_http_cookie_jar_t;
 
 /**
  * Creates an HTTP request.
@@ -127,6 +128,12 @@ time_t vlc_http_msg_get_mtime(const struct vlc_http_msg *m);
  */
 unsigned vlc_http_msg_get_retry_after(const struct vlc_http_msg *m);
 
+void vlc_http_msg_get_cookies(const struct vlc_http_msg *,
+                              struct vlc_http_cookie_jar_t *, bool secure,
+                              const char *host, const char *path);
+int vlc_http_msg_add_cookies(struct vlc_http_msg *,
+                             struct vlc_http_cookie_jar_t *);
+
 /**
  * Looks up an HTTP header.
  *
diff --git a/modules/access/http/resource.c b/modules/access/http/resource.c
index 5a9743d..27ebb81 100644
--- a/modules/access/http/resource.c
+++ b/modules/access/http/resource.c
@@ -64,8 +64,7 @@ vlc_http_res_req(const struct vlc_http_resource *res)
     if (res->referrer != NULL) /* TODO: validate URL */
         vlc_http_msg_add_header(req, "Referer", "%s", res->referrer);
 
-    vlc_http_mgr_send_cookies(res->manager, res->secure, res->host,
-                              res->path, req);
+    vlc_http_mgr_send_cookies(res->manager, req);
 
     /* TODO: vlc_http_msg_add_header(req, "TE", "gzip, deflate"); */
 



More information about the vlc-commits mailing list