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" }, } } } }
This commit is contained in:
parent
0174c971b5
commit
376d758dd7
11 changed files with 515 additions and 266 deletions
|
@ -54,9 +54,7 @@ typedef struct {
|
|||
|
||||
|
||||
typedef struct {
|
||||
char *root;
|
||||
nxt_str_t script;
|
||||
nxt_str_t index;
|
||||
nxt_conf_value_t *targets;
|
||||
nxt_conf_value_t *options;
|
||||
} nxt_php_app_conf_t;
|
||||
|
||||
|
@ -101,6 +99,8 @@ struct nxt_common_app_conf_s {
|
|||
nxt_ruby_app_conf_t ruby;
|
||||
nxt_java_app_conf_t java;
|
||||
} u;
|
||||
|
||||
nxt_conf_value_t *self;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -118,7 +118,7 @@ NXT_EXPORT double nxt_conf_get_number(nxt_conf_value_t *value);
|
|||
NXT_EXPORT uint8_t nxt_conf_get_boolean(nxt_conf_value_t *value);
|
||||
|
||||
// FIXME reimplement and reorder functions below
|
||||
nxt_uint_t nxt_conf_object_members_count(nxt_conf_value_t *value);
|
||||
NXT_EXPORT nxt_uint_t nxt_conf_object_members_count(nxt_conf_value_t *value);
|
||||
nxt_conf_value_t *nxt_conf_create_object(nxt_mp_t *mp, nxt_uint_t count);
|
||||
void nxt_conf_set_member(nxt_conf_value_t *object, nxt_str_t *name,
|
||||
nxt_conf_value_t *value, uint32_t index);
|
||||
|
|
|
@ -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_OBJECT,
|
||||
&nxt_conf_vldt_object,
|
||||
(void *) &nxt_conf_vldt_php_options_members },
|
||||
NXT_CONF_VLDT_NEXT(&nxt_conf_vldt_php_common_members)
|
||||
};
|
||||
|
||||
NXT_CONF_VLDT_NEXT(&nxt_conf_vldt_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_php_targets,
|
||||
NULL },
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1933,6 +2025,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)
|
||||
|
|
|
@ -175,6 +175,7 @@ struct nxt_http_request_s {
|
|||
nxt_http_status_t status:16;
|
||||
|
||||
uint8_t pass_count; /* 8 bits */
|
||||
uint8_t app_target;
|
||||
nxt_http_protocol_t protocol:8; /* 2 bits */
|
||||
uint8_t logged; /* 1 bit */
|
||||
uint8_t header_sent; /* 1 bit */
|
||||
|
@ -201,6 +202,7 @@ struct nxt_http_action_s {
|
|||
} u;
|
||||
|
||||
nxt_str_t name;
|
||||
nxt_int_t target;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -341,6 +341,8 @@ nxt_http_application_handler(nxt_task_t *task, nxt_http_request_t *r,
|
|||
nxt_str_set(&r->server_name, "localhost");
|
||||
}
|
||||
|
||||
r->app_target = action->target;
|
||||
|
||||
nxt_router_process_http_request(task, r, action->u.application);
|
||||
|
||||
return NULL;
|
||||
|
|
|
@ -1151,8 +1151,10 @@ static nxt_int_t
|
|||
nxt_http_action_resolve(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
||||
nxt_http_action_t *action)
|
||||
{
|
||||
nxt_int_t ret;
|
||||
nxt_str_t segments[2];
|
||||
nxt_str_t *targets;
|
||||
nxt_int_t ret;
|
||||
nxt_uint_t i;
|
||||
nxt_str_t segments[3];
|
||||
|
||||
if (action->handler != NULL) {
|
||||
if (action->handler == nxt_http_static_handler
|
||||
|
@ -1164,7 +1166,7 @@ nxt_http_action_resolve(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
|||
return NXT_OK;
|
||||
}
|
||||
|
||||
ret = nxt_http_pass_segments(tmcf->mem_pool, &action->name, segments, 2);
|
||||
ret = nxt_http_pass_segments(tmcf->mem_pool, &action->name, segments, 3);
|
||||
if (nxt_slow_path(ret != NXT_OK)) {
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
@ -1173,6 +1175,17 @@ nxt_http_action_resolve(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
|||
nxt_router_listener_application(tmcf, &segments[1], action);
|
||||
nxt_router_app_use(task, action->u.application, 1);
|
||||
|
||||
if (segments[2].length != 0) {
|
||||
targets = action->u.application->targets;
|
||||
|
||||
for (i = 0; !nxt_strstr_eq(&segments[2], &targets[i]); i++);
|
||||
|
||||
action->target = i;
|
||||
|
||||
} else {
|
||||
action->target = 0;
|
||||
}
|
||||
|
||||
} else if (nxt_str_eq(&segments[0], "upstreams", 9)) {
|
||||
nxt_upstream_find(tmcf->router_conf->upstreams, &segments[1], action);
|
||||
|
||||
|
@ -1298,6 +1311,8 @@ nxt_http_pass_application(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
|||
nxt_router_listener_application(tmcf, name, action);
|
||||
nxt_router_app_use(task, action->u.application, 1);
|
||||
|
||||
action->target = 0;
|
||||
|
||||
return action;
|
||||
}
|
||||
|
||||
|
|
|
@ -275,21 +275,9 @@ static nxt_conf_map_t nxt_python_app_conf[] = {
|
|||
|
||||
static nxt_conf_map_t nxt_php_app_conf[] = {
|
||||
{
|
||||
nxt_string("root"),
|
||||
NXT_CONF_MAP_CSTRZ,
|
||||
offsetof(nxt_common_app_conf_t, u.php.root),
|
||||
},
|
||||
|
||||
{
|
||||
nxt_string("script"),
|
||||
NXT_CONF_MAP_STR,
|
||||
offsetof(nxt_common_app_conf_t, u.php.script),
|
||||
},
|
||||
|
||||
{
|
||||
nxt_string("index"),
|
||||
NXT_CONF_MAP_STR,
|
||||
offsetof(nxt_common_app_conf_t, u.php.index),
|
||||
nxt_string("targets"),
|
||||
NXT_CONF_MAP_PTR,
|
||||
offsetof(nxt_common_app_conf_t, u.php.targets),
|
||||
},
|
||||
|
||||
{
|
||||
|
@ -457,6 +445,8 @@ nxt_port_main_start_worker_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg)
|
|||
}
|
||||
}
|
||||
|
||||
app_conf.self = conf;
|
||||
|
||||
ret = nxt_main_start_worker_process(task, task->thread->runtime,
|
||||
&app_conf, msg->port_msg.stream);
|
||||
|
||||
|
|
|
@ -29,8 +29,20 @@
|
|||
#define NXT_PHP7 1
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
nxt_str_t root;
|
||||
nxt_str_t index;
|
||||
nxt_str_t script_name;
|
||||
nxt_str_t script_dirname;
|
||||
nxt_str_t script_filename;
|
||||
} nxt_php_target_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
char *cookie;
|
||||
nxt_str_t *root;
|
||||
nxt_str_t *index;
|
||||
nxt_str_t path_info;
|
||||
nxt_str_t script_name;
|
||||
nxt_str_t script_filename;
|
||||
|
@ -53,26 +65,27 @@ typedef void (*zif_handler)(INTERNAL_FUNCTION_PARAMETERS);
|
|||
|
||||
|
||||
static nxt_int_t nxt_php_init(nxt_task_t *task, nxt_common_app_conf_t *conf);
|
||||
|
||||
static void nxt_php_str_trim_trail(nxt_str_t *str, u_char t);
|
||||
static void nxt_php_str_trim_lead(nxt_str_t *str, u_char t);
|
||||
static nxt_int_t nxt_php_dirname(const nxt_str_t *file, nxt_str_t *dir);
|
||||
nxt_inline u_char *nxt_realpath(const void *c);
|
||||
nxt_inline void nxt_php_vcwd_chdir(nxt_unit_request_info_t *req,
|
||||
const nxt_str_t *dirname);
|
||||
|
||||
static void nxt_php_script_request_handler(nxt_unit_request_info_t *req);
|
||||
static void nxt_php_path_request_handler(nxt_unit_request_info_t *req);
|
||||
static nxt_int_t nxt_php_request_init(nxt_php_run_ctx_t *ctx,
|
||||
nxt_unit_request_t *r);
|
||||
|
||||
static int nxt_php_startup(sapi_module_struct *sapi_module);
|
||||
static nxt_int_t nxt_php_set_target(nxt_task_t *task, nxt_php_target_t *target,
|
||||
nxt_conf_value_t *conf);
|
||||
static void nxt_php_set_options(nxt_task_t *task, nxt_conf_value_t *options,
|
||||
int type);
|
||||
static nxt_int_t nxt_php_alter_option(nxt_str_t *name, nxt_str_t *value,
|
||||
int type);
|
||||
static void nxt_php_disable(nxt_task_t *task, const char *type,
|
||||
nxt_str_t *value, char **ptr, nxt_php_disable_t disable);
|
||||
|
||||
static nxt_int_t nxt_php_dirname(const nxt_str_t *file, nxt_str_t *dir);
|
||||
static void nxt_php_str_trim_trail(nxt_str_t *str, u_char t);
|
||||
static void nxt_php_str_trim_lead(nxt_str_t *str, u_char t);
|
||||
nxt_inline u_char *nxt_realpath(const void *c);
|
||||
|
||||
static void nxt_php_request_handler(nxt_unit_request_info_t *req);
|
||||
static void nxt_php_dynamic_request(nxt_php_run_ctx_t *ctx,
|
||||
nxt_unit_request_t *r);
|
||||
static void nxt_php_execute(nxt_php_run_ctx_t *ctx, nxt_unit_request_t *r);
|
||||
nxt_inline void nxt_php_vcwd_chdir(nxt_unit_request_info_t *req, u_char *dir);
|
||||
|
||||
static int nxt_php_startup(sapi_module_struct *sapi_module);
|
||||
static int nxt_php_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC);
|
||||
static void *nxt_php_hash_str_find_ptr(const HashTable *ht,
|
||||
const nxt_str_t *str);
|
||||
|
@ -210,13 +223,6 @@ static sapi_module_struct nxt_php_sapi_module =
|
|||
};
|
||||
|
||||
|
||||
static nxt_str_t nxt_php_root;
|
||||
static nxt_str_t nxt_php_script_name;
|
||||
static nxt_str_t nxt_php_script_dirname;
|
||||
static nxt_str_t nxt_php_script_filename;
|
||||
static nxt_str_t nxt_php_index = nxt_string("index.php");
|
||||
|
||||
|
||||
static uint32_t compat[] = {
|
||||
NXT_VERNUM, NXT_DEBUG,
|
||||
};
|
||||
|
@ -232,6 +238,9 @@ NXT_EXPORT nxt_app_module_t nxt_app_module = {
|
|||
};
|
||||
|
||||
|
||||
static nxt_php_target_t *nxt_php_targets;
|
||||
static nxt_int_t nxt_php_last_target = -1;
|
||||
|
||||
static nxt_task_t *nxt_php_task;
|
||||
#if defined(ZTS) && PHP_VERSION_ID < 70400
|
||||
static void ***tsrm_ls;
|
||||
|
@ -241,11 +250,11 @@ static void ***tsrm_ls;
|
|||
static nxt_int_t
|
||||
nxt_php_init(nxt_task_t *task, nxt_common_app_conf_t *conf)
|
||||
{
|
||||
u_char *p, *tmp;
|
||||
nxt_str_t ini_path;
|
||||
nxt_str_t *root, *script_filename, *script_dirname, *script_name;
|
||||
nxt_str_t *index;
|
||||
u_char *p;
|
||||
uint32_t next;
|
||||
nxt_str_t ini_path, name;
|
||||
nxt_int_t ret;
|
||||
nxt_uint_t n;
|
||||
nxt_port_t *my_port, *main_port;
|
||||
nxt_runtime_t *rt;
|
||||
nxt_unit_ctx_t *unit_ctx;
|
||||
|
@ -261,105 +270,33 @@ nxt_php_init(nxt_task_t *task, nxt_common_app_conf_t *conf)
|
|||
|
||||
c = &conf->u.php;
|
||||
|
||||
if (c->root == NULL) {
|
||||
nxt_alert(task, "php root is empty");
|
||||
n = (c->targets != NULL) ? nxt_conf_object_members_count(c->targets) : 1;
|
||||
|
||||
nxt_php_targets = nxt_zalloc(sizeof(nxt_php_target_t) * n);
|
||||
if (nxt_slow_path(nxt_php_targets == NULL)) {
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
root = &nxt_php_root;
|
||||
script_filename = &nxt_php_script_filename;
|
||||
script_dirname = &nxt_php_script_dirname;
|
||||
script_name = &nxt_php_script_name;
|
||||
index = &nxt_php_index;
|
||||
if (c->targets != NULL) {
|
||||
next = 0;
|
||||
|
||||
root->start = nxt_realpath(c->root);
|
||||
if (nxt_slow_path(root->start == NULL)) {
|
||||
nxt_alert(task, "root realpath(%s) failed %E", c->root, nxt_errno);
|
||||
return NXT_ERROR;
|
||||
}
|
||||
for (n = 0; /* void */; n++) {
|
||||
value = nxt_conf_next_object_member(c->targets, &name, &next);
|
||||
if (value == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
root->length = nxt_strlen(root->start);
|
||||
|
||||
nxt_php_str_trim_trail(root, '/');
|
||||
|
||||
if (c->script.length > 0) {
|
||||
nxt_php_str_trim_lead(&c->script, '/');
|
||||
|
||||
tmp = nxt_malloc(root->length + 1 + c->script.length + 1);
|
||||
if (nxt_slow_path(tmp == NULL)) {
|
||||
return NXT_ERROR;
|
||||
ret = nxt_php_set_target(task, &nxt_php_targets[n], value);
|
||||
if (nxt_slow_path(ret != NXT_OK)) {
|
||||
return NXT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
p = tmp;
|
||||
|
||||
p = nxt_cpymem(p, root->start, root->length);
|
||||
*p++ = '/';
|
||||
|
||||
p = nxt_cpymem(p, c->script.start, c->script.length);
|
||||
*p = '\0';
|
||||
|
||||
script_filename->start = nxt_realpath(tmp);
|
||||
if (nxt_slow_path(script_filename->start == NULL)) {
|
||||
nxt_alert(task, "script realpath(%s) failed %E", tmp, nxt_errno);
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
nxt_free(tmp);
|
||||
|
||||
script_filename->length = nxt_strlen(script_filename->start);
|
||||
|
||||
if (!nxt_str_start(script_filename, root->start, root->length)) {
|
||||
nxt_alert(task, "script is not under php root");
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
ret = nxt_php_dirname(script_filename, script_dirname);
|
||||
} else {
|
||||
ret = nxt_php_set_target(task, &nxt_php_targets[0], conf->self);
|
||||
if (nxt_slow_path(ret != NXT_OK)) {
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
script_name->length = c->script.length + 1;
|
||||
script_name->start = nxt_malloc(script_name->length);
|
||||
if (nxt_slow_path(script_name->start == NULL)) {
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
script_name->start[0] = '/';
|
||||
nxt_memcpy(script_name->start + 1, c->script.start, c->script.length);
|
||||
|
||||
nxt_log_error(NXT_LOG_INFO, task->log,
|
||||
"(ABS_MODE) php script \"%V\" root: \"%V\"",
|
||||
script_name, root);
|
||||
|
||||
} else {
|
||||
nxt_log_error(NXT_LOG_INFO, task->log,
|
||||
"(non ABS_MODE) php root: \"%V\"", root);
|
||||
}
|
||||
|
||||
if (c->index.length > 0) {
|
||||
index->length = c->index.length;
|
||||
index->start = nxt_malloc(index->length);
|
||||
if (nxt_slow_path(index->start == NULL)) {
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
nxt_memcpy(index->start, c->index.start, c->index.length);
|
||||
}
|
||||
|
||||
nxt_memzero(&php_init, sizeof(nxt_unit_init_t));
|
||||
|
||||
if (nxt_php_script_filename.start != NULL) {
|
||||
if (nxt_slow_path(chdir((char *) script_dirname->start) != 0)) {
|
||||
nxt_alert(task, "failed to chdir(%V) %E", script_dirname,
|
||||
nxt_errno);
|
||||
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
php_init.callbacks.request_handler = nxt_php_script_request_handler;
|
||||
|
||||
} else {
|
||||
php_init.callbacks.request_handler = nxt_php_path_request_handler;
|
||||
}
|
||||
|
||||
#ifdef ZTS
|
||||
|
@ -430,6 +367,10 @@ nxt_php_init(nxt_task_t *task, nxt_common_app_conf_t *conf)
|
|||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
nxt_memzero(&php_init, sizeof(nxt_unit_init_t));
|
||||
|
||||
php_init.callbacks.request_handler = nxt_php_request_handler;
|
||||
|
||||
php_init.ready_port.id.pid = main_port->pid;
|
||||
php_init.ready_port.id.id = main_port->id;
|
||||
php_init.ready_port.out_fd = main_port->pair[1];
|
||||
|
@ -462,6 +403,125 @@ nxt_php_init(nxt_task_t *task, nxt_common_app_conf_t *conf)
|
|||
}
|
||||
|
||||
|
||||
static nxt_int_t
|
||||
nxt_php_set_target(nxt_task_t *task, nxt_php_target_t *target,
|
||||
nxt_conf_value_t *conf)
|
||||
{
|
||||
u_char *tmp, *p;
|
||||
nxt_str_t str;
|
||||
nxt_int_t ret;
|
||||
nxt_conf_value_t *value;
|
||||
|
||||
static nxt_str_t root_str = nxt_string("root");
|
||||
static nxt_str_t script_str = nxt_string("script");
|
||||
static nxt_str_t index_str = nxt_string("index");
|
||||
|
||||
value = nxt_conf_get_object_member(conf, &root_str, NULL);
|
||||
|
||||
if (value == NULL) {
|
||||
nxt_alert(task, "no php root specified");
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
nxt_conf_get_string(value, &str);
|
||||
|
||||
tmp = nxt_malloc(str.length + 1);
|
||||
if (nxt_slow_path(tmp == NULL)) {
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
p = tmp;
|
||||
|
||||
p = nxt_cpymem(p, str.start, str.length);
|
||||
*p = '\0';
|
||||
|
||||
p = nxt_realpath(tmp);
|
||||
if (nxt_slow_path(p == NULL)) {
|
||||
nxt_alert(task, "root realpath(%s) failed %E", tmp, nxt_errno);
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
nxt_free(tmp);
|
||||
|
||||
target->root.length = nxt_strlen(p);
|
||||
target->root.start = p;
|
||||
|
||||
nxt_php_str_trim_trail(&target->root, '/');
|
||||
|
||||
value = nxt_conf_get_object_member(conf, &script_str, NULL);
|
||||
|
||||
if (value != NULL) {
|
||||
nxt_conf_get_string(value, &str);
|
||||
|
||||
nxt_php_str_trim_lead(&str, '/');
|
||||
|
||||
tmp = nxt_malloc(target->root.length + 1 + str.length + 1);
|
||||
if (nxt_slow_path(tmp == NULL)) {
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
p = tmp;
|
||||
|
||||
p = nxt_cpymem(p, target->root.start, target->root.length);
|
||||
*p++ = '/';
|
||||
|
||||
p = nxt_cpymem(p, str.start, str.length);
|
||||
*p = '\0';
|
||||
|
||||
p = nxt_realpath(tmp);
|
||||
if (nxt_slow_path(p == NULL)) {
|
||||
nxt_alert(task, "script realpath(%s) failed %E", tmp, nxt_errno);
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
nxt_free(tmp);
|
||||
|
||||
target->script_filename.length = nxt_strlen(p);
|
||||
target->script_filename.start = p;
|
||||
|
||||
if (!nxt_str_start(&target->script_filename,
|
||||
target->root.start, target->root.length))
|
||||
{
|
||||
nxt_alert(task, "script is not under php root");
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
ret = nxt_php_dirname(&target->script_filename,
|
||||
&target->script_dirname);
|
||||
if (nxt_slow_path(ret != NXT_OK)) {
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
target->script_name.length = target->script_filename.length
|
||||
- target->root.length;
|
||||
target->script_name.start = target->script_filename.start
|
||||
+ target->root.length;
|
||||
|
||||
} else {
|
||||
value = nxt_conf_get_object_member(conf, &index_str, NULL);
|
||||
|
||||
if (value != NULL) {
|
||||
nxt_conf_get_string(value, &str);
|
||||
|
||||
tmp = nxt_malloc(str.length);
|
||||
if (nxt_slow_path(tmp == NULL)) {
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
nxt_memcpy(tmp, str.start, str.length);
|
||||
|
||||
target->index.length = str.length;
|
||||
target->index.start = tmp;
|
||||
|
||||
} else {
|
||||
nxt_str_set(&target->index, "index.php");
|
||||
}
|
||||
}
|
||||
|
||||
return NXT_OK;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
nxt_php_set_options(nxt_task_t *task, nxt_conf_value_t *options, int type)
|
||||
{
|
||||
|
@ -686,56 +746,44 @@ nxt_realpath(const void *c)
|
|||
|
||||
|
||||
static void
|
||||
nxt_php_script_request_handler(nxt_unit_request_info_t *req)
|
||||
nxt_php_request_handler(nxt_unit_request_info_t *req)
|
||||
{
|
||||
zend_file_handle file_handle;
|
||||
nxt_php_run_ctx_t ctx;
|
||||
nxt_php_target_t *target;
|
||||
nxt_php_run_ctx_t ctx;
|
||||
nxt_unit_request_t *r;
|
||||
|
||||
r = req->request;
|
||||
target = &nxt_php_targets[r->app_target];
|
||||
|
||||
nxt_memzero(&ctx, sizeof(ctx));
|
||||
|
||||
ctx.req = req;
|
||||
ctx.script_filename = nxt_php_script_filename;
|
||||
ctx.script_dirname = nxt_php_script_dirname;
|
||||
ctx.script_name = nxt_php_script_name;
|
||||
ctx.root = &target->root;
|
||||
ctx.index = &target->index;
|
||||
|
||||
nxt_memzero(&file_handle, sizeof(file_handle));
|
||||
|
||||
file_handle.type = ZEND_HANDLE_FILENAME;
|
||||
file_handle.filename = (char *) ctx.script_filename.start;
|
||||
|
||||
if (nxt_slow_path(nxt_php_request_init(&ctx, req->request) != NXT_OK)) {
|
||||
nxt_unit_request_done(req, NXT_UNIT_ERROR);
|
||||
if (target->script_filename.length == 0) {
|
||||
nxt_php_dynamic_request(&ctx, r);
|
||||
return;
|
||||
}
|
||||
|
||||
php_execute_script(&file_handle TSRMLS_CC);
|
||||
ctx.script_filename = target->script_filename;
|
||||
ctx.script_dirname = target->script_dirname;
|
||||
ctx.script_name = target->script_name;
|
||||
|
||||
if (ctx.chdir) {
|
||||
nxt_php_vcwd_chdir(ctx.req, &nxt_php_script_dirname);
|
||||
}
|
||||
ctx.chdir = (r->app_target != nxt_php_last_target);
|
||||
|
||||
php_request_shutdown(NULL);
|
||||
nxt_php_execute(&ctx, r);
|
||||
|
||||
nxt_unit_request_done(req, NXT_UNIT_OK);
|
||||
nxt_php_last_target = ctx.chdir ? -1 : r->app_target;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
nxt_php_path_request_handler(nxt_unit_request_info_t *req)
|
||||
nxt_php_dynamic_request(nxt_php_run_ctx_t *ctx, nxt_unit_request_t *r)
|
||||
{
|
||||
u_char *p;
|
||||
nxt_str_t path, script_name;
|
||||
nxt_int_t ret;
|
||||
zend_file_handle file_handle;
|
||||
nxt_php_run_ctx_t run_ctx, *ctx;
|
||||
nxt_unit_request_t *r;
|
||||
|
||||
nxt_memzero(&run_ctx, sizeof(run_ctx));
|
||||
|
||||
ctx = &run_ctx;
|
||||
ctx->req = req;
|
||||
|
||||
r = req->request;
|
||||
u_char *p;
|
||||
nxt_str_t path, script_name;
|
||||
nxt_int_t ret;
|
||||
|
||||
path.length = r->path_length;
|
||||
path.start = nxt_unit_sptr_get(&r->path);
|
||||
|
@ -750,26 +798,26 @@ nxt_php_path_request_handler(nxt_unit_request_info_t *req)
|
|||
ctx->path_info.length = r->path_length - path.length;
|
||||
|
||||
} else if (path.start[path.length - 1] == '/') {
|
||||
script_name = nxt_php_index;
|
||||
script_name = *ctx->index;
|
||||
|
||||
} else {
|
||||
if (nxt_slow_path(path.length < 4
|
||||
|| nxt_memcmp(path.start + (path.length - 4),
|
||||
".php", 4)))
|
||||
{
|
||||
nxt_unit_request_done(req, NXT_UNIT_ERROR);
|
||||
nxt_unit_request_done(ctx->req, NXT_UNIT_ERROR);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ctx->script_filename.length = nxt_php_root.length
|
||||
ctx->script_filename.length = ctx->root->length
|
||||
+ path.length
|
||||
+ script_name.length;
|
||||
|
||||
p = nxt_malloc(ctx->script_filename.length + 1);
|
||||
if (nxt_slow_path(p == NULL)) {
|
||||
nxt_unit_request_done(req, NXT_UNIT_ERROR);
|
||||
nxt_unit_request_done(ctx->req, NXT_UNIT_ERROR);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -777,9 +825,9 @@ nxt_php_path_request_handler(nxt_unit_request_info_t *req)
|
|||
ctx->script_filename.start = p;
|
||||
|
||||
ctx->script_name.length = path.length + script_name.length;
|
||||
ctx->script_name.start = p + nxt_php_root.length;
|
||||
ctx->script_name.start = p + ctx->root->length;
|
||||
|
||||
p = nxt_cpymem(p, nxt_php_root.start, nxt_php_root.length);
|
||||
p = nxt_cpymem(p, ctx->root->start, ctx->root->length);
|
||||
p = nxt_cpymem(p, path.start, path.length);
|
||||
|
||||
if (script_name.length > 0) {
|
||||
|
@ -788,50 +836,33 @@ nxt_php_path_request_handler(nxt_unit_request_info_t *req)
|
|||
|
||||
*p = '\0';
|
||||
|
||||
nxt_memzero(&file_handle, sizeof(file_handle));
|
||||
|
||||
file_handle.type = ZEND_HANDLE_FILENAME;
|
||||
file_handle.filename = (char *) ctx->script_filename.start;
|
||||
ctx->chdir = 1;
|
||||
|
||||
ret = nxt_php_dirname(&ctx->script_filename, &ctx->script_dirname);
|
||||
if (nxt_slow_path(ret != NXT_OK)) {
|
||||
nxt_unit_request_done(req, NXT_UNIT_ERROR);
|
||||
nxt_unit_request_done(ctx->req, NXT_UNIT_ERROR);
|
||||
nxt_free(ctx->script_filename.start);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (nxt_slow_path(nxt_php_request_init(ctx, req->request) != NXT_OK)) {
|
||||
nxt_unit_request_done(req, NXT_UNIT_ERROR);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
nxt_php_vcwd_chdir(ctx->req, &ctx->script_dirname);
|
||||
|
||||
php_execute_script(&file_handle TSRMLS_CC);
|
||||
|
||||
php_request_shutdown(NULL);
|
||||
|
||||
nxt_unit_request_done(req, NXT_UNIT_OK);
|
||||
|
||||
cleanup:
|
||||
nxt_php_execute(ctx, r);
|
||||
|
||||
nxt_free(ctx->script_filename.start);
|
||||
nxt_free(ctx->script_dirname.start);
|
||||
|
||||
nxt_php_last_target = -1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
nxt_php_startup(sapi_module_struct *sapi_module)
|
||||
{
|
||||
return php_module_startup(sapi_module, &nxt_php_unit_module, 1);
|
||||
}
|
||||
|
||||
|
||||
static nxt_int_t
|
||||
nxt_php_request_init(nxt_php_run_ctx_t *ctx, nxt_unit_request_t *r)
|
||||
static void
|
||||
nxt_php_execute(nxt_php_run_ctx_t *ctx, nxt_unit_request_t *r)
|
||||
{
|
||||
nxt_unit_field_t *f;
|
||||
zend_file_handle file_handle;
|
||||
|
||||
nxt_unit_req_debug(ctx->req, "PHP execute script %s",
|
||||
ctx->script_filename.start);
|
||||
|
||||
SG(server_context) = ctx;
|
||||
SG(options) |= SAPI_OPTION_NO_CHDIR;
|
||||
|
@ -860,20 +891,6 @@ nxt_php_request_init(nxt_php_run_ctx_t *ctx, nxt_unit_request_t *r)
|
|||
|
||||
SG(request_info).path_translated = NULL;
|
||||
|
||||
nxt_unit_req_debug(ctx->req, "handle.filename = '%s'",
|
||||
ctx->script_filename.start);
|
||||
|
||||
if (nxt_php_script_filename.start != NULL) {
|
||||
nxt_unit_req_debug(ctx->req, "run script %.*s in absolute mode",
|
||||
(int) nxt_php_script_filename.length,
|
||||
(char *) nxt_php_script_filename.start);
|
||||
|
||||
} else {
|
||||
nxt_unit_req_debug(ctx->req, "run script %.*s",
|
||||
(int) ctx->script_filename.length,
|
||||
(char *) ctx->script_filename.start);
|
||||
}
|
||||
|
||||
#ifdef NXT_PHP7
|
||||
if (nxt_slow_path(php_request_startup() == FAILURE)) {
|
||||
#else
|
||||
|
@ -881,23 +898,45 @@ nxt_php_request_init(nxt_php_run_ctx_t *ctx, nxt_unit_request_t *r)
|
|||
#endif
|
||||
nxt_unit_req_debug(ctx->req, "php_request_startup() failed");
|
||||
|
||||
return NXT_ERROR;
|
||||
nxt_unit_request_done(ctx->req, NXT_UNIT_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
return NXT_OK;
|
||||
if (ctx->chdir) {
|
||||
ctx->chdir = 0;
|
||||
nxt_php_vcwd_chdir(ctx->req, ctx->script_dirname.start);
|
||||
}
|
||||
|
||||
nxt_memzero(&file_handle, sizeof(file_handle));
|
||||
|
||||
file_handle.type = ZEND_HANDLE_FILENAME;
|
||||
file_handle.filename = (char *) ctx->script_filename.start;
|
||||
|
||||
php_execute_script(&file_handle TSRMLS_CC);
|
||||
|
||||
php_request_shutdown(NULL);
|
||||
|
||||
nxt_unit_request_done(ctx->req, NXT_UNIT_OK);
|
||||
}
|
||||
|
||||
|
||||
nxt_inline void
|
||||
nxt_php_vcwd_chdir(nxt_unit_request_info_t *req, const nxt_str_t *dir)
|
||||
nxt_php_vcwd_chdir(nxt_unit_request_info_t *req, u_char *dir)
|
||||
{
|
||||
if (nxt_slow_path(VCWD_CHDIR((char *) dir->start) != 0)) {
|
||||
if (nxt_slow_path(VCWD_CHDIR((char *) dir) != 0)) {
|
||||
nxt_unit_req_alert(req, "VCWD_CHDIR(%s) failed (%d: %s)",
|
||||
dir->start, errno, strerror(errno));
|
||||
dir, errno, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
nxt_php_startup(sapi_module_struct *sapi_module)
|
||||
{
|
||||
return php_module_startup(sapi_module, &nxt_php_unit_module, 1);
|
||||
}
|
||||
|
||||
|
||||
#ifdef NXT_PHP7
|
||||
static size_t
|
||||
nxt_php_unbuffered_write(const char *str, size_t str_length TSRMLS_DC)
|
||||
|
@ -1061,18 +1100,15 @@ nxt_php_register_variables(zval *track_vars_array TSRMLS_DC)
|
|||
* available.
|
||||
*/
|
||||
|
||||
if (nxt_php_script_name.start != NULL) {
|
||||
/* ABS_MODE */
|
||||
nxt_php_set_str(req, "PHP_SELF", &nxt_php_script_name,
|
||||
if (ctx->path_info.length != 0) {
|
||||
nxt_php_set_sptr(req, "PHP_SELF", &r->path, r->path_length,
|
||||
track_vars_array TSRMLS_CC);
|
||||
|
||||
nxt_php_set_str(req, "PATH_INFO", &ctx->path_info,
|
||||
track_vars_array TSRMLS_CC);
|
||||
|
||||
} else {
|
||||
nxt_php_set_sptr(req, "PHP_SELF", &r->path, r->path_length,
|
||||
track_vars_array TSRMLS_CC);
|
||||
}
|
||||
|
||||
if (ctx->path_info.length != 0) {
|
||||
nxt_php_set_str(req, "PATH_INFO", &ctx->path_info,
|
||||
nxt_php_set_str(req, "PHP_SELF", &ctx->script_name,
|
||||
track_vars_array TSRMLS_CC);
|
||||
}
|
||||
|
||||
|
@ -1100,7 +1136,7 @@ nxt_php_register_variables(zval *track_vars_array TSRMLS_DC)
|
|||
* as defined in the server's configuration file.
|
||||
*/
|
||||
|
||||
nxt_php_set_str(req, "DOCUMENT_ROOT", &nxt_php_root,
|
||||
nxt_php_set_str(req, "DOCUMENT_ROOT", ctx->root,
|
||||
track_vars_array TSRMLS_CC);
|
||||
|
||||
nxt_php_set_sptr(req, "REQUEST_METHOD", &r->method, r->method_length,
|
||||
|
|
|
@ -27,6 +27,7 @@ typedef struct {
|
|||
uint32_t requests;
|
||||
nxt_conf_value_t *limits_value;
|
||||
nxt_conf_value_t *processes_value;
|
||||
nxt_conf_value_t *targets_value;
|
||||
} nxt_router_app_conf_t;
|
||||
|
||||
|
||||
|
@ -1272,6 +1273,12 @@ static nxt_conf_map_t nxt_router_app_conf[] = {
|
|||
NXT_CONF_MAP_PTR,
|
||||
offsetof(nxt_router_app_conf_t, processes_value),
|
||||
},
|
||||
|
||||
{
|
||||
nxt_string("targets"),
|
||||
NXT_CONF_MAP_PTR,
|
||||
offsetof(nxt_router_app_conf_t, targets_value),
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
@ -1423,12 +1430,13 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
|||
{
|
||||
u_char *p;
|
||||
size_t size;
|
||||
nxt_mp_t *mp;
|
||||
uint32_t next;
|
||||
nxt_mp_t *mp, *app_mp;
|
||||
uint32_t next, next_target;
|
||||
nxt_int_t ret;
|
||||
nxt_str_t name, path;
|
||||
nxt_str_t name, path, target;
|
||||
nxt_app_t *app, *prev;
|
||||
nxt_str_t *t;
|
||||
nxt_str_t *t, *s, *targets;
|
||||
nxt_uint_t n, i;
|
||||
nxt_router_t *router;
|
||||
nxt_app_joint_t *app_joint;
|
||||
nxt_conf_value_t *conf, *http, *value, *websocket;
|
||||
|
@ -1501,13 +1509,20 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
|||
|
||||
size = nxt_conf_json_length(application, NULL);
|
||||
|
||||
app = nxt_malloc(sizeof(nxt_app_t) + name.length + size);
|
||||
if (app == NULL) {
|
||||
app_mp = nxt_mp_create(4096, 128, 1024, 64);
|
||||
if (nxt_slow_path(app_mp == NULL)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
app = nxt_mp_get(app_mp, sizeof(nxt_app_t) + name.length + size);
|
||||
if (app == NULL) {
|
||||
goto app_fail;
|
||||
}
|
||||
|
||||
nxt_memzero(app, sizeof(nxt_app_t));
|
||||
|
||||
app->mem_pool = app_mp;
|
||||
|
||||
app->name.start = nxt_pointer_to(app, sizeof(nxt_app_t));
|
||||
app->conf.start = nxt_pointer_to(app, sizeof(nxt_app_t)
|
||||
+ name.length);
|
||||
|
@ -1522,7 +1537,7 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
|||
prev = nxt_router_app_find(&router->apps, &name);
|
||||
|
||||
if (prev != NULL && nxt_strstr_eq(&app->conf, &prev->conf)) {
|
||||
nxt_free(app);
|
||||
nxt_mp_destroy(app_mp);
|
||||
|
||||
nxt_queue_remove(&prev->link);
|
||||
nxt_queue_insert_tail(&tmcf->previous, &prev->link);
|
||||
|
@ -1538,6 +1553,7 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
|||
apcf.requests = 0;
|
||||
apcf.limits_value = NULL;
|
||||
apcf.processes_value = NULL;
|
||||
apcf.targets_value = NULL;
|
||||
|
||||
app_joint = nxt_malloc(sizeof(nxt_app_joint_t));
|
||||
if (nxt_slow_path(app_joint == NULL)) {
|
||||
|
@ -1587,6 +1603,30 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
|||
apcf.spare_processes = apcf.processes;
|
||||
}
|
||||
|
||||
if (apcf.targets_value != NULL) {
|
||||
n = nxt_conf_object_members_count(apcf.targets_value);
|
||||
|
||||
targets = nxt_mp_get(app_mp, sizeof(nxt_str_t) * n);
|
||||
if (nxt_slow_path(targets == NULL)) {
|
||||
goto app_fail;
|
||||
}
|
||||
|
||||
next_target = 0;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
value = nxt_conf_next_object_member(apcf.targets_value,
|
||||
&target, &next_target);
|
||||
|
||||
s = nxt_str_dup(app_mp, &targets[i], &target);
|
||||
if (nxt_slow_path(s == NULL)) {
|
||||
goto app_fail;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
targets = NULL;
|
||||
}
|
||||
|
||||
nxt_debug(task, "application type: %V", &apcf.type);
|
||||
nxt_debug(task, "application processes: %D", apcf.processes);
|
||||
nxt_debug(task, "application request timeout: %M", apcf.timeout);
|
||||
|
@ -1628,6 +1668,8 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
|||
app->max_pending_responses = 2;
|
||||
app->max_requests = apcf.requests;
|
||||
|
||||
app->targets = targets;
|
||||
|
||||
engine = task->thread->engine;
|
||||
|
||||
app->engine = engine;
|
||||
|
@ -1839,7 +1881,7 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
|||
|
||||
app_fail:
|
||||
|
||||
nxt_free(app);
|
||||
nxt_mp_destroy(app_mp);
|
||||
|
||||
fail:
|
||||
|
||||
|
@ -1847,7 +1889,7 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
|||
|
||||
nxt_queue_remove(&app->link);
|
||||
nxt_thread_mutex_destroy(&app->mutex);
|
||||
nxt_free(app);
|
||||
nxt_mp_destroy(app->mem_pool);
|
||||
|
||||
} nxt_queue_loop;
|
||||
|
||||
|
@ -4538,7 +4580,7 @@ nxt_router_free_app(nxt_task_t *task, void *obj, void *data)
|
|||
nxt_assert(nxt_queue_is_empty(&app->idle_ports));
|
||||
|
||||
nxt_thread_mutex_destroy(&app->mutex);
|
||||
nxt_free(app);
|
||||
nxt_mp_destroy(app->mem_pool);
|
||||
|
||||
app_joint->app = NULL;
|
||||
|
||||
|
@ -4992,6 +5034,8 @@ nxt_router_prepare_msg(nxt_task_t *task, nxt_http_request_t *r,
|
|||
req = (nxt_unit_request_t *) out->mem.free;
|
||||
out->mem.free += req_size;
|
||||
|
||||
req->app_target = r->app_target;
|
||||
|
||||
req->content_length = content_length;
|
||||
|
||||
p = (u_char *) (req->fields + fields_count);
|
||||
|
|
|
@ -133,8 +133,11 @@ struct nxt_app_s {
|
|||
nxt_nsec_t res_timeout;
|
||||
nxt_msec_t idle_timeout;
|
||||
|
||||
nxt_str_t *targets;
|
||||
|
||||
nxt_app_type_t type:8;
|
||||
|
||||
nxt_mp_t *mem_pool;
|
||||
nxt_queue_link_t link;
|
||||
|
||||
nxt_str_t conf;
|
||||
|
|
|
@ -21,6 +21,7 @@ struct nxt_unit_request_s {
|
|||
uint8_t local_length;
|
||||
uint8_t tls;
|
||||
uint8_t websocket_handshake;
|
||||
uint8_t app_target;
|
||||
uint32_t server_name_length;
|
||||
uint32_t target_length;
|
||||
uint32_t path_length;
|
||||
|
|
Loading…
Reference in a new issue