diff options
author | Valentin Bartenev <vbart@nginx.com> | 2020-05-14 13:15:01 +0300 |
---|---|---|
committer | Valentin Bartenev <vbart@nginx.com> | 2020-05-14 13:15:01 +0300 |
commit | 376d758dd72ac27f2bd5bb833ba68f5c9b531880 (patch) | |
tree | a3891a0586669543c35004ccbff3a6deca893903 /src/nxt_conf_validation.c | |
parent | 0174c971b5ec0d604e4e9becfa41e0bc31179e57 (diff) | |
download | unit-376d758dd72ac27f2bd5bb833ba68f5c9b531880.tar.gz unit-376d758dd72ac27f2bd5bb833ba68f5c9b531880.tar.bz2 |
PHP: implemented "targets" option.
This allows to specify multiple subsequent targets inside PHP applications.
For example:
{
"listeners": {
"*:80": {
"pass": "routes"
}
},
"routes": [
{
"match": {
"uri": "/info"
},
"action": {
"pass": "applications/my_app/phpinfo"
}
},
{
"match": {
"uri": "/hello"
},
"action": {
"pass": "applications/my_app/hello"
}
},
{
"action": {
"pass": "applications/my_app/rest"
}
}
],
"applications": {
"my_app": {
"type": "php",
"targets": {
"phpinfo": {
"script": "phpinfo.php",
"root": "/www/data/admin",
},
"hello": {
"script": "hello.php",
"root": "/www/data/test",
},
"rest": {
"root": "/www/data/example.com",
"index": "index.php"
},
}
}
}
}
Diffstat (limited to 'src/nxt_conf_validation.c')
-rw-r--r-- | src/nxt_conf_validation.c | 202 |
1 files changed, 179 insertions, 23 deletions
diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index 476fc97b..0f46560d 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -23,13 +23,24 @@ typedef enum { NXT_CONF_VLDT_OBJECT = 1 << NXT_CONF_OBJECT, } nxt_conf_vldt_type_t; +#define NXT_CONF_VLDT_ANY_TYPE (NXT_CONF_VLDT_NULL \ + |NXT_CONF_VLDT_BOOLEAN \ + |NXT_CONF_VLDT_NUMBER \ + |NXT_CONF_VLDT_STRING \ + |NXT_CONF_VLDT_ARRAY \ + |NXT_CONF_VLDT_OBJECT) + + +typedef nxt_int_t (*nxt_conf_vldt_handler_t)(nxt_conf_validation_t *vldt, + nxt_conf_value_t *value, + void *data); + typedef struct { - nxt_str_t name; - nxt_conf_vldt_type_t type; - nxt_int_t (*validator)(nxt_conf_validation_t *vldt, - nxt_conf_value_t *value, void *data); - void *data; + nxt_str_t name; + nxt_conf_vldt_type_t type; + nxt_conf_vldt_handler_t validator; + void *data; } nxt_conf_vldt_object_t; @@ -106,6 +117,14 @@ static nxt_int_t nxt_conf_vldt_environment(nxt_conf_validation_t *vldt, nxt_str_t *name, nxt_conf_value_t *value); static nxt_int_t nxt_conf_vldt_argument(nxt_conf_validation_t *vldt, nxt_conf_value_t *value); +static nxt_int_t nxt_conf_vldt_php(nxt_conf_validation_t *vldt, + nxt_conf_value_t *value, void *data); +static nxt_int_t nxt_conf_vldt_php_targets_exclusive( + nxt_conf_validation_t *vldt, nxt_conf_value_t *value, void *data); +static nxt_int_t nxt_conf_vldt_php_targets(nxt_conf_validation_t *vldt, + nxt_conf_value_t *value, void *data); +static nxt_int_t nxt_conf_vldt_php_target(nxt_conf_validation_t *vldt, + nxt_str_t *name, nxt_conf_value_t *value); static nxt_int_t nxt_conf_vldt_php_option(nxt_conf_validation_t *vldt, nxt_str_t *name, nxt_conf_value_t *value); static nxt_int_t nxt_conf_vldt_java_classpath(nxt_conf_validation_t *vldt, @@ -630,6 +649,24 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_python_members[] = { }; +static nxt_conf_vldt_object_t nxt_conf_vldt_php_target_members[] = { + { nxt_string("root"), + NXT_CONF_VLDT_STRING, + NULL, + NULL }, + + { nxt_string("script"), + NXT_CONF_VLDT_STRING, + NULL, + NULL }, + + { nxt_string("index"), + NXT_CONF_VLDT_STRING, + NULL, + NULL } +}; + + static nxt_conf_vldt_object_t nxt_conf_vldt_php_options_members[] = { { nxt_string("file"), NXT_CONF_VLDT_STRING, @@ -650,7 +687,17 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_php_options_members[] = { }; -static nxt_conf_vldt_object_t nxt_conf_vldt_php_members[] = { +static nxt_conf_vldt_object_t nxt_conf_vldt_php_common_members[] = { + { nxt_string("options"), + NXT_CONF_VLDT_OBJECT, + &nxt_conf_vldt_object, + (void *) &nxt_conf_vldt_php_options_members }, + + NXT_CONF_VLDT_NEXT(&nxt_conf_vldt_common_members) +}; + + +static nxt_conf_vldt_object_t nxt_conf_vldt_php_notargets_members[] = { { nxt_string("root"), NXT_CONF_VLDT_STRING, NULL, @@ -666,12 +713,32 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_php_members[] = { NULL, NULL }, - { nxt_string("options"), + NXT_CONF_VLDT_NEXT(&nxt_conf_vldt_php_common_members) +}; + + +static nxt_conf_vldt_object_t nxt_conf_vldt_php_members[] = { + { nxt_string("root"), + NXT_CONF_VLDT_ANY_TYPE, + &nxt_conf_vldt_php_targets_exclusive, + (void *) "root" }, + + { nxt_string("script"), + NXT_CONF_VLDT_ANY_TYPE, + &nxt_conf_vldt_php_targets_exclusive, + (void *) "script" }, + + { nxt_string("index"), + NXT_CONF_VLDT_ANY_TYPE, + &nxt_conf_vldt_php_targets_exclusive, + (void *) "index" }, + + { nxt_string("targets"), NXT_CONF_VLDT_OBJECT, - &nxt_conf_vldt_object, - (void *) &nxt_conf_vldt_php_options_members }, + &nxt_conf_vldt_php_targets, + NULL }, - NXT_CONF_VLDT_NEXT(&nxt_conf_vldt_common_members) + NXT_CONF_VLDT_NEXT(&nxt_conf_vldt_php_common_members) }; @@ -755,7 +822,7 @@ nxt_conf_validate(nxt_conf_validation_t *vldt) } -#define NXT_CONF_VLDT_ANY_TYPE \ +#define NXT_CONF_VLDT_ANY_TYPE_STR \ "either a null, a boolean, an integer, " \ "a number, a string, an array, or an object" @@ -768,7 +835,7 @@ nxt_conf_vldt_type(nxt_conf_validation_t *vldt, nxt_str_t *name, nxt_str_t expected; nxt_bool_t serial; nxt_uint_t value_type, n, t; - u_char buf[nxt_length(NXT_CONF_VLDT_ANY_TYPE)]; + u_char buf[nxt_length(NXT_CONF_VLDT_ANY_TYPE_STR)]; static nxt_str_t type_name[] = { nxt_string("a null"), @@ -1034,11 +1101,13 @@ nxt_conf_vldt_pass(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, { nxt_str_t pass; nxt_int_t ret; - nxt_str_t segments[2]; + nxt_str_t segments[3]; + + static nxt_str_t targets_str = nxt_string("targets"); nxt_conf_get_string(value, &pass); - ret = nxt_http_pass_segments(vldt->pool, &pass, segments, 2); + ret = nxt_http_pass_segments(vldt->pool, &pass, segments, 3); if (ret != NXT_OK) { if (ret == NXT_DECLINED) { @@ -1067,12 +1136,26 @@ nxt_conf_vldt_pass(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, goto error; } + if (segments[2].length > 0) { + value = nxt_conf_get_object_member(value, &targets_str, NULL); + + if (value == NULL) { + goto error; + } + + value = nxt_conf_get_object_member(value, &segments[2], NULL); + + if (value == NULL) { + goto error; + } + } + return NXT_OK; } if (nxt_str_eq(&segments[0], "upstreams", 9)) { - if (segments[1].length == 0) { + if (segments[1].length == 0 || segments[2].length != 0) { goto error; } @@ -1092,6 +1175,11 @@ nxt_conf_vldt_pass(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, } if (nxt_str_eq(&segments[0], "routes", 6)) { + + if (segments[2].length != 0) { + goto error; + } + value = nxt_conf_get_object_member(vldt->conf, &segments[0], NULL); if (value == NULL) { @@ -1482,13 +1570,17 @@ nxt_conf_vldt_app(nxt_conf_validation_t *vldt, nxt_str_t *name, static nxt_str_t type_str = nxt_string("type"); - static void *members[] = { - nxt_conf_vldt_external_members, - nxt_conf_vldt_python_members, - nxt_conf_vldt_php_members, - nxt_conf_vldt_perl_members, - nxt_conf_vldt_ruby_members, - nxt_conf_vldt_java_members, + static struct { + nxt_conf_vldt_handler_t validator; + nxt_conf_vldt_object_t *members; + + } types[] = { + { nxt_conf_vldt_object, nxt_conf_vldt_external_members }, + { nxt_conf_vldt_object, nxt_conf_vldt_python_members }, + { nxt_conf_vldt_php, NULL }, + { nxt_conf_vldt_object, nxt_conf_vldt_perl_members }, + { nxt_conf_vldt_object, nxt_conf_vldt_ruby_members }, + { nxt_conf_vldt_object, nxt_conf_vldt_java_members }, }; ret = nxt_conf_vldt_type(vldt, name, value, NXT_CONF_VLDT_OBJECT); @@ -1522,7 +1614,7 @@ nxt_conf_vldt_app(nxt_conf_validation_t *vldt, nxt_str_t *name, &type); } - return nxt_conf_vldt_object(vldt, value, members[lang->type]); + return types[lang->type].validator(vldt, value, types[lang->type].members); } @@ -1934,6 +2026,70 @@ nxt_conf_vldt_argument(nxt_conf_validation_t *vldt, nxt_conf_value_t *value) static nxt_int_t +nxt_conf_vldt_php(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, + void *data) +{ + nxt_conf_value_t *targets; + + static nxt_str_t targets_str = nxt_string("targets"); + + targets = nxt_conf_get_object_member(value, &targets_str, NULL); + + if (targets != NULL) { + return nxt_conf_vldt_object(vldt, value, nxt_conf_vldt_php_members); + } + + return nxt_conf_vldt_object(vldt, value, + nxt_conf_vldt_php_notargets_members); +} + + +static nxt_int_t +nxt_conf_vldt_php_targets_exclusive(nxt_conf_validation_t *vldt, + nxt_conf_value_t *value, void *data) +{ + return nxt_conf_vldt_error(vldt, "The \"%s\" option is mutually exclusive " + "with the \"targets\" object.", data); +} + + +static nxt_int_t +nxt_conf_vldt_php_targets(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, + void *data) +{ + nxt_uint_t n; + + n = nxt_conf_object_members_count(value); + + if (n > 254) { + return nxt_conf_vldt_error(vldt, "The \"targets\" object must not " + "contain more than 254 members."); + } + + return nxt_conf_vldt_object_iterator(vldt, value, + &nxt_conf_vldt_php_target); +} + + +static nxt_int_t +nxt_conf_vldt_php_target(nxt_conf_validation_t *vldt, nxt_str_t *name, + nxt_conf_value_t *value) +{ + if (name->length == 0) { + return nxt_conf_vldt_error(vldt, + "The PHP target name must not be empty."); + } + + if (nxt_conf_type(value) != NXT_CONF_OBJECT) { + return nxt_conf_vldt_error(vldt, "The \"%V\" PHP target must be " + "an object.", name); + } + + return nxt_conf_vldt_object(vldt, value, &nxt_conf_vldt_php_target_members); +} + + +static nxt_int_t nxt_conf_vldt_php_option(nxt_conf_validation_t *vldt, nxt_str_t *name, nxt_conf_value_t *value) { |