[vlc-commits] https: simplify HTTP/2 headers parsing
Rémi Denis-Courmont
git at videolan.org
Sun Dec 20 17:12:27 CET 2015
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sun Dec 20 18:11:27 2015 +0200| [750d5ebcdfc362c504c52039e851c224be41ac7b] | committer: Rémi Denis-Courmont
https: simplify HTTP/2 headers parsing
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=750d5ebcdfc362c504c52039e851c224be41ac7b
---
modules/access/http/h2conn.c | 3 ++-
modules/access/http/h2frame.c | 31 ++++++++++++++++++-------------
modules/access/http/h2frame.h | 3 ++-
modules/access/http/h2frame_test.c | 5 ++---
modules/access/http/message.c | 9 ++-------
modules/access/http/message.h | 3 ++-
modules/access/http/message_test.c | 14 +++++++-------
7 files changed, 35 insertions(+), 33 deletions(-)
diff --git a/modules/access/http/h2conn.c b/modules/access/http/h2conn.c
index a1a1b72..535ecbe 100644
--- a/modules/access/http/h2conn.c
+++ b/modules/access/http/h2conn.c
@@ -113,7 +113,8 @@ static int vlc_h2_stream_fatal(struct vlc_h2_stream *s, uint_fast32_t code)
}
/** Reports received stream headers */
-static void vlc_h2_stream_headers(void *ctx, unsigned count, char *hdrs[][2])
+static void vlc_h2_stream_headers(void *ctx, unsigned count,
+ const char *const hdrs[][2])
{
struct vlc_h2_stream *s = ctx;
diff --git a/modules/access/http/h2frame.c b/modules/access/http/h2frame.c
index c5ff0d6..acaa5ab 100644
--- a/modules/access/http/h2frame.c
+++ b/modules/access/http/h2frame.c
@@ -522,41 +522,46 @@ static int vlc_h2_parse_headers_end(struct vlc_h2_parser *p)
char *headers[VLC_H2_MAX_HEADERS][2];
/* TODO: limit total decompressed size of the headers list */
- int val = hpack_decode(p->headers.decoder, p->headers.buf, p->headers.len,
- headers, VLC_H2_MAX_HEADERS);
- if (val > VLC_H2_MAX_HEADERS)
+ int n = hpack_decode(p->headers.decoder, p->headers.buf, p->headers.len,
+ headers, VLC_H2_MAX_HEADERS);
+ if (n > VLC_H2_MAX_HEADERS)
{
for (unsigned i = 0; i < VLC_H2_MAX_HEADERS; i++)
{
free(headers[i][0]);
free(headers[i][1]);
}
- val = -1;
+ n = -1;
}
- if (val < 0)
+ if (n < 0)
return vlc_h2_parse_error(p, VLC_H2_COMPRESSION_ERROR);
void *s = vlc_h2_stream_lookup(p, p->headers.sid);
+ int val = 0;
+
if (s != NULL)
{
- p->cbs->stream_headers(s, val, headers);
- val = 0;
+ const char *ch[n ? n : 1][2];
+
+ for (int i = 0; i < n; i++)
+ ch[i][0] = headers[i][0], ch[i][1] = headers[i][1];
+
+ p->cbs->stream_headers(s, n, ch);
if (p->headers.eos)
p->cbs->stream_end(s);
}
else
- {
- for (int i = 0; i < val; i++)
- {
- free(headers[i][0]);
- free(headers[i][1]);
- }
/* NOTE: The specification implies that the error should be sent for
* the first header frame. But we actually want to receive the whole
* fragmented headers block, to preserve the HPACK decoder state.
* So we send the error at the last header frame instead. */
val = vlc_h2_stream_error(p, p->headers.sid, VLC_H2_REFUSED_STREAM);
+
+ for (int i = 0; i < n; i++)
+ {
+ free(headers[i][0]);
+ free(headers[i][1]);
}
p->parser = vlc_h2_parse_generic;
diff --git a/modules/access/http/h2frame.h b/modules/access/http/h2frame.h
index d25e43a..49a5c1f 100644
--- a/modules/access/http/h2frame.h
+++ b/modules/access/http/h2frame.h
@@ -106,7 +106,8 @@ struct vlc_h2_parser_cbs
void *(*stream_lookup)(void *ctx, uint_fast32_t id);
int (*stream_error)(void *ctx, uint_fast32_t id, uint_fast32_t code);
- void (*stream_headers)(void *ctx, unsigned count, char *headers[][2]);
+ void (*stream_headers)(void *ctx, unsigned count,
+ const char *const headers[][2]);
int (*stream_data)(void *ctx, struct vlc_h2_frame *f);
void (*stream_end)(void *ctx);
int (*stream_reset)(void *ctx, uint_fast32_t code);
diff --git a/modules/access/http/h2frame_test.c b/modules/access/http/h2frame_test.c
index 4557aa6..2cbb082 100644
--- a/modules/access/http/h2frame_test.c
+++ b/modules/access/http/h2frame_test.c
@@ -142,7 +142,8 @@ static const unsigned resp_hdrc = sizeof (resp_hdrv) / sizeof (resp_hdrv[0]);
static unsigned stream_header_tables;
-static void vlc_h2_stream_headers(void *ctx, unsigned count, char *hdrs[][2])
+static void vlc_h2_stream_headers(void *ctx, unsigned count,
+ const char *const hdrs[][2])
{
assert(ctx == &stream_cookie);
assert(count == resp_hdrc);
@@ -151,8 +152,6 @@ static void vlc_h2_stream_headers(void *ctx, unsigned count, char *hdrs[][2])
{
assert(!strcmp(hdrs[i][0], resp_hdrv[i][0]));
assert(!strcmp(hdrs[i][1], resp_hdrv[i][1]));
- free(hdrs[i][1]);
- free(hdrs[i][0]);
}
stream_header_tables++;
diff --git a/modules/access/http/message.c b/modules/access/http/message.c
index f7137de..33b500b 100644
--- a/modules/access/http/message.c
+++ b/modules/access/http/message.c
@@ -427,7 +427,8 @@ struct vlc_h2_frame *vlc_http_msg_h2_frame(const struct vlc_http_msg *m,
return f;
}
-struct vlc_http_msg *vlc_http_msg_h2_headers(unsigned n, char *hdrs[][2])
+struct vlc_http_msg *vlc_http_msg_h2_headers(unsigned n,
+ const char *const hdrs[][2])
{
struct vlc_http_msg *m = vlc_http_resp_create(0);
if (unlikely(m == NULL))
@@ -507,12 +508,6 @@ error:
vlc_http_msg_destroy(m);
m = NULL;
}
-
- for (unsigned i = 0; i < n; i++)
- {
- free(hdrs[i][0]);
- free(hdrs[i][1]);
- }
return m;
}
diff --git a/modules/access/http/message.h b/modules/access/http/message.h
index 7e57177..b514e85 100644
--- a/modules/access/http/message.h
+++ b/modules/access/http/message.h
@@ -257,4 +257,5 @@ struct vlc_h2_frame;
struct vlc_h2_frame *vlc_http_msg_h2_frame(const struct vlc_http_msg *m,
uint_fast32_t stream_id, bool eos);
-struct vlc_http_msg *vlc_http_msg_h2_headers(unsigned n, char *hdrs[][2]);
+struct vlc_http_msg *vlc_http_msg_h2_headers(unsigned count,
+ const char *const headers[][2]);
diff --git a/modules/access/http/message_test.c b/modules/access/http/message_test.c
index 2fec662..92883dc 100644
--- a/modules/access/http/message_test.c
+++ b/modules/access/http/message_test.c
@@ -255,10 +255,10 @@ int main(void)
vlc_http_msg_destroy(m);
- char *bad1[][2] = {
- { strdup(":status"), strdup("200") },
- { strdup(":status"), strdup("200") },
- { strdup("Server"), strdup("BigBad/1.0") },
+ const char *bad1[][2] = {
+ { ":status", "200" },
+ { ":status", "200" },
+ { "Server", "BigBad/1.0" },
};
m = vlc_http_msg_h2_headers(3, bad1);
@@ -288,12 +288,12 @@ vlc_h2_frame_headers(uint_fast32_t id, uint_fast32_t mtu, bool eos,
assert(mtu == VLC_H2_DEFAULT_MAX_FRAME);
assert(eos);
- char *headers[VLC_H2_MAX_HEADERS][2];
+ const char *headers[VLC_H2_MAX_HEADERS][2];
for (unsigned i = 0; i < count; i++)
{
- headers[i][0] = strdup(tab[i][0]);
- headers[i][1] = strdup(tab[i][1]);
+ headers[i][0] = tab[i][0];
+ headers[i][1] = tab[i][1];
}
m = vlc_http_msg_h2_headers(count, headers);
More information about the vlc-commits
mailing list