summaryrefslogtreecommitdiffstats
path: root/debian/vendor-h2o/lib/handler/configurator/headers_util.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--debian/vendor-h2o/lib/handler/configurator/headers_util.c143
1 files changed, 143 insertions, 0 deletions
diff --git a/debian/vendor-h2o/lib/handler/configurator/headers_util.c b/debian/vendor-h2o/lib/handler/configurator/headers_util.c
new file mode 100644
index 0000000..c05b9b7
--- /dev/null
+++ b/debian/vendor-h2o/lib/handler/configurator/headers_util.c
@@ -0,0 +1,143 @@
+#include "h2o.h"
+#include "h2o/configurator.h"
+
+struct headers_util_configurator_t {
+ h2o_configurator_t super;
+ h2o_configurator_t *child;
+ h2o_configurator_get_headers_commands_cb get_commands;
+};
+
+static int extract_name(const char *src, size_t len, h2o_iovec_t **_name)
+{
+ h2o_iovec_t name;
+ const h2o_token_t *name_token;
+
+ name = h2o_str_stripws(src, len);
+ if (name.len == 0)
+ return -1;
+
+ name = h2o_strdup(NULL, name.base, name.len);
+ h2o_strtolower(name.base, name.len);
+
+ if ((name_token = h2o_lookup_token(name.base, name.len)) != NULL) {
+ *_name = (h2o_iovec_t *)&name_token->buf;
+ free(name.base);
+ } else {
+ *_name = h2o_mem_alloc(sizeof(**_name));
+ **_name = name;
+ }
+
+ return 0;
+}
+
+static int extract_name_value(const char *src, h2o_iovec_t **name, h2o_iovec_t *value)
+{
+ const char *colon = strchr(src, ':');
+
+ if (colon == NULL)
+ return -1;
+
+ if (extract_name(src, colon - src, name) != 0)
+ return -1;
+ *value = h2o_str_stripws(colon + 1, strlen(colon + 1));
+ *value = h2o_strdup(NULL, value->base, value->len);
+
+ return 0;
+}
+
+static int add_cmd(h2o_configurator_command_t *cmd, yoml_t *node, int cmd_id, h2o_iovec_t *name, h2o_iovec_t value,
+ h2o_headers_command_t **cmds)
+{
+ if (h2o_iovec_is_token(name)) {
+ const h2o_token_t *token = (void *)name;
+ if (h2o_headers_is_prohibited_name(token)) {
+ h2o_configurator_errprintf(cmd, node, "the named header cannot be rewritten");
+ return -1;
+ }
+ }
+
+ h2o_headers_append_command(cmds, cmd_id, name, value);
+ return 0;
+}
+
+static int on_config_header_2arg(h2o_configurator_command_t *cmd, h2o_configurator_context_t *ctx, int cmd_id, yoml_t *node,
+ h2o_headers_command_t **headers_cmds)
+{
+ h2o_iovec_t *name, value;
+
+ if (extract_name_value(node->data.scalar, &name, &value) != 0) {
+ h2o_configurator_errprintf(cmd, node, "failed to parse the value; should be in form of `name: value`");
+ return -1;
+ }
+ if (add_cmd(cmd, node, cmd_id, name, value, headers_cmds) != 0) {
+ if (!h2o_iovec_is_token(name))
+ free(name->base);
+ free(value.base);
+ return -1;
+ }
+ return 0;
+}
+
+static int on_config_header_unset(h2o_configurator_command_t *cmd, h2o_configurator_context_t *ctx, yoml_t *node)
+{
+ h2o_iovec_t *name;
+ struct headers_util_configurator_t *self = (void *)cmd->configurator;
+
+ if (extract_name(node->data.scalar, strlen(node->data.scalar), &name) != 0) {
+ h2o_configurator_errprintf(cmd, node, "invalid header name");
+ return -1;
+ }
+ if (add_cmd(cmd, node, H2O_HEADERS_CMD_UNSET, name, (h2o_iovec_t){NULL}, self->get_commands(self->child)) != 0) {
+ if (!h2o_iovec_is_token(name))
+ free(name->base);
+ return -1;
+ }
+ return 0;
+}
+
+#define DEFINE_2ARG(fn, cmd_id) \
+ static int fn(h2o_configurator_command_t *cmd, h2o_configurator_context_t *ctx, yoml_t *node) \
+ { \
+ struct headers_util_configurator_t *self = (void *)cmd->configurator; \
+ return on_config_header_2arg(cmd, ctx, cmd_id, node, self->get_commands(self->child)); \
+ }
+
+DEFINE_2ARG(on_config_header_add, H2O_HEADERS_CMD_ADD)
+DEFINE_2ARG(on_config_header_append, H2O_HEADERS_CMD_APPEND)
+DEFINE_2ARG(on_config_header_merge, H2O_HEADERS_CMD_MERGE)
+DEFINE_2ARG(on_config_header_set, H2O_HEADERS_CMD_SET)
+DEFINE_2ARG(on_config_header_setifempty, H2O_HEADERS_CMD_SETIFEMPTY)
+
+#undef DEFINE_2ARG
+
+void h2o_configurator_define_headers_commands(h2o_globalconf_t *global_conf, h2o_configurator_t *conf, const char *prefix,
+ h2o_configurator_get_headers_commands_cb get_commands)
+{
+ struct headers_util_configurator_t *c = (void *)h2o_configurator_create(global_conf, sizeof(*c));
+ c->child = conf;
+ c->get_commands = get_commands;
+ size_t prefix_len = strlen(prefix);
+
+#define DEFINE_CMD_NAME(name, suffix) \
+ char *name = h2o_mem_alloc(prefix_len + sizeof(suffix)); \
+ memcpy(name, prefix, prefix_len); \
+ memcpy(name + prefix_len, suffix, sizeof(suffix))
+
+ DEFINE_CMD_NAME(add_directive, ".add");
+ DEFINE_CMD_NAME(append_directive, ".append");
+ DEFINE_CMD_NAME(merge_directive, ".merge");
+ DEFINE_CMD_NAME(set_directive, ".set");
+ DEFINE_CMD_NAME(setifempty_directive, ".setifempty");
+ DEFINE_CMD_NAME(unset_directive, ".unset");
+#undef DEFINE_CMD_NAME
+
+#define DEFINE_CMD(name, cb) \
+ h2o_configurator_define_command(&c->super, name, H2O_CONFIGURATOR_FLAG_ALL_LEVELS | H2O_CONFIGURATOR_FLAG_EXPECT_SCALAR, cb)
+ DEFINE_CMD(add_directive, on_config_header_add);
+ DEFINE_CMD(append_directive, on_config_header_append);
+ DEFINE_CMD(merge_directive, on_config_header_merge);
+ DEFINE_CMD(set_directive, on_config_header_set);
+ DEFINE_CMD(setifempty_directive, on_config_header_setifempty);
+ DEFINE_CMD(unset_directive, on_config_header_unset);
+#undef DEFINE_CMD
+}