PHP: added PATH_INFO support.
This commit is contained in:
@@ -143,14 +143,16 @@ static sapi_module_struct nxt_php_sapi_module =
|
|||||||
|
|
||||||
struct nxt_php_run_ctx_s {
|
struct nxt_php_run_ctx_s {
|
||||||
char *cookie;
|
char *cookie;
|
||||||
nxt_str_t script;
|
nxt_str_t path_info;
|
||||||
|
nxt_str_t script_name;
|
||||||
|
nxt_str_t script_filename;
|
||||||
nxt_unit_request_info_t *req;
|
nxt_unit_request_info_t *req;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static nxt_str_t nxt_php_path;
|
|
||||||
static nxt_str_t nxt_php_root;
|
static nxt_str_t nxt_php_root;
|
||||||
static nxt_str_t nxt_php_script;
|
static nxt_str_t nxt_php_script_name;
|
||||||
|
static nxt_str_t nxt_php_script_filename;
|
||||||
static nxt_str_t nxt_php_index = nxt_string("index.php");
|
static nxt_str_t nxt_php_index = nxt_string("index.php");
|
||||||
|
|
||||||
|
|
||||||
@@ -179,8 +181,8 @@ static nxt_int_t
|
|||||||
nxt_php_init(nxt_task_t *task, nxt_common_app_conf_t *conf)
|
nxt_php_init(nxt_task_t *task, nxt_common_app_conf_t *conf)
|
||||||
{
|
{
|
||||||
u_char *p;
|
u_char *p;
|
||||||
nxt_str_t rpath, ini_path;
|
nxt_str_t ini_path;
|
||||||
nxt_str_t *root, *path, *script, *index;
|
nxt_str_t *root, *script_filename, *script_name, *index;
|
||||||
nxt_port_t *my_port, *main_port;
|
nxt_port_t *my_port, *main_port;
|
||||||
nxt_runtime_t *rt;
|
nxt_runtime_t *rt;
|
||||||
nxt_unit_ctx_t *unit_ctx;
|
nxt_unit_ctx_t *unit_ctx;
|
||||||
@@ -202,8 +204,8 @@ nxt_php_init(nxt_task_t *task, nxt_common_app_conf_t *conf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
root = &nxt_php_root;
|
root = &nxt_php_root;
|
||||||
path = &nxt_php_path;
|
script_filename = &nxt_php_script_filename;
|
||||||
script = &nxt_php_script;
|
script_name = &nxt_php_script_name;
|
||||||
index = &nxt_php_index;
|
index = &nxt_php_index;
|
||||||
|
|
||||||
root->start = nxt_realpath(c->root);
|
root->start = nxt_realpath(c->root);
|
||||||
@@ -219,47 +221,44 @@ nxt_php_init(nxt_task_t *task, nxt_common_app_conf_t *conf)
|
|||||||
if (c->script.length > 0) {
|
if (c->script.length > 0) {
|
||||||
nxt_php_str_trim_lead(&c->script, '/');
|
nxt_php_str_trim_lead(&c->script, '/');
|
||||||
|
|
||||||
path->length = root->length + 1 + c->script.length;
|
p = nxt_malloc(root->length + 1 + c->script.length + 1);
|
||||||
path->start = nxt_malloc(path->length + 1);
|
if (nxt_slow_path(p == NULL)) {
|
||||||
if (nxt_slow_path(path->start == NULL)) {
|
|
||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = nxt_cpymem(path->start, root->start, root->length);
|
p = nxt_cpymem(p, root->start, root->length);
|
||||||
*p++ = '/';
|
*p++ = '/';
|
||||||
|
|
||||||
p = nxt_cpymem(p, c->script.start, c->script.length);
|
p = nxt_cpymem(p, c->script.start, c->script.length);
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
|
||||||
rpath.start = nxt_realpath(path->start);
|
script_filename->start = nxt_realpath(p);
|
||||||
if (nxt_slow_path(rpath.start == NULL)) {
|
if (nxt_slow_path(script_filename->start == NULL)) {
|
||||||
nxt_alert(task, "script realpath(%V) failed %E", path, nxt_errno);
|
nxt_alert(task, "script realpath(%s) failed %E", p, nxt_errno);
|
||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
rpath.length = nxt_strlen(rpath.start);
|
nxt_free(p);
|
||||||
|
|
||||||
if (!nxt_str_start(&rpath, root->start, root->length)) {
|
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");
|
nxt_alert(task, "script is not under php root");
|
||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
nxt_free(path->start);
|
script_name->length = c->script.length + 1;
|
||||||
|
script_name->start = nxt_malloc(script_name->length);
|
||||||
*path = rpath;
|
if (nxt_slow_path(script_name->start == NULL)) {
|
||||||
|
|
||||||
script->length = c->script.length + 1;
|
|
||||||
script->start = nxt_malloc(script->length);
|
|
||||||
if (nxt_slow_path(script->start == NULL)) {
|
|
||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
script->start[0] = '/';
|
script_name->start[0] = '/';
|
||||||
nxt_memcpy(script->start + 1, c->script.start, c->script.length);
|
nxt_memcpy(script_name->start + 1, c->script.start, c->script.length);
|
||||||
|
|
||||||
nxt_log_error(NXT_LOG_INFO, task->log,
|
nxt_log_error(NXT_LOG_INFO, task->log,
|
||||||
"(ABS_MODE) php script \"%V\" root: \"%V\"",
|
"(ABS_MODE) php script \"%V\" root: \"%V\"",
|
||||||
script, root);
|
script_name, root);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
nxt_log_error(NXT_LOG_INFO, task->log,
|
nxt_log_error(NXT_LOG_INFO, task->log,
|
||||||
@@ -596,7 +595,15 @@ nxt_php_request_handler(nxt_unit_request_info_t *req)
|
|||||||
path.length = r->path_length;
|
path.length = r->path_length;
|
||||||
path.start = nxt_unit_sptr_get(&r->path);
|
path.start = nxt_unit_sptr_get(&r->path);
|
||||||
|
|
||||||
if (nxt_php_path.start == NULL) {
|
if (nxt_php_script_filename.start == NULL) {
|
||||||
|
ctx->path_info.start = (u_char *) strstr((char *) path.start, ".php/");
|
||||||
|
if (ctx->path_info.start != NULL) {
|
||||||
|
ctx->path_info.start += 4;
|
||||||
|
path.length = ctx->path_info.start - path.start;
|
||||||
|
|
||||||
|
ctx->path_info.length = r->path_length - path.length;
|
||||||
|
}
|
||||||
|
|
||||||
if (path.start[path.length - 1] == '/') {
|
if (path.start[path.length - 1] == '/') {
|
||||||
script_name = nxt_php_index;
|
script_name = nxt_php_index;
|
||||||
|
|
||||||
@@ -605,15 +612,20 @@ nxt_php_request_handler(nxt_unit_request_info_t *req)
|
|||||||
script_name.start = NULL;
|
script_name.start = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->script.length = nxt_php_root.length + path.length
|
ctx->script_filename.length = nxt_php_root.length + path.length
|
||||||
+ script_name.length;
|
+ script_name.length;
|
||||||
p = ctx->script.start = nxt_malloc(ctx->script.length + 1);
|
p = nxt_malloc(ctx->script_filename.length + 1);
|
||||||
if (nxt_slow_path(p == NULL)) {
|
if (nxt_slow_path(p == NULL)) {
|
||||||
nxt_unit_request_done(req, NXT_UNIT_ERROR);
|
nxt_unit_request_done(req, NXT_UNIT_ERROR);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctx->script_filename.start = p;
|
||||||
|
|
||||||
|
ctx->script_name.length = path.length + script_name.length;
|
||||||
|
ctx->script_name.start = p + nxt_php_root.length;
|
||||||
|
|
||||||
p = nxt_cpymem(p, nxt_php_root.start, nxt_php_root.length);
|
p = nxt_cpymem(p, nxt_php_root.start, nxt_php_root.length);
|
||||||
p = nxt_cpymem(p, path.start, path.length);
|
p = nxt_cpymem(p, path.start, path.length);
|
||||||
|
|
||||||
@@ -624,7 +636,8 @@ nxt_php_request_handler(nxt_unit_request_info_t *req)
|
|||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ctx->script = nxt_php_path;
|
ctx->script_filename = nxt_php_script_filename;
|
||||||
|
ctx->script_name = nxt_php_script_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
SG(server_context) = ctx;
|
SG(server_context) = ctx;
|
||||||
@@ -654,20 +667,22 @@ nxt_php_request_handler(nxt_unit_request_info_t *req)
|
|||||||
SG(request_info).path_translated = NULL;
|
SG(request_info).path_translated = NULL;
|
||||||
|
|
||||||
file_handle.type = ZEND_HANDLE_FILENAME;
|
file_handle.type = ZEND_HANDLE_FILENAME;
|
||||||
file_handle.filename = (char *) ctx->script.start;
|
file_handle.filename = (char *) ctx->script_filename.start;
|
||||||
file_handle.free_filename = 0;
|
file_handle.free_filename = 0;
|
||||||
file_handle.opened_path = NULL;
|
file_handle.opened_path = NULL;
|
||||||
|
|
||||||
nxt_unit_req_debug(req, "handle.filename = '%s'", ctx->script.start);
|
nxt_unit_req_debug(req, "handle.filename = '%s'",
|
||||||
|
ctx->script_filename.start);
|
||||||
|
|
||||||
if (nxt_php_path.start != NULL) {
|
if (nxt_php_script_filename.start != NULL) {
|
||||||
nxt_unit_req_debug(req, "run script %.*s in absolute mode",
|
nxt_unit_req_debug(req, "run script %.*s in absolute mode",
|
||||||
(int) nxt_php_path.length,
|
(int) nxt_php_script_filename.length,
|
||||||
(char *) nxt_php_path.start);
|
(char *) nxt_php_script_filename.start);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
nxt_unit_req_debug(req, "run script %.*s", (int) ctx->script.length,
|
nxt_unit_req_debug(req, "run script %.*s",
|
||||||
(char *) ctx->script.start);
|
(int) ctx->script_filename.length,
|
||||||
|
(char *) ctx->script_filename.start);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (NXT_PHP7)
|
#if (NXT_PHP7)
|
||||||
@@ -690,8 +705,8 @@ fail:
|
|||||||
|
|
||||||
nxt_unit_request_done(req, rc);
|
nxt_unit_request_done(req, rc);
|
||||||
|
|
||||||
if (ctx->script.start != nxt_php_path.start) {
|
if (ctx->script_filename.start != nxt_php_script_filename.start) {
|
||||||
nxt_free(ctx->script.start);
|
nxt_free(ctx->script_filename.start);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -855,49 +870,56 @@ nxt_php_register_variables(zval *track_vars_array TSRMLS_DC)
|
|||||||
nxt_php_set_sptr(req, "SERVER_PROTOCOL", &r->version, r->version_length,
|
nxt_php_set_sptr(req, "SERVER_PROTOCOL", &r->version, r->version_length,
|
||||||
track_vars_array TSRMLS_CC);
|
track_vars_array TSRMLS_CC);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 'SCRIPT_NAME'
|
* 'PHP_SELF'
|
||||||
* Contains the current script's path. This is useful for pages which need to
|
* The filename of the currently executing script, relative to the document
|
||||||
* point to themselves. The __FILE__ constant contains the full path and
|
* root. For instance, $_SERVER['PHP_SELF'] in a script at the address
|
||||||
* filename of the current (i.e. included) file.
|
* http://example.com/foo/bar.php would be /foo/bar.php. The __FILE__
|
||||||
*/
|
* constant contains the full path and filename of the current (i.e.
|
||||||
|
* included) file. If PHP is running as a command-line processor this
|
||||||
|
* variable contains the script name since PHP 4.3.0. Previously it was not
|
||||||
|
* available.
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
if (nxt_php_script_name.start != NULL) {
|
||||||
* 'SCRIPT_FILENAME'
|
/* ABS_MODE */
|
||||||
* The absolute pathname of the currently executing script.
|
nxt_php_set_str(req, "PHP_SELF", &nxt_php_script_name,
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 'DOCUMENT_ROOT'
|
|
||||||
* The document root directory under which the current script is executing,
|
|
||||||
* as defined in the server's configuration file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (nxt_php_script.start != NULL) {
|
|
||||||
// ABS_MODE
|
|
||||||
/*
|
|
||||||
* 'PHP_SELF'
|
|
||||||
* The filename of the currently executing script, relative to the document
|
|
||||||
* root. For instance, $_SERVER['PHP_SELF'] in a script at the address
|
|
||||||
* http://example.com/foo/bar.php would be /foo/bar.php. The __FILE__ constant
|
|
||||||
* contains the full path and filename of the current (i.e. included) file.
|
|
||||||
* If PHP is running as a command-line processor this variable contains the
|
|
||||||
* script name since PHP 4.3.0. Previously it was not available.
|
|
||||||
*/
|
|
||||||
nxt_php_set_str(req, "PHP_SELF", &nxt_php_script,
|
|
||||||
track_vars_array TSRMLS_CC);
|
|
||||||
nxt_php_set_str(req, "SCRIPT_NAME", &nxt_php_script,
|
|
||||||
track_vars_array TSRMLS_CC);
|
track_vars_array TSRMLS_CC);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
nxt_php_set_sptr(req, "PHP_SELF", &r->path, r->path_length,
|
nxt_php_set_sptr(req, "PHP_SELF", &r->path, r->path_length,
|
||||||
track_vars_array TSRMLS_CC);
|
track_vars_array TSRMLS_CC);
|
||||||
nxt_php_set_sptr(req, "SCRIPT_NAME", &r->path, r->path_length,
|
|
||||||
track_vars_array TSRMLS_CC);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nxt_php_set_str(req, "SCRIPT_FILENAME", &ctx->script,
|
if (ctx->path_info.length != 0) {
|
||||||
|
nxt_php_set_str(req, "PATH_INFO", &ctx->path_info,
|
||||||
|
track_vars_array TSRMLS_CC);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 'SCRIPT_NAME'
|
||||||
|
* Contains the current script's path. This is useful for pages which need
|
||||||
|
* to point to themselves. The __FILE__ constant contains the full path and
|
||||||
|
* filename of the current (i.e. included) file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
nxt_php_set_str(req, "SCRIPT_NAME", &ctx->script_name,
|
||||||
track_vars_array TSRMLS_CC);
|
track_vars_array TSRMLS_CC);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 'SCRIPT_FILENAME'
|
||||||
|
* The absolute pathname of the currently executing script.
|
||||||
|
*/
|
||||||
|
|
||||||
|
nxt_php_set_str(req, "SCRIPT_FILENAME", &ctx->script_filename,
|
||||||
|
track_vars_array TSRMLS_CC);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 'DOCUMENT_ROOT'
|
||||||
|
* The document root directory under which the current script is executing,
|
||||||
|
* 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", &nxt_php_root,
|
||||||
track_vars_array TSRMLS_CC);
|
track_vars_array TSRMLS_CC);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user