diff options
author | Uwe Schindler <thetaphi@php.net> | 2003-07-24 17:40:40 +0000 |
---|---|---|
committer | Uwe Schindler <thetaphi@php.net> | 2003-07-24 17:40:40 +0000 |
commit | 3fbe69f49aae47fa6e624fb9e8dedbf29cd0f88f (patch) | |
tree | 1ee4c63a5f2d26b946d90ebbdcfe563f352f3644 /sapi | |
parent | e03b0dea7d5298ff60bdf25af7f565f0e0c2a7a9 (diff) | |
download | php-git-3fbe69f49aae47fa6e624fb9e8dedbf29cd0f88f.tar.gz |
Possibility to use php5_execute to display server error pages or directory listing pages
Diffstat (limited to 'sapi')
-rw-r--r-- | sapi/nsapi/nsapi-readme.txt | 30 | ||||
-rw-r--r-- | sapi/nsapi/nsapi.c | 129 |
2 files changed, 128 insertions, 31 deletions
diff --git a/sapi/nsapi/nsapi-readme.txt b/sapi/nsapi/nsapi-readme.txt index a34c0bf61c..2635866541 100644 --- a/sapi/nsapi/nsapi-readme.txt +++ b/sapi/nsapi/nsapi-readme.txt @@ -72,7 +72,7 @@ hide PHP usage by renaming files to .html Authentication configuration ---------------------------- -PHP authentication cannot be used with any other authentication. ALL +PHP authentication cannot be used with any other authentication. ALL AUTHENTICATION IS PASSED TO YOUR PHP SCRIPT. To configure PHP Authentication for the entire server, add the following line: @@ -91,3 +91,31 @@ To use PHP Authentication on a single directory, add the following: AuthTrans fn=php5_auth_trans </Object> + +Special use for error pages or self-made directory listings +----------------------------------------------------------- + +You can use PHP to generate the error pages for "404 Not Found" +or similar. Add the following line to the object in obj.conf for +every error page you want to overwrite: + + Error fn="php5_execute" code=XXX script="/path/to/script.php" [inikey=value inikey=value...] + +where XXX ist the HTTP error code. Please delete any other Error +directives which could interfere with yours. +If you want to place a page for all errors that could exist, leave +the "code" parameter out. Your script can get the HTTP status code +with $_SERVER['ERROR_TYPE']. + +Another posibility is to generate self-made directory listings. +Just generate a PHP script which displays a directory listing and +replace the corresponding default Service line for +type="magnus-internal/directory" in obj.conf with the following: + + Service fn="php5_execute" type="magnus-internal/directory" script="/path/to/script.php" [inikey=value inikey=value...] + +For both error and directory listing pages the original URI and +translated URI are in the variables $_SERVER['PATH_INFO'] and +$_SERVER['PATH_TRANSLATED']. + +$ Id: $ diff --git a/sapi/nsapi/nsapi.c b/sapi/nsapi/nsapi.c index c10811b181..0a9857dde6 100644 --- a/sapi/nsapi/nsapi.c +++ b/sapi/nsapi/nsapi.c @@ -90,6 +90,9 @@ typedef struct nsapi_request_context { Session *sn; Request *rq; int read_post_bytes; + char *path_info; + int fixed_script; /* 0 if script is from URI, 1 if script is from "script" parameter */ + short http_error; /* 0 in normal mode; for errors the HTTP error code */ } nsapi_request_context; /* @@ -118,8 +121,6 @@ static nsapi_equiv nsapi_reqpb[] = { static size_t nsapi_reqpb_size = sizeof(nsapi_reqpb)/sizeof(nsapi_reqpb[0]); static nsapi_equiv nsapi_vars[] = { - { "PATH_INFO", "path-info" }, - { "SCRIPT_FILENAME", "path" }, { "AUTH_TYPE", "auth-type" }, { "CLIENT_CERT", "auth-cert" }, { "REMOTE_USER", "auth-user" } @@ -134,7 +135,8 @@ static nsapi_equiv nsapi_client[] = { }; static size_t nsapi_client_size = sizeof(nsapi_client)/sizeof(nsapi_client[0]); -static char *nsapi_exclude_from_ini_entries[] = { "fn", "type", "method", "directive", NULL }; +/* this parameters to "Service"/"Error" are NSAPI ones which should not be php.ini keys and are excluded */ +static char *nsapi_exclude_from_ini_entries[] = { "fn", "type", "method", "directive", "code", "reason", "script", NULL }; static char *nsapi_strdup(char *str) { @@ -475,8 +477,6 @@ static int sapi_nsapi_header_handler(sapi_header_struct *sapi_header, sapi_heade if (!strcasecmp(header_name, "Content-Type")) { param_free(pblock_remove("content-type", rc->rq->srvhdrs)); pblock_nvinsert("content-type", header_content, rc->rq->srvhdrs); - } else if (!strcasecmp(header_name, "Set-Cookie")) { - pblock_nvinsert("set-cookie", header_content, rc->rq->srvhdrs); } else { pblock_nvinsert(header_name, header_content, rc->rq->srvhdrs); } @@ -583,6 +583,7 @@ static void sapi_nsapi_register_server_variables(zval *track_vars_array TSRMLS_D { nsapi_request_context *rc = (nsapi_request_context *)SG(server_context); register size_t i; + int pos; char *value,*p; char buf[NS_BUF_SIZE + 1]; struct pb_entry *entry; @@ -652,40 +653,50 @@ static void sapi_nsapi_register_server_variables(zval *track_vars_array TSRMLS_D /* DOCUMENT_ROOT */ if (value = request_translate_uri("/", rc->sn)) { - value[strlen(value) - 1] = 0; + value[strlen(value) - 1] = '\0'; php_register_variable("DOCUMENT_ROOT", value, track_vars_array TSRMLS_CC); nsapi_free(value); } - /* PATH_TRANSLATED */ - if (value = pblock_findval("path-info", rc->rq->vars)) { - if (value = request_translate_uri(value, rc->sn)) { + /* PATH_INFO / PATH_TRANSLATED */ + if (rc->path_info) { + if (value = request_translate_uri(rc->path_info, rc->sn)) { php_register_variable("PATH_TRANSLATED", value, track_vars_array TSRMLS_CC); nsapi_free(value); } + php_register_variable("PATH_INFO", rc->path_info, track_vars_array TSRMLS_CC); } - /* Create full Request-URI */ - if (value = pblock_findval("uri", rc->rq->reqpb)) { - strncpy(buf, value, NS_BUF_SIZE); + /* Create full Request-URI & Script-Name */ + if (SG(request_info).request_uri) { + strncpy(buf, SG(request_info).request_uri, NS_BUF_SIZE); buf[NS_BUF_SIZE]='\0'; - if (value = pblock_findval("query", rc->rq->reqpb)) { + if (SG(request_info).query_string) { p = strchr(buf, 0); - snprintf(p, NS_BUF_SIZE-(p-buf), "?%s", value); + snprintf(p, NS_BUF_SIZE-(p-buf), "?%s", SG(request_info).query_string); buf[NS_BUF_SIZE]='\0'; } php_register_variable("REQUEST_URI", buf, track_vars_array TSRMLS_CC); - } - /* Create Script-Name */ - if (value = pblock_findval("uri", rc->rq->reqpb)) { - strncpy(buf, value, NS_BUF_SIZE); + strncpy(buf, SG(request_info).request_uri, NS_BUF_SIZE); buf[NS_BUF_SIZE]='\0'; - if (value = pblock_findval("path-info", rc->rq->vars)) { - buf[strlen(buf) - strlen(value)] = '\0'; + if (rc->path_info) { + pos = strlen(SG(request_info).request_uri) - strlen(rc->path_info); + if (pos>=0 && pos<=NS_BUF_SIZE && rc->path_info) { + buf[pos] = '\0'; + } else { + buf[0]='\0'; + } } php_register_variable("SCRIPT_NAME", buf, track_vars_array TSRMLS_CC); } + php_register_variable("SCRIPT_FILENAME", SG(request_info).path_translated, track_vars_array TSRMLS_CC); + + /* special variables in error mode */ + if (rc->http_error) { + sprintf(buf, "%d", rc->http_error); + php_register_variable("ERROR_TYPE", buf, track_vars_array TSRMLS_CC); + } } static void nsapi_log_message(char *message) @@ -780,6 +791,13 @@ void NSAPI_PUBLIC php5_close(void *vparam) log_error(LOG_INFORM, "php5_close", NULL, NULL, "Shutdown PHP Module"); } +/********************************************************* +/ init SAF +/ +/ Init fn="php5_init" [php_ini="/path/to/php.ini"] +/ Initialize the NSAPI module in magnus.conf +/ +/*********************************************************/ int NSAPI_PUBLIC php5_init(pblock *pb, Session *sn, Request *rq) { php_core_globals *core_globals; @@ -812,6 +830,21 @@ int NSAPI_PUBLIC php5_init(pblock *pb, Session *sn, Request *rq) return REQ_PROCEED; } +/********************************************************* +/ normal use in Service directive: +/ +/ Service fn="php5_execute" type=... method=... [inikey=inivalue inikey=inivalue...] +/ +/ use in Service for a directory to supply a php-made directory listing instead of server default: +/ +/ Service fn="php5_execute" type="magnus-internal/directory" script="/path/to/script.php" [inikey=inivalue inikey=inivalue...] +/ +/ use in Error SAF to display php script as error page: +/ +/ Error fn="php5_execute" code=XXX script="/path/to/script.php" [inikey=inivalue inikey=inivalue...] +/ Error fn="php5_execute" reason="Reason" script="/path/to/script.php" [inikey=inivalue inikey=inivalue...] +/ +/*********************************************************/ int NSAPI_PUBLIC php5_execute(pblock *pb, Session *sn, Request *rq) { int retval; @@ -819,23 +852,47 @@ int NSAPI_PUBLIC php5_execute(pblock *pb, Session *sn, Request *rq) zend_file_handle file_handle = {0}; struct stat fst; + char *path_info; char *query_string = pblock_findval("query", rq->reqpb); char *uri = pblock_findval("uri", rq->reqpb); - char *path_info = pblock_findval("path-info", rq->vars); char *request_method = pblock_findval("method", rq->reqpb); char *content_type = pblock_findval("content-type", rq->headers); char *content_length = pblock_findval("content-length", rq->headers); - char *path_translated = pblock_findval("path", rq->vars); + char *directive = pblock_findval("Directive", pb); + int error_directive = (directive && !strcasecmp(directive, "error")); + int fixed_script = 1; + + /* try to use script parameter -> Error or Service for directory listing */ + char *path_translated = pblock_findval("script", pb); TSRMLS_FETCH(); + /* if script parameter is missing: normal use as Service SAF */ + if (!path_translated) { + path_translated = pblock_findval("path", rq->vars); + path_info = pblock_findval("path-info", rq->vars); + fixed_script = 0; + if (error_directive) { + /* go to next error directive if script parameter is missing */ + log_error(LOG_WARN, pblock_findval("fn", pb), sn, rq, "Missing 'script' parameter"); + return REQ_NOACTION; + } + } else { + /* in error the path_info is the uri to the requested page */ + path_info = pblock_findval("uri", rq->reqpb); + } + /* check if this uri was included in an other PHP script with nsapi_virtual() by looking for a request context in the current thread */ if (SG(server_context)) { /* send 500 internal server error */ log_error(LOG_WARN, pblock_findval("fn", pb), sn, rq, "Cannot make nesting PHP requests with nsapi_virtual()"); - protocol_status(sn, rq, 500, NULL); - return REQ_ABORTED; + if (error_directive) { + return REQ_NOACTION; + } else { + protocol_status(sn, rq, 500, NULL); + return REQ_ABORTED; + } } request_context = (nsapi_request_context *)MALLOC(sizeof(nsapi_request_context)); @@ -843,6 +900,9 @@ int NSAPI_PUBLIC php5_execute(pblock *pb, Session *sn, Request *rq) request_context->sn = sn; request_context->rq = rq; request_context->read_post_bytes = 0; + request_context->fixed_script = fixed_script; + request_context->http_error = (error_directive) ? rq->status_num : 0; + request_context->path_info = nsapi_strdup(path_info); SG(server_context) = request_context; SG(request_info).query_string = nsapi_strdup(query_string); @@ -851,7 +911,7 @@ int NSAPI_PUBLIC php5_execute(pblock *pb, Session *sn, Request *rq) SG(request_info).path_translated = nsapi_strdup(path_translated); SG(request_info).content_type = nsapi_strdup(content_type); SG(request_info).content_length = (content_length == NULL) ? 0 : strtoul(content_length, 0, 0); - SG(sapi_headers).http_response_code = 200; + SG(sapi_headers).http_response_code = (error_directive) ? rq->status_num : 200; nsapi_php_ini_entries(NSLS_C TSRMLS_CC); @@ -868,16 +928,25 @@ int NSAPI_PUBLIC php5_execute(pblock *pb, Session *sn, Request *rq) } else { /* send 500 internal server error */ log_error(LOG_WARN, pblock_findval("fn", pb), sn, rq, "Cannot prepare PHP engine!"); - protocol_status(sn, rq, 500, NULL); - retval=REQ_ABORTED; + if (error_directive) { + retval=REQ_NOACTION; + } else { + protocol_status(sn, rq, 500, NULL); + retval=REQ_ABORTED; + } } } else { /* send 404 because file not found */ - log_error(LOG_WARN, pblock_findval("fn", pb), sn, rq, "Cannot execute PHP script: %s", SG(request_info).path_translated); - protocol_status(sn, rq, 404, NULL); - retval=REQ_ABORTED; + log_error(LOG_WARN, pblock_findval("fn", pb), sn, rq, "Cannot execute PHP script: %s (File not found)", SG(request_info).path_translated); + if (error_directive) { + retval=REQ_NOACTION; + } else { + protocol_status(sn, rq, 404, NULL); + retval=REQ_ABORTED; + } } + nsapi_free(request_context->path_info); nsapi_free(SG(request_info).query_string); nsapi_free(SG(request_info).request_uri); nsapi_free((void*)(SG(request_info).request_method)); |