From be1c7e50e1e8809ea56f2c9d472eccd8ffd73a97 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 04:57:58 +0200 Subject: Adding upstream version 1.44.3. Signed-off-by: Daniel Baumann --- web/server/h2o/libh2o/lib/handler/headers_util.c | 114 +++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 web/server/h2o/libh2o/lib/handler/headers_util.c (limited to 'web/server/h2o/libh2o/lib/handler/headers_util.c') diff --git a/web/server/h2o/libh2o/lib/handler/headers_util.c b/web/server/h2o/libh2o/lib/handler/headers_util.c new file mode 100644 index 00000000..5ecacfa5 --- /dev/null +++ b/web/server/h2o/libh2o/lib/handler/headers_util.c @@ -0,0 +1,114 @@ +#include "h2o.h" + +static h2o_header_t *find_header(h2o_headers_t *headers, h2o_headers_command_t *cmd) +{ + size_t index; + + if (h2o_iovec_is_token(cmd->name)) { + index = h2o_find_header(headers, (void *)cmd->name, SIZE_MAX); + } else { + index = h2o_find_header_by_str(headers, cmd->name->base, cmd->name->len, SIZE_MAX); + } + if (index == SIZE_MAX) + return NULL; + return headers->entries + index; +} + +static void remove_header(h2o_headers_t *headers, h2o_headers_command_t *cmd) +{ + size_t src, dst = 0; + + for (src = 0; src != headers->size; ++src) { + if (h2o_iovec_is_token(cmd->name)) { + if (headers->entries[src].name == cmd->name) + continue; + } else { + if (h2o_memis(headers->entries[src].name->base, headers->entries[src].name->len, cmd->name->base, cmd->name->len)) + continue; + } + /* not matched */ + if (dst != src) + headers->entries[dst] = headers->entries[src]; + ++dst; + } + headers->size = dst; +} + +void h2o_headers_append_command(h2o_headers_command_t **cmds, int cmd, h2o_iovec_t *name, h2o_iovec_t value) +{ + h2o_headers_command_t *new_cmds; + size_t cnt; + + if (*cmds != NULL) { + for (cnt = 0; (*cmds)[cnt].cmd != H2O_HEADERS_CMD_NULL; ++cnt) + ; + } else { + cnt = 0; + } + + new_cmds = h2o_mem_alloc_shared(NULL, (cnt + 2) * sizeof(*new_cmds), NULL); + if (*cmds != NULL) + memcpy(new_cmds, *cmds, cnt * sizeof(*new_cmds)); + new_cmds[cnt] = (h2o_headers_command_t){cmd, name, value}; + new_cmds[cnt + 1] = (h2o_headers_command_t){H2O_HEADERS_CMD_NULL}; + + if (*cmds != NULL) + h2o_mem_release_shared(*cmds); + *cmds = new_cmds; +} + +void h2o_rewrite_headers(h2o_mem_pool_t *pool, h2o_headers_t *headers, h2o_headers_command_t *cmd) +{ + h2o_header_t *target; + + switch (cmd->cmd) { + case H2O_HEADERS_CMD_ADD: + goto AddHeader; + case H2O_HEADERS_CMD_APPEND: + if ((target = find_header(headers, cmd)) == NULL) + goto AddHeader; + goto AppendToken; + case H2O_HEADERS_CMD_MERGE: + if ((target = find_header(headers, cmd)) == NULL) + goto AddHeader; + if (h2o_contains_token(target->value.base, target->value.len, cmd->value.base, cmd->value.len, ',')) + return; + goto AppendToken; + case H2O_HEADERS_CMD_SET: + remove_header(headers, cmd); + goto AddHeader; + case H2O_HEADERS_CMD_SETIFEMPTY: + if (find_header(headers, cmd) != NULL) + return; + goto AddHeader; + case H2O_HEADERS_CMD_UNSET: + remove_header(headers, cmd); + return; + } + + assert(!"FIXME"); + return; + +AddHeader: + if (h2o_iovec_is_token(cmd->name)) { + h2o_add_header(pool, headers, (void *)cmd->name, NULL, cmd->value.base, cmd->value.len); + } else { + h2o_add_header_by_str(pool, headers, cmd->name->base, cmd->name->len, 0, NULL, cmd->value.base, cmd->value.len); + } + return; + +AppendToken: + if (target->value.len != 0) { + h2o_iovec_t v; + v.len = target->value.len + 2 + cmd->value.len; + v.base = h2o_mem_alloc_pool(pool, v.len); + memcpy(v.base, target->value.base, target->value.len); + v.base[target->value.len] = ','; + v.base[target->value.len + 1] = ' '; + memcpy(v.base + target->value.len + 2, cmd->value.base, cmd->value.len); + target->value = v; + } else { + target->value = cmd->value; + } + return; +} -- cgit v1.2.3