static int set_mimetypes(h2o_configurator_command_t *cmd, h2o_mimemap_t *mimemap, const char *file, yoml_t *node) { size_t i, j; assert(node->type == YOML_TYPE_MAPPING); for (i = 0; i != node->data.mapping.size; ++i) { yoml_t *key = node->data.mapping.elements[i].key; yoml_t *value = node->data.mapping.elements[i].value; if (assert_is_mimetype(cmd, file, key) != 0) return -1; switch (value->type) { case YOML_TYPE_SCALAR: if (assert_is_extension(cmd, file, value) != 0) return -1; h2o_mimemap_set_type(mimemap, value->data.scalar + 1, key->data.scalar); break; case YOML_TYPE_SEQUENCE: for (j = 0; j != value->data.sequence.size; ++j) { yoml_t *ext_node = value->data.sequence.elements[j]; if (assert_is_extension(cmd, file, ext_node) != 0) return -1; h2o_mimemap_set_type(mimemap, ext_node->data.scalar + 1, key->data.scalar); } break; default: h2o_config_print_error(cmd, file, value, "only scalar or sequence of scalar is permitted at the value part of the argument"); return -1; } } return 0; }
static int set_mimetypes(h2o_configurator_command_t *cmd, h2o_mimemap_t *mimemap, yoml_t *node) { size_t i, j; h2o_mimemap_type_t *type = NULL; assert(node->type == YOML_TYPE_MAPPING); for (i = 0; i != node->data.mapping.size; ++i) { yoml_t *key = node->data.mapping.elements[i].key; yoml_t *value = node->data.mapping.elements[i].value; if (assert_is_mimetype(cmd, key) != 0) return -1; type = h2o_mimemap_create_extension_type(key->data.scalar); switch (value->type) { case YOML_TYPE_SCALAR: if (assert_is_extension(cmd, value) != 0) goto Error; h2o_mimemap_set_type(mimemap, value->data.scalar + 1, type, 1); break; case YOML_TYPE_SEQUENCE: for (j = 0; j != value->data.sequence.size; ++j) { yoml_t *ext_node = value->data.sequence.elements[j]; if (assert_is_extension(cmd, ext_node) != 0) goto Error; h2o_mimemap_set_type(mimemap, ext_node->data.scalar + 1, type, 1); } break; default: h2o_configurator_errprintf(cmd, value, "only scalar or sequence of scalar is permitted at the value part of the argument"); goto Error; } h2o_mem_release_shared(type); type = NULL; } return 0; Error: if (type != NULL) h2o_mem_release_shared(type); return -1; }
static int on_config_custom_handler(h2o_configurator_command_t *cmd, h2o_configurator_context_t *ctx, yoml_t *node) { static const char *ignore_commands[] = {"extension", NULL}; struct st_h2o_file_configurator_t *self = (void *)cmd->configurator; h2o_pathconf_t *prev_pathconf = ctx->pathconf; yoml_t *ext_node; h2o_mimemap_type_t *type = NULL; int ret = -1; if (node->type != YOML_TYPE_MAPPING) { h2o_configurator_errprintf(cmd, node, "argument must be a MAPPING"); goto Exit; } if ((ext_node = yoml_get(node, "extension")) == NULL) { h2o_configurator_errprintf(cmd, node, "mandatory key `extension` is missing"); goto Exit; } type = h2o_mimemap_create_dynamic_type(ctx->globalconf); ctx->pathconf = &type->data.dynamic.pathconf; if (h2o_configurator_apply_commands(ctx, node, H2O_CONFIGURATOR_FLAG_EXTENSION, ignore_commands) != 0) goto Exit; switch (type->data.dynamic.pathconf.handlers.size) { case 1: break; case 0: h2o_configurator_errprintf(cmd, node, "no handler declared for given extension"); goto Exit; default: h2o_configurator_errprintf(cmd, node, "cannot assign more than one handler for given extension"); goto Exit; } clone_mimemap_if_clean(self); switch (ext_node->type) { case YOML_TYPE_SCALAR: if (assert_is_extension(cmd, ext_node) != 0) goto Exit; h2o_mimemap_set_type(self->vars->mimemap, ext_node->data.scalar + 1, type, 1); break; case YOML_TYPE_SEQUENCE: { size_t i; for (i = 0; i != ext_node->data.sequence.size; ++i) { yoml_t *n = ext_node->data.sequence.elements[i]; if (assert_is_extension(cmd, n) != 0) goto Exit; h2o_mimemap_set_type(self->vars->mimemap, n->data.scalar + 1, type, 1); } } break; default: h2o_configurator_errprintf(cmd, ext_node, "only scalar or sequence of scalar is permitted at the value part of the argument"); goto Exit; } ret = 0; Exit: if (type != NULL) h2o_mem_release_shared(type); ctx->pathconf = prev_pathconf; return ret; }