1 2 /* 3 * Copyright (C) Valentin V. Bartenev 4 * Copyright (C) NGINX, Inc. 5 */ 6 7 #include <nxt_main.h> 8 #include <nxt_conf.h> 9 #include <nxt_application.h> 10 11 12 typedef struct { 13 nxt_str_t name; 14 nxt_uint_t type; 15 nxt_int_t (*validator)(nxt_conf_value_t *conf, nxt_conf_value_t *value, 16 void *data); 17 void *data; 18 } nxt_conf_vldt_object_t; 19 20 21 typedef nxt_int_t (*nxt_conf_vldt_member_t)(nxt_conf_value_t *conf, 22 nxt_str_t *name, 23 nxt_conf_value_t *value); 24 25 static nxt_int_t nxt_conf_vldt_listener(nxt_conf_value_t *conf, nxt_str_t *name, 26 nxt_conf_value_t *value); 27 static nxt_int_t nxt_conf_vldt_app_name(nxt_conf_value_t *conf, 28 nxt_conf_value_t *value, void *data); 29 static nxt_int_t nxt_conf_vldt_app(nxt_conf_value_t *conf, nxt_str_t *name, 30 nxt_conf_value_t *value); 31 static nxt_int_t nxt_conf_vldt_object(nxt_conf_value_t *conf, 32 nxt_conf_value_t *value, void *data); 33 static nxt_int_t nxt_conf_vldt_object_iterator(nxt_conf_value_t *conf, 34 nxt_conf_value_t *value, void *data); 35 36 37 static nxt_conf_vldt_object_t nxt_conf_vldt_root_members[] = { 38 { nxt_string("listeners"), 39 NXT_CONF_OBJECT, 40 &nxt_conf_vldt_object_iterator, 41 (void *) &nxt_conf_vldt_listener }, 42 43 { nxt_string("applications"), 44 NXT_CONF_OBJECT, 45 &nxt_conf_vldt_object_iterator, 46 (void *) &nxt_conf_vldt_app }, 47 48 { nxt_null_string, 0, NULL, NULL } 49 }; 50 51 52 static nxt_conf_vldt_object_t nxt_conf_vldt_listener_members[] = { 53 { nxt_string("application"), 54 NXT_CONF_STRING, 55 &nxt_conf_vldt_app_name, 56 NULL }, 57 58 { nxt_null_string, 0, NULL, NULL } 59 }; 60 61 62 static nxt_conf_vldt_object_t nxt_conf_vldt_python_members[] = { 63 { nxt_string("type"), 64 NXT_CONF_STRING, 65 NULL, 66 NULL }, 67 68 { nxt_string("workers"), 69 NXT_CONF_INTEGER, 70 NULL, 71 NULL }, 72 73 { nxt_string("user"), 74 NXT_CONF_STRING, 75 NULL, 76 NULL }, 77 78 { nxt_string("group"), 79 NXT_CONF_STRING, 80 NULL, 81 NULL }, 82 83 { nxt_string("path"), 84 NXT_CONF_STRING, 85 NULL, 86 NULL }, 87 88 { nxt_string("module"), 89 NXT_CONF_STRING, 90 NULL, 91 NULL }, 92 93 { nxt_null_string, 0, NULL, NULL } 94 }; 95 96 97 static nxt_conf_vldt_object_t nxt_conf_vldt_php_members[] = { 98 { nxt_string("type"), 99 NXT_CONF_STRING, 100 NULL, 101 NULL }, 102 103 { nxt_string("workers"), 104 NXT_CONF_INTEGER, 105 NULL, 106 NULL }, 107 108 { nxt_string("user"), 109 NXT_CONF_STRING, 110 NULL, 111 NULL }, 112 113 { nxt_string("group"), 114 NXT_CONF_STRING, 115 NULL, 116 NULL }, 117 118 { nxt_string("root"), 119 NXT_CONF_STRING, 120 NULL, 121 NULL }, 122 123 { nxt_string("script"), 124 NXT_CONF_STRING, 125 NULL, 126 NULL }, 127 128 { nxt_string("index"), 129 NXT_CONF_STRING, 130 NULL, 131 NULL }, 132 133 { nxt_null_string, 0, NULL, NULL } 134 }; 135 136 137 static nxt_conf_vldt_object_t nxt_conf_vldt_go_members[] = { 138 { nxt_string("type"), 139 NXT_CONF_STRING, 140 NULL, 141 NULL }, 142 143 { nxt_string("workers"), 144 NXT_CONF_INTEGER, 145 NULL, 146 NULL }, 147 148 { nxt_string("user"), 149 NXT_CONF_STRING, 150 NULL, 151 NULL }, 152 153 { nxt_string("group"), 154 NXT_CONF_STRING, 155 NULL, 156 NULL }, 157 158 { nxt_string("executable"), 159 NXT_CONF_STRING, 160 NULL, 161 NULL }, 162 163 { nxt_null_string, 0, NULL, NULL } 164 }; 165 166 167 nxt_int_t 168 nxt_conf_validate(nxt_conf_value_t *value) 169 { 170 if (nxt_conf_type(value) != NXT_CONF_OBJECT) { 171 return NXT_ERROR; 172 } 173 174 return nxt_conf_vldt_object(value, value, nxt_conf_vldt_root_members); 175 } 176 177 178 static nxt_int_t 179 nxt_conf_vldt_listener(nxt_conf_value_t *conf, nxt_str_t *name, 180 nxt_conf_value_t *value) 181 { 182 return nxt_conf_vldt_object(conf, value, nxt_conf_vldt_listener_members); 183 } 184 185 186 static nxt_int_t 187 nxt_conf_vldt_app_name(nxt_conf_value_t *conf, nxt_conf_value_t *value, 188 void *data) 189 { 190 nxt_str_t name; 191 nxt_conf_value_t *apps, *app; 192 193 static nxt_str_t apps_str = nxt_string("applications"); 194 195 apps = nxt_conf_get_object_member(conf, &apps_str, NULL); 196 197 if (nxt_slow_path(apps == NULL)) { 198 return NXT_ERROR; 199 } 200 201 nxt_conf_get_string(value, &name); 202 203 app = nxt_conf_get_object_member(apps, &name, NULL); 204 205 if (nxt_slow_path(app == NULL)) { 206 return NXT_ERROR; 207 } 208 209 return NXT_OK; 210 } 211 212 213 static nxt_int_t 214 nxt_conf_vldt_app(nxt_conf_value_t *conf, nxt_str_t *name, 215 nxt_conf_value_t *value) 216 { 217 nxt_str_t type; 218 nxt_uint_t n; 219 nxt_thread_t *thread; 220 nxt_conf_value_t *type_value; 221 nxt_app_lang_module_t *lang; 222 223 static nxt_str_t type_str = nxt_string("type"); 224 225 static void *members[] = { 226 nxt_conf_vldt_python_members, 227 nxt_conf_vldt_php_members, 228 nxt_conf_vldt_go_members, 229 }; 230 231 type_value = nxt_conf_get_object_member(value, &type_str, NULL); 232 233 if (nxt_slow_path(type_value == NULL)) { 234 return NXT_ERROR; 235 } 236 237 if (nxt_conf_type(type_value) != NXT_CONF_STRING) { 238 return NXT_ERROR; 239 } 240 241 nxt_conf_get_string(type_value, &type); 242 243 thread = nxt_thread(); 244 245 lang = nxt_app_lang_module(thread->runtime, &type); 246 if (lang == NULL) { 247 return NXT_ERROR; 248 } 249 250 n = nxt_app_parse_type(&lang->type); 251 if (n != NXT_APP_UNKNOWN) { 252 return nxt_conf_vldt_object(conf, value, members[n]); 253 } 254 255 return NXT_ERROR; 256 } 257 258 259 static nxt_int_t 260 nxt_conf_vldt_object(nxt_conf_value_t *conf, nxt_conf_value_t *value, 261 void *data) 262 { 263 uint32_t index; 264 nxt_str_t name; 265 nxt_conf_value_t *member; 266 nxt_conf_vldt_object_t *vldt; 267 268 index = 0; 269 270 for ( ;; ) { 271 member = nxt_conf_next_object_member(value, &name, &index); 272 273 if (member == NULL) { 274 return NXT_OK; 275 } 276 277 vldt = data; 278 279 for ( ;; ) { 280 if (vldt->name.length == 0) { 281 return NXT_ERROR; 282 } 283 284 if (!nxt_strstr_eq(&vldt->name, &name)) { 285 vldt++; 286 continue; 287 } 288 289 if (nxt_conf_type(member) != vldt->type) { 290 return NXT_ERROR; 291 } 292 293 if (vldt->validator != NULL 294 && vldt->validator(conf, member, vldt->data) != NXT_OK) 295 { 296 return NXT_ERROR; 297 } 298 299 break; 300 } 301 } 302 } 303 304 305 static nxt_int_t 306 nxt_conf_vldt_object_iterator(nxt_conf_value_t *conf, nxt_conf_value_t *value, 307 void *data) 308 { 309 uint32_t index; 310 nxt_str_t name; 311 nxt_conf_value_t *member; 312 nxt_conf_vldt_member_t validator; 313 314 validator = (nxt_conf_vldt_member_t) data; 315 index = 0; 316 317 for ( ;; ) { 318 member = nxt_conf_next_object_member(value, &name, &index); 319 320 if (member == NULL) { 321 return NXT_OK; 322 } 323 324 if (validator(conf, &name, member) != NXT_OK) { 325 return NXT_ERROR; 326 } 327 } 328 } 329