📄 cgi_main.c
字号:
}static char *sapi_cgi_read_cookies(TSRMLS_D){ return sapi_cgibin_getenv((char *)"HTTP_COOKIE",0 TSRMLS_CC);}#if PHP_FASTCGIvoid cgi_php_import_environment_variables(zval *array_ptr TSRMLS_DC){ if (!FCGX_IsCGI()) { FCGX_Request *request = (FCGX_Request *)SG(server_context); char **env, *p, *t; for (env = request->envp; env != NULL && *env != NULL; env++) { p = strchr(*env, '='); if (!p) { /* malformed entry? */ continue; } t = estrndup(*env, p - *env); php_register_variable(t, p+1, array_ptr TSRMLS_CC); efree(t); } } /* call php's original import as a catch-all */ php_php_import_environment_variables(array_ptr TSRMLS_CC);}#endifstatic void sapi_cgi_register_variables(zval *track_vars_array TSRMLS_DC){ /* In CGI mode, we consider the environment to be a part of the server * variables */ php_import_environment_variables(track_vars_array TSRMLS_CC); /* Build the special-case PHP_SELF variable for the CGI version */ php_register_variable("PHP_SELF", (SG(request_info).request_uri ? SG(request_info).request_uri:""), track_vars_array TSRMLS_CC);}static void sapi_cgi_log_message(char *message){#if PHP_FASTCGI long logging = 1; TSRMLS_FETCH(); if (cfg_get_long("fastcgi.logging", &logging) == FAILURE) { logging = 1; } if (!FCGX_IsCGI() && logging) { FCGX_Request *request = (FCGX_Request *)SG(server_context); if (request) { FCGX_FPrintF( request->err, "%s\n", message ); } /* ignore return code */ } else#endif /* PHP_FASTCGI */ fprintf(stderr, "%s\n", message);}static int sapi_cgi_deactivate(TSRMLS_D){ fflush(stdout); if(SG(request_info).argv0) { free(SG(request_info).argv0); SG(request_info).argv0 = NULL; } return SUCCESS;}static int php_cgi_startup(sapi_module_struct *sapi_module){ if (php_module_startup(sapi_module, NULL, 0) == FAILURE) { return FAILURE; } return SUCCESS;}static int sapi_cgi_get_fd(int *fd TSRMLS_DC){#if PHP_FASTCGI FCGX_Request *request = (FCGX_Request *)SG(server_context); *fd = request->ipcFd; if (*fd >= 0) return SUCCESS; return FAILURE;#else *fd = STDOUT_FILENO; return SUCCESS;#endif}static int sapi_cgi_force_http_10(TSRMLS_D){ return SUCCESS;}/* {{{ sapi_module_struct cgi_sapi_module */static sapi_module_struct cgi_sapi_module = {#if PHP_FASTCGI "cgi-fcgi", /* name */ "CGI/FastCGI", /* pretty name */#else "cgi", /* name */ "CGI", /* pretty name */#endif php_cgi_startup, /* startup */ php_module_shutdown_wrapper, /* shutdown */ NULL, /* activate */ sapi_cgi_deactivate, /* deactivate */ sapi_cgibin_ub_write, /* unbuffered write */ sapi_cgibin_flush, /* flush */ NULL, /* get uid */ sapi_cgibin_getenv, /* getenv */ php_error, /* error handler */ NULL, /* header handler */ sapi_cgi_send_headers, /* send headers handler */ NULL, /* send header handler */ sapi_cgi_read_post, /* read POST data */ sapi_cgi_read_cookies, /* read Cookies */ sapi_cgi_register_variables, /* register server variables */ sapi_cgi_log_message, /* Log message */ NULL, /* php.ini path override */ NULL, /* block interruptions */ NULL, /* unblock interruptions */ NULL, /* default post reader */ NULL, /* treat data */ NULL, /* executable location */ 0, /* php.ini ignore */ sapi_cgi_get_fd, /* get fd */ sapi_cgi_force_http_10, /* force HTTP/1.0 */};/* }}} *//* {{{ php_cgi_usage */static void php_cgi_usage(char *argv0){ char *prog; prog = strrchr(argv0, '/'); if (prog) { prog++; } else { prog = "php"; } php_printf("Usage: %s [-q] [-h] [-s] [-v] [-i] [-f <file>] \n" " %s <file> [args...]\n" " -a Run interactively\n"#if PHP_FASTCGI && !defined(PHP_WIN32) " -b <address:port>|<port> Bind Path for external FASTCGI Server mode\n"#endif " -C Do not chdir to the script's directory\n" " -c <path>|<file> Look for php.ini file in this directory\n" " -n No php.ini file will be used\n" " -d foo[=bar] Define INI entry foo with value 'bar'\n" " -e Generate extended information for debugger/profiler\n" " -f <file> Parse <file>. Implies `-q'\n" " -h This help\n" " -i PHP information\n" " -l Syntax check only (lint)\n" " -m Show compiled in modules\n" " -q Quiet-mode. Suppress HTTP Header output.\n" " -s Display colour syntax highlighted source.\n" " -v Version number\n" " -w Display source with stripped comments and whitespace.\n" " -z <file> Load Zend extension <file>.\n", prog, prog);}/* }}} *//* {{{ init_request_info initializes request_info structure specificly in this section we handle proper translations for: PATH_INFO derived from the portion of the URI path following the script name but preceding any query data may be empty PATH_TRANSLATED derived by taking any path-info component of the request URI and performing any virtual-to-physical translation appropriate to map it onto the server's document repository structure empty if PATH_INFO is empty The env var PATH_TRANSLATED **IS DIFFERENT** than the request_info.path_translated variable, the latter should match SCRIPT_FILENAME instead. SCRIPT_NAME set to a URL path that could identify the CGI script rather than the interpreter. PHP_SELF is set to this. REQUEST_URI uri section following the domain:port part of a URI SCRIPT_FILENAME The virtual-to-physical translation of SCRIPT_NAME (as per PATH_TRANSLATED) These settings are documented at http://cgi-spec.golux.com/ Based on the following URL request: http://localhost/info.php/test?a=b should produce, which btw is the same as if we were running under mod_cgi on apache (ie. not using ScriptAlias directives): PATH_INFO=/test PATH_TRANSLATED=/docroot/test SCRIPT_NAME=/info.php REQUEST_URI=/info.php/test?a=b SCRIPT_FILENAME=/docroot/info.php QUERY_STRING=a=b but what we get is (cgi/mod_fastcgi under apache): PATH_INFO=/info.php/test PATH_TRANSLATED=/docroot/info.php/test SCRIPT_NAME=/php/php-cgi (from the Action setting I suppose) REQUEST_URI=/info.php/test?a=b SCRIPT_FILENAME=/path/to/php/bin/php-cgi (Action setting translated) QUERY_STRING=a=b Comments in the code below refer to using the above URL in a request */static void init_request_info(TSRMLS_D){ char *env_script_filename = sapi_cgibin_getenv("SCRIPT_FILENAME",0 TSRMLS_CC); char *env_path_translated = sapi_cgibin_getenv("PATH_TRANSLATED",0 TSRMLS_CC); char *script_path_translated = env_script_filename;#if !DISCARD_PATH /* some broken servers do not have script_filename or argv0 an example, IIS configured in some ways. then they do more broken stuff and set path_translated to the cgi script location */ if (!script_path_translated && env_path_translated) { script_path_translated = env_path_translated; }#endif /* initialize the defaults */ SG(request_info).path_translated = NULL; SG(request_info).request_method = NULL; SG(request_info).query_string = NULL; SG(request_info).request_uri = NULL; SG(request_info).content_type = NULL; SG(request_info).content_length = 0; SG(sapi_headers).http_response_code = 200; /* script_path_translated being set is a good indication that we are running in a cgi environment, since it is always null otherwise. otherwise, the filename of the script will be retreived later via argc/argv */ if (script_path_translated) { const char *auth; char *content_length = sapi_cgibin_getenv("CONTENT_LENGTH",0 TSRMLS_CC); char *content_type = sapi_cgibin_getenv("CONTENT_TYPE",0 TSRMLS_CC); char *env_path_info = sapi_cgibin_getenv("PATH_INFO",0 TSRMLS_CC); char *env_script_name = sapi_cgibin_getenv("SCRIPT_NAME",0 TSRMLS_CC);#if ENABLE_PATHINFO_CHECK struct stat st; char *env_redirect_url = sapi_cgibin_getenv("REDIRECT_URL",0 TSRMLS_CC); char *env_document_root = sapi_cgibin_getenv("DOCUMENT_ROOT",0 TSRMLS_CC); if (fix_pathinfo) { /* save the originals first for anything we change later */ if (env_path_translated) { _sapi_cgibin_putenv("ORIG_PATH_TRANSLATED",env_path_translated TSRMLS_CC); } if (env_path_info) { _sapi_cgibin_putenv("ORIG_PATH_INFO",env_path_info TSRMLS_CC); } if (env_script_name) { _sapi_cgibin_putenv("ORIG_SCRIPT_NAME",env_script_name TSRMLS_CC); } if (env_script_filename) { _sapi_cgibin_putenv("ORIG_SCRIPT_FILENAME",env_script_filename TSRMLS_CC); } if (!env_document_root) { /* ini version of document root */ if (!env_document_root) { env_document_root = PG(doc_root); } /* set the document root, this makes a more consistent env for php scripts */ if (env_document_root) { env_document_root = _sapi_cgibin_putenv("DOCUMENT_ROOT",env_document_root TSRMLS_CC); /* fix docroot */ TRANSLATE_SLASHES(env_document_root); } } if (env_path_translated != NULL && env_redirect_url != NULL) { /* pretty much apache specific. If we have a redirect_url then our script_filename and script_name point to the php executable */ script_path_translated = env_path_translated; /* we correct SCRIPT_NAME now in case we don't have PATH_INFO */ env_script_name = _sapi_cgibin_putenv("SCRIPT_NAME",env_redirect_url TSRMLS_CC); }#ifdef __riscos__ /* Convert path to unix format*/ __riscosify_control|=__RISCOSIFY_DONT_CHECK_DIR; script_path_translated=__unixify(script_path_translated,0,NULL,1,0);#endif /* * if the file doesn't exist, try to extract PATH_INFO out * of it by stat'ing back through the '/' * this fixes url's like /info.php/test */ if (script_path_translated && stat( script_path_translated, &st ) == -1 ) { char *pt = estrdup(script_path_translated); int len = strlen(pt); char *ptr; while( (ptr = strrchr(pt,'/')) || (ptr = strrchr(pt,'\\')) ) { *ptr = 0; if ( stat(pt, &st) == 0 && S_ISREG(st.st_mode) ) { /* * okay, we found the base script! * work out how many chars we had to strip off; * then we can modify PATH_INFO * accordingly * * we now have the makings of * PATH_INFO=/test * SCRIPT_FILENAME=/docroot/info.php * * we now need to figure out what docroot is. * if DOCUMENT_ROOT is set, this is easy, otherwise, * we have to play the game of hide and seek to figure * out what SCRIPT_NAME should be */ int slen = len - strlen(pt); int pilen = strlen( env_path_info ); char *path_info = env_path_info + pilen - slen; env_path_info = _sapi_cgibin_putenv("PATH_INFO",path_info TSRMLS_CC); script_path_translated = _sapi_cgibin_putenv("SCRIPT_FILENAME",pt TSRMLS_CC); TRANSLATE_SLASHES(pt); /* figure out docroot SCRIPT_FILENAME minus SCRIPT_NAME */ if (env_document_root) { int l = strlen(env_document_root); int path_translated_len = 0; char *path_translated = NULL; if (l && env_document_root[l-1]=='/') { --l; } /* we have docroot, so we should have: * DOCUMENT_ROOT=/docroot * SCRIPT_FILENAME=/docroot/info.php * * SCRIPT_NAME is the portion of the path beyond docroot */ env_script_name = _sapi_cgibin_putenv("SCRIPT_NAME",pt+l TSRMLS_CC); /* * PATH_TRANSATED = DOCUMENT_ROOT + PATH_INFO */ path_translated_len = l + strlen(env_path_info) + 2; path_translated = (char *)emalloc(path_translated_len); *path_translated = 0; strncat(path_translated,env_document_root,l); strcat(path_translated,env_path_info); env_path_translated = _sapi_cgibin_putenv("PATH_TRANSLATED",path_translated TSRMLS_CC); efree(path_translated); } else if (env_script_name && strstr(pt,env_script_name)) { /* * PATH_TRANSATED = PATH_TRANSATED - SCRIPT_NAME + PATH_INFO */ int ptlen = strlen(pt)-strlen(env_script_name); int path_translated_len = ptlen + strlen(env_path_info) + 2; char *path_translated = NULL; path_translated = (char *)emalloc(path_translated_len); *path_translated = 0; strncat(path_translated,pt,ptlen); strcat(path_translated,env_path_info); env_path_translated = _sapi_cgibin_putenv("PATH_TRANSLATED",path_translated TSRMLS_CC); efree(path_translated); } break; } } if (!ptr) { /* * if we stripped out all the '/' and still didn't find * a valid path... we will fail, badly. of course we would * have failed anyway... we output 'no input file' now. */ script_path_translated = _sapi_cgibin_putenv("SCRIPT_FILENAME",NULL TSRMLS_CC); SG(sapi_headers).http_response_code = 404; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -