Commit a9984c5b authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

https: fix receiving multiple cookies (fixes #16181)

parent c1a723e0
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
#include <assert.h> #include <assert.h>
#include <vlc_common.h> #include <vlc_common.h>
#include <vlc_tls.h> #include <vlc_tls.h>
#include <vlc_http.h>
#include <vlc_interrupt.h> #include <vlc_interrupt.h>
#include "transport.h" #include "transport.h"
#include "conn.h" #include "conn.h"
...@@ -135,7 +134,7 @@ struct vlc_http_mgr ...@@ -135,7 +134,7 @@ struct vlc_http_mgr
{ {
vlc_object_t *obj; vlc_object_t *obj;
vlc_tls_creds_t *creds; vlc_tls_creds_t *creds;
vlc_http_cookie_jar_t *jar; struct vlc_http_cookie_jar_t *jar;
struct vlc_http_conn *conn; struct vlc_http_conn *conn;
bool use_h2c; bool use_h2c;
}; };
...@@ -272,23 +271,10 @@ struct vlc_http_msg *vlc_http_mgr_request(struct vlc_http_mgr *mgr, bool https, ...@@ -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); 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, int vlc_http_mgr_send_cookies(struct vlc_http_mgr *mgr,
const char *host, const char *path,
struct vlc_http_msg *req) struct vlc_http_msg *req)
{ {
int ret = 0; return mgr->jar != NULL ? vlc_http_msg_add_cookies(req, mgr->jar) : 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;
} }
void vlc_http_mgr_recv_cookies(struct vlc_http_mgr *mgr, bool https, 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, ...@@ -296,16 +282,12 @@ void vlc_http_mgr_recv_cookies(struct vlc_http_mgr *mgr, bool https,
const struct vlc_http_msg *resp) const struct vlc_http_msg *resp)
{ {
if (mgr->jar != NULL) if (mgr->jar != NULL)
{ /* FIXME: fold multiple Set-Cookies headers with ';' */ vlc_http_msg_get_cookies(resp, mgr->jar, https, host, path);
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);
}
} }
struct vlc_http_mgr *vlc_http_mgr_create(vlc_object_t *obj, 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)); struct vlc_http_mgr *mgr = malloc(sizeof (*mgr));
if (unlikely(mgr == NULL)) if (unlikely(mgr == NULL))
......
...@@ -25,9 +25,7 @@ struct vlc_http_cookie_jar_t; ...@@ -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, struct vlc_http_msg *vlc_http_mgr_request(struct vlc_http_mgr *mgr, bool https,
const char *host, unsigned port, const char *host, unsigned port,
const struct vlc_http_msg *req); const struct vlc_http_msg *req);
int vlc_http_mgr_send_cookies(struct vlc_http_mgr *mgr, bool https, int vlc_http_mgr_send_cookies(struct vlc_http_mgr *, struct vlc_http_msg *);
const char *host, const char *path,
struct vlc_http_msg *req);
void vlc_http_mgr_recv_cookies(struct vlc_http_mgr *mgr, bool https, void vlc_http_mgr_recv_cookies(struct vlc_http_mgr *mgr, bool https,
const char *host, const char *path, const char *host, const char *path,
const struct vlc_http_msg *resp); const struct vlc_http_msg *resp);
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <string.h> #include <string.h>
#include <vlc_common.h> #include <vlc_common.h>
#include <vlc_http.h>
#include "file.h" #include "file.h"
#include "message.h" #include "message.h"
...@@ -40,11 +41,15 @@ static const char *replies[2] = { NULL, NULL }; ...@@ -40,11 +41,15 @@ static const char *replies[2] = { NULL, NULL };
static uintmax_t offset = 0; static uintmax_t offset = 0;
static bool etags = false; static bool etags = false;
static vlc_http_cookie_jar_t *jar;
int main(void) int main(void)
{ {
struct vlc_http_file *f; struct vlc_http_file *f;
char *str; char *str;
jar = vlc_http_cookies_new();
/* Request failure test */ /* Request failure test */
f = vlc_http_file_create(NULL, url, ua, NULL); f = vlc_http_file_create(NULL, url, ua, NULL);
assert(f != NULL); assert(f != NULL);
...@@ -205,6 +210,7 @@ int main(void) ...@@ -205,6 +210,7 @@ int main(void)
assert(f != NULL); assert(f != NULL);
vlc_http_file_destroy(f); vlc_http_file_destroy(f);
vlc_http_cookies_destroy(jar);
return 0; return 0;
} }
...@@ -320,25 +326,20 @@ struct vlc_http_msg *vlc_http_mgr_request(struct vlc_http_mgr *mgr, bool https, ...@@ -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); return vlc_http_stream_read_headers(&stream);
} }
int vlc_http_mgr_send_cookies(struct vlc_http_mgr *mgr, bool https, int vlc_http_mgr_send_cookies(struct vlc_http_mgr *mgr,
const char *host, const char *path,
struct vlc_http_msg *req) struct vlc_http_msg *req)
{ {
assert(https);
assert(!strcmp(host, "www.example.com"));
assert(!strcmp(path, "/dir/file.ext?a=b"));
assert(mgr == NULL); assert(mgr == NULL);
(void) req; return vlc_http_msg_add_cookies(req, jar);
return 0;
} }
void vlc_http_mgr_recv_cookies(struct vlc_http_mgr *mgr, bool https, void vlc_http_mgr_recv_cookies(struct vlc_http_mgr *mgr, bool https,
const char *host, const char *path, const char *host, const char *path,
const struct vlc_http_msg *resp) const struct vlc_http_msg *resp)
{ {
assert(mgr == NULL);
assert(https); assert(https);
assert(!strcmp(host, "www.example.com")); assert(!strcmp(host, "www.example.com"));
assert(!strcmp(path, "/dir/file.ext?a=b")); assert(!strcmp(path, "/dir/file.ext?a=b"));
assert(mgr == NULL); vlc_http_msg_get_cookies(resp, jar, https, host, path);
(void) resp;
} }
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <time.h> #include <time.h>
#include <vlc_common.h> #include <vlc_common.h>
#include <vlc_http.h>
#include "message.h" #include "message.h"
#include "h2frame.h" #include "h2frame.h"
...@@ -794,3 +795,50 @@ uintmax_t vlc_http_msg_get_size(const struct vlc_http_msg *m) ...@@ -794,3 +795,50 @@ uintmax_t vlc_http_msg_get_size(const struct vlc_http_msg *m)
errno = EINVAL; errno = EINVAL;
return -1; 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;
}
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
struct vlc_http_msg; struct vlc_http_msg;
struct block_t; struct block_t;
struct vlc_http_cookie_jar_t;
/** /**
* Creates an HTTP request. * Creates an HTTP request.
...@@ -127,6 +128,12 @@ time_t vlc_http_msg_get_mtime(const struct vlc_http_msg *m); ...@@ -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); 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. * Looks up an HTTP header.
* *
......
...@@ -64,8 +64,7 @@ vlc_http_res_req(const struct vlc_http_resource *res) ...@@ -64,8 +64,7 @@ vlc_http_res_req(const struct vlc_http_resource *res)
if (res->referrer != NULL) /* TODO: validate URL */ if (res->referrer != NULL) /* TODO: validate URL */
vlc_http_msg_add_header(req, "Referer", "%s", res->referrer); vlc_http_msg_add_header(req, "Referer", "%s", res->referrer);
vlc_http_mgr_send_cookies(res->manager, res->secure, res->host, vlc_http_mgr_send_cookies(res->manager, req);
res->path, req);
/* TODO: vlc_http_msg_add_header(req, "TE", "gzip, deflate"); */ /* TODO: vlc_http_msg_add_header(req, "TE", "gzip, deflate"); */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment