1 /* 2 * Copyright (c) 2014 DeNA Co., Ltd. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a copy 5 * of this software and associated documentation files (the "Software"), to 6 * deal in the Software without restriction, including without limitation the 7 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 * sell copies of the Software, and to permit persons to whom the Software is 9 * furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 * IN THE SOFTWARE. 21 */ 22 #ifndef h2o__configurator_h 23 #define h2o__configurator_h 24 25 #include "yoml.h" 26 27 enum { 28 H2O_CONFIGURATOR_FLAG_GLOBAL = 0x1, 29 H2O_CONFIGURATOR_FLAG_HOST = 0x2, 30 H2O_CONFIGURATOR_FLAG_PATH = 0x4, 31 H2O_CONFIGURATOR_FLAG_EXTENSION = 0x8, 32 H2O_CONFIGURATOR_FLAG_ALL_LEVELS = 33 H2O_CONFIGURATOR_FLAG_GLOBAL | H2O_CONFIGURATOR_FLAG_HOST | H2O_CONFIGURATOR_FLAG_PATH | H2O_CONFIGURATOR_FLAG_EXTENSION, 34 H2O_CONFIGURATOR_FLAG_EXPECT_SCALAR = 0x100, 35 H2O_CONFIGURATOR_FLAG_EXPECT_SEQUENCE = 0x200, 36 H2O_CONFIGURATOR_FLAG_EXPECT_MAPPING = 0x400, 37 H2O_CONFIGURATOR_FLAG_DEFERRED = 0x1000, 38 H2O_CONFIGURATOR_FLAG_SEMI_DEFERRED = 0x2000 /* used by file.custom-handler (invoked before hosts,paths,file-dir, etc.) */ 39 }; 40 41 #define H2O_CONFIGURATOR_NUM_LEVELS 4 42 43 typedef struct st_h2o_configurator_context_t { 44 /** 45 * pointer to globalconf 46 */ 47 h2o_globalconf_t *globalconf; 48 /** 49 * pointer to hostconf, or NULL if the context is above host level 50 */ 51 h2o_hostconf_t *hostconf; 52 /** 53 * pointer to pathconf (either at path level or custom handler level), or NULL 54 */ 55 h2o_pathconf_t *pathconf; 56 /** 57 * pointer to mimemap 58 */ 59 h2o_mimemap_t **mimemap; 60 /** 61 * pointer to env 62 */ 63 h2o_envconf_t *env; 64 /** 65 * if is a dry run 66 */ 67 int dry_run; 68 /** 69 * parent context (or NULL if the context is at global level) 70 */ 71 struct st_h2o_configurator_context_t *parent; 72 } h2o_configurator_context_t; 73 74 typedef int (*h2o_configurator_dispose_cb)(h2o_configurator_t *configurator); 75 typedef int (*h2o_configurator_enter_cb)(h2o_configurator_t *configurator, h2o_configurator_context_t *ctx, yoml_t *node); 76 typedef int (*h2o_configurator_exit_cb)(h2o_configurator_t *configurator, h2o_configurator_context_t *ctx, yoml_t *node); 77 typedef int (*h2o_configurator_command_cb)(h2o_configurator_command_t *cmd, h2o_configurator_context_t *ctx, yoml_t *node); 78 typedef h2o_headers_command_t **(*h2o_configurator_get_headers_commands_cb)(h2o_configurator_t *conf); 79 80 struct st_h2o_configurator_command_t { 81 /** 82 * configurator to which the command belongs 83 */ 84 h2o_configurator_t *configurator; 85 /** 86 * name of the command handled by the configurator 87 */ 88 const char *name; 89 /** 90 * flags 91 */ 92 int flags; 93 /** 94 * mandatory callback called to handle the command 95 */ 96 h2o_configurator_command_cb cb; 97 }; 98 99 /** 100 * basic structure of a configurator (handles a configuration command) 101 */ 102 struct st_h2o_configurator_t { 103 h2o_linklist_t _link; 104 /** 105 * optional callback called when the global config is being disposed 106 */ 107 h2o_configurator_dispose_cb dispose; 108 /** 109 * optional callback called before the configuration commands are handled 110 */ 111 h2o_configurator_enter_cb enter; 112 /** 113 * optional callback called after all the configuration commands are handled 114 */ 115 h2o_configurator_exit_cb exit; 116 /** 117 * list of commands 118 */ 119 H2O_VECTOR(h2o_configurator_command_t) commands; 120 }; 121 122 /** 123 * registers a configurator 124 */ 125 h2o_configurator_t *h2o_configurator_create(h2o_globalconf_t *conf, size_t sz); 126 /** 127 * 128 */ 129 void h2o_configurator_define_command(h2o_configurator_t *configurator, const char *name, int flags, h2o_configurator_command_cb cb); 130 /** 131 * returns a configurator of given command name 132 * @return configurator for given name or NULL if not found 133 */ 134 h2o_configurator_command_t *h2o_configurator_get_command(h2o_globalconf_t *conf, const char *name); 135 /** 136 * applies the configuration to the context 137 * @return 0 if successful, -1 if not 138 */ 139 int h2o_configurator_apply(h2o_globalconf_t *config, yoml_t *node, int dry_run); 140 /** 141 * 142 */ 143 int h2o_configurator_apply_commands(h2o_configurator_context_t *ctx, yoml_t *node, int flags_mask, const char **ignore_commands); 144 /** 145 * emits configuration error 146 */ 147 void h2o_configurator_errprintf(h2o_configurator_command_t *cmd, yoml_t *node, const char *reason, ...) 148 __attribute__((format(printf, 3, 4))); 149 /** 150 * interprets the configuration value using sscanf, or prints an error upon failure 151 * @param configurator configurator 152 * @param node configuration value 153 * @param fmt scanf-style format string 154 * @return 0 if successful, -1 if not 155 */ 156 int h2o_configurator_scanf(h2o_configurator_command_t *cmd, yoml_t *node, const char *fmt, ...) 157 __attribute__((format(scanf, 3, 4))); 158 /** 159 * interprets the configuration value and returns the index of the matched string within the candidate strings, or prints an error 160 * upon failure 161 * @param configurator configurator 162 * @param node configuration value 163 * @param candidates a comma-separated list of strings (should not contain whitespaces) 164 * @return index of the matched string within the given list, or -1 if none of them matched 165 */ 166 ssize_t h2o_configurator_get_one_of(h2o_configurator_command_t *cmd, yoml_t *node, const char *candidates); 167 /** 168 * extracts values (required and optional) from a mapping by their keys, or prints an error upon failure 169 * @param configurator configurator 170 * @param node the mapping to parse 171 * @param keys_required comma-separated list of required keys (or NULL) 172 * @param keys_optional comma-separated list of optional keys (or NULL) 173 * @param ... pointers to `yoml_t **` for receiving the results; they should appear in the order they appear in the key names 174 * @return 0 if successful, -1 if not 175 */ 176 #define h2o_configurator_parse_mapping(cmd, node, keys_required, keys_optional, ...) \ 177 h2o_configurator__do_parse_mapping((cmd), (node), (keys_required), (keys_optional), (yoml_t * **[]){__VA_ARGS__}, \ 178 sizeof((yoml_t ***[]){__VA_ARGS__}) / sizeof(yoml_t ***)) 179 int h2o_configurator__do_parse_mapping(h2o_configurator_command_t *cmd, yoml_t *node, const char *keys_required, 180 const char *keys_optional, yoml_t ****values, size_t num_values); 181 /** 182 * returns the absolute paths of supplementary commands 183 */ 184 char *h2o_configurator_get_cmd_path(const char *cmd); 185 186 /** 187 * lib/handler/configurator/headers_util.c 188 */ 189 void h2o_configurator_define_headers_commands(h2o_globalconf_t *global_conf, h2o_configurator_t *conf, const char *prefix, 190 h2o_configurator_get_headers_commands_cb get_commands); 191 192 void h2o_configurator__init_core(h2o_globalconf_t *conf); 193 void h2o_configurator__dispose_configurators(h2o_globalconf_t *conf); 194 195 #endif 196