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 12typedef struct { 13 nxt_str_t name; 14 nxt_conf_type_t type; 15 nxt_int_t (*validator)(nxt_conf_validation_t *vldt, 16 nxt_conf_value_t *value, void *data); 17 void *data; 18} nxt_conf_vldt_object_t; 19 20 21typedef nxt_int_t (*nxt_conf_vldt_member_t)(nxt_conf_validation_t *vldt, 22 nxt_str_t *name, 23 nxt_conf_value_t *value); 24 25typedef nxt_int_t (*nxt_conf_vldt_system_t)(nxt_conf_validation_t *vldt, 26 char *name); 27 28 29static nxt_int_t nxt_conf_vldt_type(nxt_conf_validation_t *vldt, 30 nxt_str_t *name, nxt_conf_value_t *value, nxt_conf_type_t type); 31static nxt_int_t nxt_conf_vldt_error(nxt_conf_validation_t *vldt, 32 const char *fmt, ...); 33 34static nxt_int_t nxt_conf_vldt_listener(nxt_conf_validation_t *vldt, 35 nxt_str_t *name, nxt_conf_value_t *value); 36static nxt_int_t nxt_conf_vldt_app_name(nxt_conf_validation_t *vldt, 37 nxt_conf_value_t *value, void *data); 38static nxt_int_t nxt_conf_vldt_app(nxt_conf_validation_t *vldt, 39 nxt_str_t *name, nxt_conf_value_t *value); 40static nxt_int_t nxt_conf_vldt_object(nxt_conf_validation_t *vldt, 41 nxt_conf_value_t *value, void *data); 42static nxt_int_t nxt_conf_vldt_object_iterator(nxt_conf_validation_t *vldt, 43 nxt_conf_value_t *value, void *data); 44static nxt_int_t nxt_conf_vldt_system(nxt_conf_validation_t *vldt, 45 nxt_conf_value_t *value, void *data); 46static nxt_int_t nxt_conf_vldt_user(nxt_conf_validation_t *vldt, char *name); 47static nxt_int_t nxt_conf_vldt_group(nxt_conf_validation_t *vldt, char *name); 48 49 50static nxt_conf_vldt_object_t nxt_conf_vldt_root_members[] = { 51 { nxt_string("listeners"), 52 NXT_CONF_OBJECT, 53 &nxt_conf_vldt_object_iterator, 54 (void *) &nxt_conf_vldt_listener }, 55 56 { nxt_string("applications"), 57 NXT_CONF_OBJECT, 58 &nxt_conf_vldt_object_iterator, 59 (void *) &nxt_conf_vldt_app }, 60 61 { nxt_null_string, 0, NULL, NULL } 62}; 63 64 65static nxt_conf_vldt_object_t nxt_conf_vldt_listener_members[] = { 66 { nxt_string("application"), 67 NXT_CONF_STRING, 68 &nxt_conf_vldt_app_name, 69 NULL }, 70 71 { nxt_null_string, 0, NULL, NULL } 72}; 73 74 75static nxt_conf_vldt_object_t nxt_conf_vldt_app_limits_members[] = { 76 { nxt_string("timeout"), 77 NXT_CONF_INTEGER, 78 NULL, 79 NULL }, 80
| 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 12typedef struct { 13 nxt_str_t name; 14 nxt_conf_type_t type; 15 nxt_int_t (*validator)(nxt_conf_validation_t *vldt, 16 nxt_conf_value_t *value, void *data); 17 void *data; 18} nxt_conf_vldt_object_t; 19 20 21typedef nxt_int_t (*nxt_conf_vldt_member_t)(nxt_conf_validation_t *vldt, 22 nxt_str_t *name, 23 nxt_conf_value_t *value); 24 25typedef nxt_int_t (*nxt_conf_vldt_system_t)(nxt_conf_validation_t *vldt, 26 char *name); 27 28 29static nxt_int_t nxt_conf_vldt_type(nxt_conf_validation_t *vldt, 30 nxt_str_t *name, nxt_conf_value_t *value, nxt_conf_type_t type); 31static nxt_int_t nxt_conf_vldt_error(nxt_conf_validation_t *vldt, 32 const char *fmt, ...); 33 34static nxt_int_t nxt_conf_vldt_listener(nxt_conf_validation_t *vldt, 35 nxt_str_t *name, nxt_conf_value_t *value); 36static nxt_int_t nxt_conf_vldt_app_name(nxt_conf_validation_t *vldt, 37 nxt_conf_value_t *value, void *data); 38static nxt_int_t nxt_conf_vldt_app(nxt_conf_validation_t *vldt, 39 nxt_str_t *name, nxt_conf_value_t *value); 40static nxt_int_t nxt_conf_vldt_object(nxt_conf_validation_t *vldt, 41 nxt_conf_value_t *value, void *data); 42static nxt_int_t nxt_conf_vldt_object_iterator(nxt_conf_validation_t *vldt, 43 nxt_conf_value_t *value, void *data); 44static nxt_int_t nxt_conf_vldt_system(nxt_conf_validation_t *vldt, 45 nxt_conf_value_t *value, void *data); 46static nxt_int_t nxt_conf_vldt_user(nxt_conf_validation_t *vldt, char *name); 47static nxt_int_t nxt_conf_vldt_group(nxt_conf_validation_t *vldt, char *name); 48 49 50static nxt_conf_vldt_object_t nxt_conf_vldt_root_members[] = { 51 { nxt_string("listeners"), 52 NXT_CONF_OBJECT, 53 &nxt_conf_vldt_object_iterator, 54 (void *) &nxt_conf_vldt_listener }, 55 56 { nxt_string("applications"), 57 NXT_CONF_OBJECT, 58 &nxt_conf_vldt_object_iterator, 59 (void *) &nxt_conf_vldt_app }, 60 61 { nxt_null_string, 0, NULL, NULL } 62}; 63 64 65static nxt_conf_vldt_object_t nxt_conf_vldt_listener_members[] = { 66 { nxt_string("application"), 67 NXT_CONF_STRING, 68 &nxt_conf_vldt_app_name, 69 NULL }, 70 71 { nxt_null_string, 0, NULL, NULL } 72}; 73 74 75static nxt_conf_vldt_object_t nxt_conf_vldt_app_limits_members[] = { 76 { nxt_string("timeout"), 77 NXT_CONF_INTEGER, 78 NULL, 79 NULL }, 80
|
81 { nxt_string("requests"), 82 NXT_CONF_INTEGER, 83 NULL, 84 NULL }, 85 86 { nxt_null_string, 0, NULL, NULL } 87}; 88 89 90static nxt_conf_vldt_object_t nxt_conf_vldt_python_members[] = { 91 { nxt_string("type"), 92 NXT_CONF_STRING, 93 NULL, 94 NULL }, 95 96 { nxt_string("workers"), 97 NXT_CONF_INTEGER, 98 NULL, 99 NULL }, 100 101 { nxt_string("limits"), 102 NXT_CONF_OBJECT, 103 &nxt_conf_vldt_object, 104 (void *) &nxt_conf_vldt_app_limits_members }, 105 106 { nxt_string("user"), 107 NXT_CONF_STRING, 108 nxt_conf_vldt_system, 109 (void *) &nxt_conf_vldt_user }, 110 111 { nxt_string("group"), 112 NXT_CONF_STRING, 113 nxt_conf_vldt_system, 114 (void *) &nxt_conf_vldt_group }, 115 116 { nxt_string("working_directory"), 117 NXT_CONF_STRING, 118 NULL, 119 NULL }, 120 121 { nxt_string("home"), 122 NXT_CONF_STRING, 123 NULL, 124 NULL }, 125 126 { nxt_string("path"), 127 NXT_CONF_STRING, 128 NULL, 129 NULL }, 130 131 { nxt_string("module"), 132 NXT_CONF_STRING, 133 NULL, 134 NULL }, 135 136 { nxt_null_string, 0, NULL, NULL } 137}; 138 139 140static nxt_conf_vldt_object_t nxt_conf_vldt_php_members[] = { 141 { nxt_string("type"), 142 NXT_CONF_STRING, 143 NULL, 144 NULL }, 145 146 { nxt_string("workers"), 147 NXT_CONF_INTEGER, 148 NULL, 149 NULL }, 150 151 { nxt_string("limits"), 152 NXT_CONF_OBJECT, 153 &nxt_conf_vldt_object, 154 (void *) &nxt_conf_vldt_app_limits_members }, 155 156 { nxt_string("user"), 157 NXT_CONF_STRING, 158 nxt_conf_vldt_system, 159 (void *) &nxt_conf_vldt_user }, 160 161 { nxt_string("group"), 162 NXT_CONF_STRING, 163 nxt_conf_vldt_system, 164 (void *) &nxt_conf_vldt_group }, 165 166 { nxt_string("working_directory"), 167 NXT_CONF_STRING, 168 NULL, 169 NULL }, 170 171 { nxt_string("root"), 172 NXT_CONF_STRING, 173 NULL, 174 NULL }, 175 176 { nxt_string("script"), 177 NXT_CONF_STRING, 178 NULL, 179 NULL }, 180 181 { nxt_string("index"), 182 NXT_CONF_STRING, 183 NULL, 184 NULL }, 185 186 { nxt_null_string, 0, NULL, NULL } 187}; 188 189 190static nxt_conf_vldt_object_t nxt_conf_vldt_go_members[] = { 191 { nxt_string("type"), 192 NXT_CONF_STRING, 193 NULL, 194 NULL }, 195 196 { nxt_string("workers"), 197 NXT_CONF_INTEGER, 198 NULL, 199 NULL }, 200 201 { nxt_string("limits"), 202 NXT_CONF_OBJECT, 203 &nxt_conf_vldt_object, 204 (void *) &nxt_conf_vldt_app_limits_members }, 205 206 { nxt_string("user"), 207 NXT_CONF_STRING, 208 nxt_conf_vldt_system, 209 (void *) &nxt_conf_vldt_user }, 210 211 { nxt_string("group"), 212 NXT_CONF_STRING, 213 nxt_conf_vldt_system, 214 (void *) &nxt_conf_vldt_group }, 215 216 { nxt_string("working_directory"), 217 NXT_CONF_STRING, 218 NULL, 219 NULL }, 220 221 { nxt_string("executable"), 222 NXT_CONF_STRING, 223 NULL, 224 NULL }, 225 226 { nxt_null_string, 0, NULL, NULL } 227}; 228 229 230nxt_int_t 231nxt_conf_validate(nxt_conf_validation_t *vldt) 232{ 233 nxt_int_t ret; 234 235 ret = nxt_conf_vldt_type(vldt, NULL, vldt->conf, NXT_CONF_OBJECT); 236 237 if (ret != NXT_OK) { 238 return ret; 239 } 240 241 return nxt_conf_vldt_object(vldt, vldt->conf, nxt_conf_vldt_root_members); 242} 243 244 245static nxt_int_t 246nxt_conf_vldt_type(nxt_conf_validation_t *vldt, nxt_str_t *name, 247 nxt_conf_value_t *value, nxt_conf_type_t type) 248{ 249 nxt_uint_t value_type; 250 251 static const char *type_name[] = { 252 "a null", 253 "a boolean", 254 "an integer", 255 "a number", 256 "a string", 257 "an array", 258 "an object" 259 }; 260 261 value_type = nxt_conf_type(value); 262 263 if (value_type == type) { 264 return NXT_OK; 265 } 266 267 if (name == NULL) { 268 return nxt_conf_vldt_error(vldt, 269 "The configuration must be %s, not %s.", 270 type_name[type], type_name[value_type]); 271 } 272 273 return nxt_conf_vldt_error(vldt, 274 "The \"%V\" value must be %s, not %s.", 275 name, type_name[type], type_name[value_type]); 276} 277 278 279static nxt_int_t 280nxt_conf_vldt_error(nxt_conf_validation_t *vldt, const char *fmt, ...) 281{ 282 u_char *p, *end; 283 size_t size; 284 va_list args; 285 u_char error[NXT_MAX_ERROR_STR]; 286 287 va_start(args, fmt); 288 end = nxt_vsprintf(error, error + NXT_MAX_ERROR_STR, fmt, args); 289 va_end(args); 290 291 size = end - error; 292 293 p = nxt_mp_nget(vldt->pool, size); 294 if (p == NULL) { 295 return NXT_ERROR; 296 } 297 298 nxt_memcpy(p, error, size); 299 300 vldt->error.length = size; 301 vldt->error.start = p; 302 303 return NXT_DECLINED; 304} 305 306 307static nxt_int_t 308nxt_conf_vldt_listener(nxt_conf_validation_t *vldt, nxt_str_t *name, 309 nxt_conf_value_t *value) 310{ 311 nxt_int_t ret; 312 313 ret = nxt_conf_vldt_type(vldt, name, value, NXT_CONF_OBJECT); 314 315 if (ret != NXT_OK) { 316 return ret; 317 } 318 319 return nxt_conf_vldt_object(vldt, value, nxt_conf_vldt_listener_members); 320} 321 322 323static nxt_int_t 324nxt_conf_vldt_app_name(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, 325 void *data) 326{ 327 nxt_str_t name; 328 nxt_conf_value_t *apps, *app; 329 330 static nxt_str_t apps_str = nxt_string("applications"); 331 332 nxt_conf_get_string(value, &name); 333 334 apps = nxt_conf_get_object_member(vldt->conf, &apps_str, NULL); 335 336 if (nxt_slow_path(apps == NULL)) { 337 goto error; 338 } 339 340 app = nxt_conf_get_object_member(apps, &name, NULL); 341 342 if (nxt_slow_path(app == NULL)) { 343 goto error; 344 } 345 346 return NXT_OK; 347 348error: 349 350 return nxt_conf_vldt_error(vldt, "Listening socket is assigned for " 351 "a non existing application \"%V\".", 352 &name); 353} 354 355 356static nxt_int_t 357nxt_conf_vldt_app(nxt_conf_validation_t *vldt, nxt_str_t *name, 358 nxt_conf_value_t *value) 359{ 360 nxt_int_t ret; 361 nxt_str_t type; 362 nxt_thread_t *thread; 363 nxt_conf_value_t *type_value; 364 nxt_app_lang_module_t *lang; 365 366 static nxt_str_t type_str = nxt_string("type"); 367 368 static void *members[] = { 369 nxt_conf_vldt_python_members, 370 nxt_conf_vldt_php_members, 371 nxt_conf_vldt_go_members, 372 }; 373 374 ret = nxt_conf_vldt_type(vldt, name, value, NXT_CONF_OBJECT); 375 376 if (ret != NXT_OK) { 377 return ret; 378 } 379 380 type_value = nxt_conf_get_object_member(value, &type_str, NULL); 381 382 if (type_value == NULL) { 383 return nxt_conf_vldt_error(vldt, 384 "Application must have the \"type\" property set."); 385 } 386 387 ret = nxt_conf_vldt_type(vldt, &type_str, type_value, NXT_CONF_STRING); 388 389 if (ret != NXT_OK) { 390 return ret; 391 } 392 393 nxt_conf_get_string(type_value, &type); 394 395 thread = nxt_thread(); 396 397 lang = nxt_app_lang_module(thread->runtime, &type); 398 if (lang == NULL) { 399 return nxt_conf_vldt_error(vldt, 400 "The module to run \"%V\" is not found " 401 "among the available application modules.", 402 &type); 403 } 404 405 return nxt_conf_vldt_object(vldt, value, members[lang->type]); 406} 407 408 409static nxt_int_t 410nxt_conf_vldt_object(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, 411 void *data) 412{ 413 uint32_t index; 414 nxt_int_t ret; 415 nxt_str_t name; 416 nxt_conf_value_t *member; 417 nxt_conf_vldt_object_t *vals; 418 419 index = 0; 420 421 for ( ;; ) { 422 member = nxt_conf_next_object_member(value, &name, &index); 423 424 if (member == NULL) { 425 return NXT_OK; 426 } 427 428 vals = data; 429 430 for ( ;; ) { 431 if (vals->name.length == 0) { 432 return nxt_conf_vldt_error(vldt, "Unknown parameter \"%V\".", 433 &name); 434 } 435 436 if (!nxt_strstr_eq(&vals->name, &name)) { 437 vals++; 438 continue; 439 } 440 441 ret = nxt_conf_vldt_type(vldt, &name, member, vals->type); 442 443 if (ret != NXT_OK) { 444 return ret; 445 } 446 447 if (vals->validator != NULL) { 448 ret = vals->validator(vldt, member, vals->data); 449 450 if (ret != NXT_OK) { 451 return ret; 452 } 453 } 454 455 break; 456 } 457 } 458} 459 460 461static nxt_int_t 462nxt_conf_vldt_object_iterator(nxt_conf_validation_t *vldt, 463 nxt_conf_value_t *value, void *data) 464{ 465 uint32_t index; 466 nxt_int_t ret; 467 nxt_str_t name; 468 nxt_conf_value_t *member; 469 nxt_conf_vldt_member_t validator; 470 471 validator = (nxt_conf_vldt_member_t) data; 472 index = 0; 473 474 for ( ;; ) { 475 member = nxt_conf_next_object_member(value, &name, &index); 476 477 if (member == NULL) { 478 return NXT_OK; 479 } 480 481 ret = validator(vldt, &name, member); 482 483 if (ret != NXT_OK) { 484 return ret; 485 } 486 } 487} 488 489 490static nxt_int_t 491nxt_conf_vldt_system(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, 492 void *data) 493{ 494 size_t length; 495 nxt_str_t name; 496 nxt_conf_vldt_system_t validator; 497 char string[32]; 498 499 /* The cast is required by Sun C. */ 500 validator = (nxt_conf_vldt_system_t) data; 501 502 nxt_conf_get_string(value, &name); 503 504 length = name.length + 1; 505 length = nxt_min(length, sizeof(string)); 506 507 nxt_cpystrn((u_char *) string, name.start, length); 508 509 return validator(vldt, string); 510} 511 512 513static nxt_int_t 514nxt_conf_vldt_user(nxt_conf_validation_t *vldt, char *user) 515{ 516 struct passwd *pwd; 517 518 nxt_errno = 0; 519 520 pwd = getpwnam(user); 521 522 if (pwd != NULL) { 523 return NXT_OK; 524 } 525 526 if (nxt_errno == 0) { 527 return nxt_conf_vldt_error(vldt, "User \"%s\" is not found.", user); 528 } 529 530 return NXT_ERROR; 531} 532 533 534static nxt_int_t 535nxt_conf_vldt_group(nxt_conf_validation_t *vldt, char *group) 536{ 537 struct group *grp; 538 539 nxt_errno = 0; 540 541 grp = getgrnam(group); 542 543 if (grp != NULL) { 544 return NXT_OK; 545 } 546 547 if (nxt_errno == 0) { 548 return nxt_conf_vldt_error(vldt, "Group \"%s\" is not found.", group); 549 } 550 551 return NXT_ERROR; 552} 553 554
| 86 { nxt_string("requests"), 87 NXT_CONF_INTEGER, 88 NULL, 89 NULL }, 90 91 { nxt_null_string, 0, NULL, NULL } 92}; 93 94 95static nxt_conf_vldt_object_t nxt_conf_vldt_python_members[] = { 96 { nxt_string("type"), 97 NXT_CONF_STRING, 98 NULL, 99 NULL }, 100 101 { nxt_string("workers"), 102 NXT_CONF_INTEGER, 103 NULL, 104 NULL }, 105 106 { nxt_string("limits"), 107 NXT_CONF_OBJECT, 108 &nxt_conf_vldt_object, 109 (void *) &nxt_conf_vldt_app_limits_members }, 110 111 { nxt_string("user"), 112 NXT_CONF_STRING, 113 nxt_conf_vldt_system, 114 (void *) &nxt_conf_vldt_user }, 115 116 { nxt_string("group"), 117 NXT_CONF_STRING, 118 nxt_conf_vldt_system, 119 (void *) &nxt_conf_vldt_group }, 120 121 { nxt_string("working_directory"), 122 NXT_CONF_STRING, 123 NULL, 124 NULL }, 125 126 { nxt_string("home"), 127 NXT_CONF_STRING, 128 NULL, 129 NULL }, 130 131 { nxt_string("path"), 132 NXT_CONF_STRING, 133 NULL, 134 NULL }, 135 136 { nxt_string("module"), 137 NXT_CONF_STRING, 138 NULL, 139 NULL }, 140 141 { nxt_null_string, 0, NULL, NULL } 142}; 143 144 145static nxt_conf_vldt_object_t nxt_conf_vldt_php_members[] = { 146 { nxt_string("type"), 147 NXT_CONF_STRING, 148 NULL, 149 NULL }, 150 151 { nxt_string("workers"), 152 NXT_CONF_INTEGER, 153 NULL, 154 NULL }, 155 156 { nxt_string("limits"), 157 NXT_CONF_OBJECT, 158 &nxt_conf_vldt_object, 159 (void *) &nxt_conf_vldt_app_limits_members }, 160 161 { nxt_string("user"), 162 NXT_CONF_STRING, 163 nxt_conf_vldt_system, 164 (void *) &nxt_conf_vldt_user }, 165 166 { nxt_string("group"), 167 NXT_CONF_STRING, 168 nxt_conf_vldt_system, 169 (void *) &nxt_conf_vldt_group }, 170 171 { nxt_string("working_directory"), 172 NXT_CONF_STRING, 173 NULL, 174 NULL }, 175 176 { nxt_string("root"), 177 NXT_CONF_STRING, 178 NULL, 179 NULL }, 180 181 { nxt_string("script"), 182 NXT_CONF_STRING, 183 NULL, 184 NULL }, 185 186 { nxt_string("index"), 187 NXT_CONF_STRING, 188 NULL, 189 NULL }, 190 191 { nxt_null_string, 0, NULL, NULL } 192}; 193 194 195static nxt_conf_vldt_object_t nxt_conf_vldt_go_members[] = { 196 { nxt_string("type"), 197 NXT_CONF_STRING, 198 NULL, 199 NULL }, 200 201 { nxt_string("workers"), 202 NXT_CONF_INTEGER, 203 NULL, 204 NULL }, 205 206 { nxt_string("limits"), 207 NXT_CONF_OBJECT, 208 &nxt_conf_vldt_object, 209 (void *) &nxt_conf_vldt_app_limits_members }, 210 211 { nxt_string("user"), 212 NXT_CONF_STRING, 213 nxt_conf_vldt_system, 214 (void *) &nxt_conf_vldt_user }, 215 216 { nxt_string("group"), 217 NXT_CONF_STRING, 218 nxt_conf_vldt_system, 219 (void *) &nxt_conf_vldt_group }, 220 221 { nxt_string("working_directory"), 222 NXT_CONF_STRING, 223 NULL, 224 NULL }, 225 226 { nxt_string("executable"), 227 NXT_CONF_STRING, 228 NULL, 229 NULL }, 230 231 { nxt_null_string, 0, NULL, NULL } 232}; 233 234 235nxt_int_t 236nxt_conf_validate(nxt_conf_validation_t *vldt) 237{ 238 nxt_int_t ret; 239 240 ret = nxt_conf_vldt_type(vldt, NULL, vldt->conf, NXT_CONF_OBJECT); 241 242 if (ret != NXT_OK) { 243 return ret; 244 } 245 246 return nxt_conf_vldt_object(vldt, vldt->conf, nxt_conf_vldt_root_members); 247} 248 249 250static nxt_int_t 251nxt_conf_vldt_type(nxt_conf_validation_t *vldt, nxt_str_t *name, 252 nxt_conf_value_t *value, nxt_conf_type_t type) 253{ 254 nxt_uint_t value_type; 255 256 static const char *type_name[] = { 257 "a null", 258 "a boolean", 259 "an integer", 260 "a number", 261 "a string", 262 "an array", 263 "an object" 264 }; 265 266 value_type = nxt_conf_type(value); 267 268 if (value_type == type) { 269 return NXT_OK; 270 } 271 272 if (name == NULL) { 273 return nxt_conf_vldt_error(vldt, 274 "The configuration must be %s, not %s.", 275 type_name[type], type_name[value_type]); 276 } 277 278 return nxt_conf_vldt_error(vldt, 279 "The \"%V\" value must be %s, not %s.", 280 name, type_name[type], type_name[value_type]); 281} 282 283 284static nxt_int_t 285nxt_conf_vldt_error(nxt_conf_validation_t *vldt, const char *fmt, ...) 286{ 287 u_char *p, *end; 288 size_t size; 289 va_list args; 290 u_char error[NXT_MAX_ERROR_STR]; 291 292 va_start(args, fmt); 293 end = nxt_vsprintf(error, error + NXT_MAX_ERROR_STR, fmt, args); 294 va_end(args); 295 296 size = end - error; 297 298 p = nxt_mp_nget(vldt->pool, size); 299 if (p == NULL) { 300 return NXT_ERROR; 301 } 302 303 nxt_memcpy(p, error, size); 304 305 vldt->error.length = size; 306 vldt->error.start = p; 307 308 return NXT_DECLINED; 309} 310 311 312static nxt_int_t 313nxt_conf_vldt_listener(nxt_conf_validation_t *vldt, nxt_str_t *name, 314 nxt_conf_value_t *value) 315{ 316 nxt_int_t ret; 317 318 ret = nxt_conf_vldt_type(vldt, name, value, NXT_CONF_OBJECT); 319 320 if (ret != NXT_OK) { 321 return ret; 322 } 323 324 return nxt_conf_vldt_object(vldt, value, nxt_conf_vldt_listener_members); 325} 326 327 328static nxt_int_t 329nxt_conf_vldt_app_name(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, 330 void *data) 331{ 332 nxt_str_t name; 333 nxt_conf_value_t *apps, *app; 334 335 static nxt_str_t apps_str = nxt_string("applications"); 336 337 nxt_conf_get_string(value, &name); 338 339 apps = nxt_conf_get_object_member(vldt->conf, &apps_str, NULL); 340 341 if (nxt_slow_path(apps == NULL)) { 342 goto error; 343 } 344 345 app = nxt_conf_get_object_member(apps, &name, NULL); 346 347 if (nxt_slow_path(app == NULL)) { 348 goto error; 349 } 350 351 return NXT_OK; 352 353error: 354 355 return nxt_conf_vldt_error(vldt, "Listening socket is assigned for " 356 "a non existing application \"%V\".", 357 &name); 358} 359 360 361static nxt_int_t 362nxt_conf_vldt_app(nxt_conf_validation_t *vldt, nxt_str_t *name, 363 nxt_conf_value_t *value) 364{ 365 nxt_int_t ret; 366 nxt_str_t type; 367 nxt_thread_t *thread; 368 nxt_conf_value_t *type_value; 369 nxt_app_lang_module_t *lang; 370 371 static nxt_str_t type_str = nxt_string("type"); 372 373 static void *members[] = { 374 nxt_conf_vldt_python_members, 375 nxt_conf_vldt_php_members, 376 nxt_conf_vldt_go_members, 377 }; 378 379 ret = nxt_conf_vldt_type(vldt, name, value, NXT_CONF_OBJECT); 380 381 if (ret != NXT_OK) { 382 return ret; 383 } 384 385 type_value = nxt_conf_get_object_member(value, &type_str, NULL); 386 387 if (type_value == NULL) { 388 return nxt_conf_vldt_error(vldt, 389 "Application must have the \"type\" property set."); 390 } 391 392 ret = nxt_conf_vldt_type(vldt, &type_str, type_value, NXT_CONF_STRING); 393 394 if (ret != NXT_OK) { 395 return ret; 396 } 397 398 nxt_conf_get_string(type_value, &type); 399 400 thread = nxt_thread(); 401 402 lang = nxt_app_lang_module(thread->runtime, &type); 403 if (lang == NULL) { 404 return nxt_conf_vldt_error(vldt, 405 "The module to run \"%V\" is not found " 406 "among the available application modules.", 407 &type); 408 } 409 410 return nxt_conf_vldt_object(vldt, value, members[lang->type]); 411} 412 413 414static nxt_int_t 415nxt_conf_vldt_object(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, 416 void *data) 417{ 418 uint32_t index; 419 nxt_int_t ret; 420 nxt_str_t name; 421 nxt_conf_value_t *member; 422 nxt_conf_vldt_object_t *vals; 423 424 index = 0; 425 426 for ( ;; ) { 427 member = nxt_conf_next_object_member(value, &name, &index); 428 429 if (member == NULL) { 430 return NXT_OK; 431 } 432 433 vals = data; 434 435 for ( ;; ) { 436 if (vals->name.length == 0) { 437 return nxt_conf_vldt_error(vldt, "Unknown parameter \"%V\".", 438 &name); 439 } 440 441 if (!nxt_strstr_eq(&vals->name, &name)) { 442 vals++; 443 continue; 444 } 445 446 ret = nxt_conf_vldt_type(vldt, &name, member, vals->type); 447 448 if (ret != NXT_OK) { 449 return ret; 450 } 451 452 if (vals->validator != NULL) { 453 ret = vals->validator(vldt, member, vals->data); 454 455 if (ret != NXT_OK) { 456 return ret; 457 } 458 } 459 460 break; 461 } 462 } 463} 464 465 466static nxt_int_t 467nxt_conf_vldt_object_iterator(nxt_conf_validation_t *vldt, 468 nxt_conf_value_t *value, void *data) 469{ 470 uint32_t index; 471 nxt_int_t ret; 472 nxt_str_t name; 473 nxt_conf_value_t *member; 474 nxt_conf_vldt_member_t validator; 475 476 validator = (nxt_conf_vldt_member_t) data; 477 index = 0; 478 479 for ( ;; ) { 480 member = nxt_conf_next_object_member(value, &name, &index); 481 482 if (member == NULL) { 483 return NXT_OK; 484 } 485 486 ret = validator(vldt, &name, member); 487 488 if (ret != NXT_OK) { 489 return ret; 490 } 491 } 492} 493 494 495static nxt_int_t 496nxt_conf_vldt_system(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, 497 void *data) 498{ 499 size_t length; 500 nxt_str_t name; 501 nxt_conf_vldt_system_t validator; 502 char string[32]; 503 504 /* The cast is required by Sun C. */ 505 validator = (nxt_conf_vldt_system_t) data; 506 507 nxt_conf_get_string(value, &name); 508 509 length = name.length + 1; 510 length = nxt_min(length, sizeof(string)); 511 512 nxt_cpystrn((u_char *) string, name.start, length); 513 514 return validator(vldt, string); 515} 516 517 518static nxt_int_t 519nxt_conf_vldt_user(nxt_conf_validation_t *vldt, char *user) 520{ 521 struct passwd *pwd; 522 523 nxt_errno = 0; 524 525 pwd = getpwnam(user); 526 527 if (pwd != NULL) { 528 return NXT_OK; 529 } 530 531 if (nxt_errno == 0) { 532 return nxt_conf_vldt_error(vldt, "User \"%s\" is not found.", user); 533 } 534 535 return NXT_ERROR; 536} 537 538 539static nxt_int_t 540nxt_conf_vldt_group(nxt_conf_validation_t *vldt, char *group) 541{ 542 struct group *grp; 543 544 nxt_errno = 0; 545 546 grp = getgrnam(group); 547 548 if (grp != NULL) { 549 return NXT_OK; 550 } 551 552 if (nxt_errno == 0) { 553 return nxt_conf_vldt_error(vldt, "Group \"%s\" is not found.", group); 554 } 555 556 return NXT_ERROR; 557} 558 559
|