123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973 |
- /*
- +----------------------------------------------------------------------+
- | PHP Version 5 |
- +----------------------------------------------------------------------+
- | Copyright (c) 1997-2016 The PHP Group |
- +----------------------------------------------------------------------+
- | This source file is subject to version 3.01 of the PHP license, |
- | that is bundled with this package in the file LICENSE, and is |
- | available through the world-wide-web at the following url: |
- | http://www.php.net/license/3_01.txt |
- | If you did not receive a copy of the PHP license and are unable to |
- | obtain it through the world-wide-web, please send a note to |
- | license@php.net so we can mail you a copy immediately. |
- +----------------------------------------------------------------------+
- | Authors: Zeev Suraski <zeev@zend.com> |
- | Ben Mansell <ben@zeus.com> (Zeus Support) |
- +----------------------------------------------------------------------+
- */
- /* $Id$ */
- #include "php.h"
- #include <httpext.h>
- #include <httpfilt.h>
- #include <httpext.h>
- #include "php_main.h"
- #include "SAPI.h"
- #include "php_globals.h"
- #include "ext/standard/info.h"
- #include "php_variables.h"
- #include "php_ini.h"
- #ifdef PHP_WIN32
- # include <process.h>
- #else
- # define __try
- # define __except(val)
- # define __declspec(foo)
- #endif
- #ifdef WITH_ZEUS
- # include "httpext.h"
- # include <errno.h>
- # define GetLastError() errno
- #endif
- #ifdef PHP_WIN32
- #define PHP_ENABLE_SEH
- #endif
- /*
- uncomment the following lines to turn off
- exception trapping when running under a debugger
- #ifdef _DEBUG
- #undef PHP_ENABLE_SEH
- #endif
- */
- #define MAX_STATUS_LENGTH sizeof("xxxx LONGEST POSSIBLE STATUS DESCRIPTION")
- #define ISAPI_SERVER_VAR_BUF_SIZE 1024
- #define ISAPI_POST_DATA_BUF 1024
- static zend_bool bFilterLoaded=0;
- static zend_bool bTerminateThreadsOnError=0;
- static char *isapi_special_server_variable_names[] = {
- "ALL_HTTP",
- "HTTPS",
- #ifndef WITH_ZEUS
- "SCRIPT_NAME",
- #endif
- NULL
- };
- #define NUM_SPECIAL_VARS (sizeof(isapi_special_server_variable_names)/sizeof(char *))
- #define SPECIAL_VAR_ALL_HTTP 0
- #define SPECIAL_VAR_HTTPS 1
- #define SPECIAL_VAR_PHP_SELF 2
- static char *isapi_server_variable_names[] = {
- "AUTH_PASSWORD",
- "AUTH_TYPE",
- "AUTH_USER",
- "CONTENT_LENGTH",
- "CONTENT_TYPE",
- "PATH_TRANSLATED",
- "QUERY_STRING",
- "REMOTE_ADDR",
- "REMOTE_HOST",
- "REMOTE_USER",
- "REQUEST_METHOD",
- "SERVER_NAME",
- "SERVER_PORT",
- "SERVER_PROTOCOL",
- "SERVER_SOFTWARE",
- #ifndef WITH_ZEUS
- "APPL_MD_PATH",
- "APPL_PHYSICAL_PATH",
- "INSTANCE_ID",
- "INSTANCE_META_PATH",
- "LOGON_USER",
- "REQUEST_URI",
- "URL",
- #else
- "DOCUMENT_ROOT",
- #endif
- NULL
- };
- static char *isapi_secure_server_variable_names[] = {
- "CERT_COOKIE",
- "CERT_FLAGS",
- "CERT_ISSUER",
- "CERT_KEYSIZE",
- "CERT_SECRETKEYSIZE",
- "CERT_SERIALNUMBER",
- "CERT_SERVER_ISSUER",
- "CERT_SERVER_SUBJECT",
- "CERT_SUBJECT",
- "HTTPS_KEYSIZE",
- "HTTPS_SECRETKEYSIZE",
- "HTTPS_SERVER_ISSUER",
- "HTTPS_SERVER_SUBJECT",
- "SERVER_PORT_SECURE",
- #ifdef WITH_ZEUS
- "SSL_CLIENT_CN",
- "SSL_CLIENT_EMAIL",
- "SSL_CLIENT_OU",
- "SSL_CLIENT_O",
- "SSL_CLIENT_L",
- "SSL_CLIENT_ST",
- "SSL_CLIENT_C",
- "SSL_CLIENT_I_CN",
- "SSL_CLIENT_I_EMAIL",
- "SSL_CLIENT_I_OU",
- "SSL_CLIENT_I_O",
- "SSL_CLIENT_I_L",
- "SSL_CLIENT_I_ST",
- "SSL_CLIENT_I_C",
- #endif
- NULL
- };
- static void php_info_isapi(ZEND_MODULE_INFO_FUNC_ARGS)
- {
- char **p;
- char variable_buf[ISAPI_SERVER_VAR_BUF_SIZE];
- DWORD variable_len;
- char **all_variables[] = {
- isapi_server_variable_names,
- isapi_special_server_variable_names,
- isapi_secure_server_variable_names,
- NULL
- };
- char ***server_variable_names;
- LPEXTENSION_CONTROL_BLOCK lpECB;
- lpECB = (LPEXTENSION_CONTROL_BLOCK) SG(server_context);
- php_info_print_table_start();
- php_info_print_table_header(2, "Server Variable", "Value");
- server_variable_names = all_variables;
- while (*server_variable_names) {
- p = *server_variable_names;
- while (*p) {
- variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
- if (lpECB->GetServerVariable(lpECB->ConnID, *p, variable_buf, &variable_len)
- && variable_buf[0]) {
- php_info_print_table_row(2, *p, variable_buf);
- } else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
- char *tmp_variable_buf;
- tmp_variable_buf = (char *) emalloc(variable_len);
- if (lpECB->GetServerVariable(lpECB->ConnID, *p, tmp_variable_buf, &variable_len)
- && variable_buf[0]) {
- php_info_print_table_row(2, *p, tmp_variable_buf);
- }
- efree(tmp_variable_buf);
- }
- p++;
- }
- server_variable_names++;
- }
- php_info_print_table_end();
- }
- static zend_module_entry php_isapi_module = {
- STANDARD_MODULE_HEADER,
- "ISAPI",
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- php_info_isapi,
- NULL,
- STANDARD_MODULE_PROPERTIES
- };
- static int sapi_isapi_ub_write(const char *str, uint str_length TSRMLS_DC)
- {
- DWORD num_bytes = str_length;
- LPEXTENSION_CONTROL_BLOCK ecb;
-
- ecb = (LPEXTENSION_CONTROL_BLOCK) SG(server_context);
- if (ecb->WriteClient(ecb->ConnID, (char *) str, &num_bytes, HSE_IO_SYNC) == FALSE) {
- php_handle_aborted_connection();
- }
- return num_bytes;
- }
- static int sapi_isapi_header_handler(sapi_header_struct *sapi_header, sapi_header_op_enum op, sapi_headers_struct *sapi_headers TSRMLS_DC)
- {
- return SAPI_HEADER_ADD;
- }
- static void accumulate_header_length(sapi_header_struct *sapi_header, uint *total_length TSRMLS_DC)
- {
- *total_length += sapi_header->header_len+2;
- }
- static void concat_header(sapi_header_struct *sapi_header, char **combined_headers_ptr TSRMLS_DC)
- {
- memcpy(*combined_headers_ptr, sapi_header->header, sapi_header->header_len);
- *combined_headers_ptr += sapi_header->header_len;
- **combined_headers_ptr = '\r';
- (*combined_headers_ptr)++;
- **combined_headers_ptr = '\n';
- (*combined_headers_ptr)++;
- }
- static int sapi_isapi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
- {
- uint total_length = 2; /* account for the trailing \r\n */
- char *combined_headers, *combined_headers_ptr;
- LPEXTENSION_CONTROL_BLOCK lpECB = (LPEXTENSION_CONTROL_BLOCK) SG(server_context);
- HSE_SEND_HEADER_EX_INFO header_info;
- sapi_header_struct default_content_type;
- char *status_buf = NULL;
- /* Obtain headers length */
- if (SG(sapi_headers).send_default_content_type) {
- sapi_get_default_content_type_header(&default_content_type TSRMLS_CC);
- accumulate_header_length(&default_content_type, (void *) &total_length TSRMLS_CC);
- }
- zend_llist_apply_with_argument(&SG(sapi_headers).headers, (llist_apply_with_arg_func_t) accumulate_header_length, (void *) &total_length TSRMLS_CC);
- /* Generate headers */
- combined_headers = (char *) emalloc(total_length+1);
- combined_headers_ptr = combined_headers;
- if (SG(sapi_headers).send_default_content_type) {
- concat_header(&default_content_type, (void *) &combined_headers_ptr TSRMLS_CC);
- sapi_free_header(&default_content_type); /* we no longer need it */
- }
- zend_llist_apply_with_argument(&SG(sapi_headers).headers, (llist_apply_with_arg_func_t) concat_header, (void *) &combined_headers_ptr TSRMLS_CC);
- *combined_headers_ptr++ = '\r';
- *combined_headers_ptr++ = '\n';
- *combined_headers_ptr = 0;
- switch (SG(sapi_headers).http_response_code) {
- case 200:
- header_info.pszStatus = "200 OK";
- break;
- case 302:
- header_info.pszStatus = "302 Moved Temporarily";
- break;
- case 401:
- header_info.pszStatus = "401 Authorization Required";
- break;
- default: {
- const char *sline = SG(sapi_headers).http_status_line;
- int sline_len;
-
- /* httpd requires that r->status_line is set to the first digit of
- * the status-code: */
- if (sline && ((sline_len = strlen(sline)) > 12) && strncmp(sline, "HTTP/1.", 7) == 0 && sline[8] == ' ') {
- if ((sline_len - 9) > MAX_STATUS_LENGTH) {
- status_buf = estrndup(sline + 9, MAX_STATUS_LENGTH);
- } else {
- status_buf = estrndup(sline + 9, sline_len - 9);
- }
- } else {
- status_buf = emalloc(MAX_STATUS_LENGTH + 1);
- snprintf(status_buf, MAX_STATUS_LENGTH, "%d Undescribed", SG(sapi_headers).http_response_code);
- }
- header_info.pszStatus = status_buf;
- break;
- }
- }
- header_info.cchStatus = strlen(header_info.pszStatus);
- header_info.pszHeader = combined_headers;
- header_info.cchHeader = total_length;
- header_info.fKeepConn = FALSE;
- lpECB->dwHttpStatusCode = SG(sapi_headers).http_response_code;
- lpECB->ServerSupportFunction(lpECB->ConnID, HSE_REQ_SEND_RESPONSE_HEADER_EX, &header_info, NULL, NULL);
- efree(combined_headers);
- if (status_buf) {
- efree(status_buf);
- }
- return SAPI_HEADER_SENT_SUCCESSFULLY;
- }
- static int php_isapi_startup(sapi_module_struct *sapi_module)
- {
- if (php_module_startup(sapi_module, &php_isapi_module, 1)==FAILURE) {
- return FAILURE;
- } else {
- bTerminateThreadsOnError = (zend_bool) INI_INT("isapi.terminate_threads_on_error");
- return SUCCESS;
- }
- }
- static int sapi_isapi_read_post(char *buffer, uint count_bytes TSRMLS_DC)
- {
- LPEXTENSION_CONTROL_BLOCK lpECB = (LPEXTENSION_CONTROL_BLOCK) SG(server_context);
- DWORD read_from_buf=0;
- DWORD read_from_input=0;
- DWORD total_read=0;
- if ((DWORD) SG(read_post_bytes) < lpECB->cbAvailable) {
- read_from_buf = MIN(lpECB->cbAvailable-SG(read_post_bytes), count_bytes);
- memcpy(buffer, lpECB->lpbData+SG(read_post_bytes), read_from_buf);
- total_read += read_from_buf;
- }
- if (read_from_buf<count_bytes
- && (SG(read_post_bytes)+read_from_buf) < lpECB->cbTotalBytes) {
- DWORD cbRead=0, cbSize;
- read_from_input = MIN(count_bytes-read_from_buf, lpECB->cbTotalBytes-SG(read_post_bytes)-read_from_buf);
- while (cbRead < read_from_input) {
- cbSize = read_from_input - cbRead;
- if (!lpECB->ReadClient(lpECB->ConnID, buffer+read_from_buf+cbRead, &cbSize) || cbSize==0) {
- break;
- }
- cbRead += cbSize;
- }
- total_read += cbRead;
- }
- return total_read;
- }
- static char *sapi_isapi_read_cookies(TSRMLS_D)
- {
- LPEXTENSION_CONTROL_BLOCK lpECB = (LPEXTENSION_CONTROL_BLOCK) SG(server_context);
- char variable_buf[ISAPI_SERVER_VAR_BUF_SIZE];
- DWORD variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
- if (lpECB->GetServerVariable(lpECB->ConnID, "HTTP_COOKIE", variable_buf, &variable_len)) {
- return estrndup(variable_buf, variable_len);
- } else if (GetLastError()==ERROR_INSUFFICIENT_BUFFER) {
- char *tmp_variable_buf = (char *) emalloc(variable_len+1);
- if (lpECB->GetServerVariable(lpECB->ConnID, "HTTP_COOKIE", tmp_variable_buf, &variable_len)) {
- tmp_variable_buf[variable_len] = 0;
- return tmp_variable_buf;
- } else {
- efree(tmp_variable_buf);
- }
- }
- return STR_EMPTY_ALLOC();
- }
- #ifdef WITH_ZEUS
- static void sapi_isapi_register_zeus_ssl_variables(LPEXTENSION_CONTROL_BLOCK lpECB, zval *track_vars_array TSRMLS_DC)
- {
- char static_variable_buf[ISAPI_SERVER_VAR_BUF_SIZE];
- DWORD variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
- char static_cons_buf[ISAPI_SERVER_VAR_BUF_SIZE];
- /*
- * We need to construct the /C=.../ST=...
- * DN's for SSL_CLIENT_DN and SSL_CLIENT_I_DN
- */
- strcpy( static_cons_buf, "/C=" );
- if( lpECB->GetServerVariable( lpECB->ConnID, "SSL_CLIENT_C", static_variable_buf, &variable_len ) && static_variable_buf[0] ) {
- strlcat( static_cons_buf, static_variable_buf, ISAPI_SERVER_VAR_BUF_SIZE);
- }
- strlcat( static_cons_buf, "/ST=", ISAPI_SERVER_VAR_BUF_SIZE);
- variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
- if( lpECB->GetServerVariable( lpECB->ConnID, "SSL_CLIENT_ST", static_variable_buf, &variable_len ) && static_variable_buf[0] ) {
- strlcat( static_cons_buf, static_variable_buf, ISAPI_SERVER_VAR_BUF_SIZE );
- }
- php_register_variable( "SSL_CLIENT_DN", static_cons_buf, track_vars_array TSRMLS_CC );
-
- strcpy( static_cons_buf, "/C=" );
- variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
- if( lpECB->GetServerVariable( lpECB->ConnID, "SSL_CLIENT_I_C", static_variable_buf, &variable_len ) && static_variable_buf[0] ) {
- strlcat( static_cons_buf, static_variable_buf, ISAPI_SERVER_VAR_BUF_SIZE );
- }
- strlcat( static_cons_buf, "/ST=", ISAPI_SERVER_VAR_BUF_SIZE);
- variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
- if( lpECB->GetServerVariable( lpECB->ConnID, "SSL_CLIENT_I_ST", static_variable_buf, &variable_len ) && static_variable_buf[0] ) {
- strlcat( static_cons_buf, static_variable_buf, ISAPI_SERVER_VAR_BUF_SIZE );
- }
- php_register_variable( "SSL_CLIENT_I_DN", static_cons_buf, track_vars_array TSRMLS_CC );
- }
- static void sapi_isapi_register_zeus_variables(LPEXTENSION_CONTROL_BLOCK lpECB, zval *track_vars_array TSRMLS_DC)
- {
- char static_variable_buf[ISAPI_SERVER_VAR_BUF_SIZE];
- DWORD variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
- DWORD scriptname_len = ISAPI_SERVER_VAR_BUF_SIZE;
- DWORD pathinfo_len = 0;
- char *strtok_buf = NULL;
- /* Get SCRIPT_NAME, we use this to work out which bit of the URL
- * belongs in PHP's version of PATH_INFO
- */
- lpECB->GetServerVariable(lpECB->ConnID, "SCRIPT_NAME", static_variable_buf, &scriptname_len);
- /* Adjust Zeus' version of PATH_INFO, set PHP_SELF,
- * and generate REQUEST_URI
- */
- if ( lpECB->GetServerVariable(lpECB->ConnID, "PATH_INFO", static_variable_buf, &variable_len) && static_variable_buf[0] ) {
- /* PHP_SELF is just PATH_INFO */
- php_register_variable( "PHP_SELF", static_variable_buf, track_vars_array TSRMLS_CC );
- /* Chop off filename to get just the 'real' PATH_INFO' */
- pathinfo_len = variable_len - scriptname_len;
- php_register_variable( "PATH_INFO", static_variable_buf + scriptname_len - 1, track_vars_array TSRMLS_CC );
- /* append query string to give url... extra byte for '?' */
- if ( strlen(lpECB->lpszQueryString) + variable_len + 1 < ISAPI_SERVER_VAR_BUF_SIZE ) {
- /* append query string only if it is present... */
- if ( strlen(lpECB->lpszQueryString) ) {
- static_variable_buf[ variable_len - 1 ] = '?';
- strcpy( static_variable_buf + variable_len, lpECB->lpszQueryString );
- }
- php_register_variable( "URL", static_variable_buf, track_vars_array TSRMLS_CC );
- php_register_variable( "REQUEST_URI", static_variable_buf, track_vars_array TSRMLS_CC );
- }
- }
- /* Get and adjust PATH_TRANSLATED to what PHP wants */
- variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
- if ( lpECB->GetServerVariable(lpECB->ConnID, "PATH_TRANSLATED", static_variable_buf, &variable_len) && static_variable_buf[0] ) {
- static_variable_buf[ variable_len - pathinfo_len - 1 ] = '\0';
- php_register_variable( "PATH_TRANSLATED", static_variable_buf, track_vars_array TSRMLS_CC );
- }
- /* Bring in the AUTHENTICATION stuff as needed */
- variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
- if ( lpECB->GetServerVariable(lpECB->ConnID, "AUTH_USER", static_variable_buf, &variable_len) && static_variable_buf[0] ) {
- php_register_variable( "PHP_AUTH_USER", static_variable_buf, track_vars_array TSRMLS_CC );
- }
- variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
- if ( lpECB->GetServerVariable(lpECB->ConnID, "AUTH_PASSWORD", static_variable_buf, &variable_len) && static_variable_buf[0] ) {
- php_register_variable( "PHP_AUTH_PW", static_variable_buf, track_vars_array TSRMLS_CC );
- }
- variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
- if ( lpECB->GetServerVariable(lpECB->ConnID, "AUTH_TYPE", static_variable_buf, &variable_len) && static_variable_buf[0] ) {
- php_register_variable( "AUTH_TYPE", static_variable_buf, track_vars_array TSRMLS_CC );
- }
-
- /* And now, for the SSL variables (if applicable) */
- variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
- if ( lpECB->GetServerVariable(lpECB->ConnID, "CERT_COOKIE", static_variable_buf, &variable_len) && static_variable_buf[0] ) {
- sapi_isapi_register_zeus_ssl_variables( lpECB, track_vars_array TSRMLS_CC );
- }
- /* Copy some of the variables we need to meet Apache specs */
- variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
- if ( lpECB->GetServerVariable(lpECB->ConnID, "SERVER_SOFTWARE", static_variable_buf, &variable_len) && static_variable_buf[0] ) {
- php_register_variable( "SERVER_SIGNATURE", static_variable_buf, track_vars_array TSRMLS_CC );
- }
- }
- #else
- static void sapi_isapi_register_iis_variables(LPEXTENSION_CONTROL_BLOCK lpECB, zval *track_vars_array TSRMLS_DC)
- {
- char static_variable_buf[ISAPI_SERVER_VAR_BUF_SIZE];
- char path_info_buf[ISAPI_SERVER_VAR_BUF_SIZE];
- DWORD variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
- DWORD scriptname_len = ISAPI_SERVER_VAR_BUF_SIZE;
- DWORD pathinfo_len = 0;
- HSE_URL_MAPEX_INFO humi;
- /* Get SCRIPT_NAME, we use this to work out which bit of the URL
- * belongs in PHP's version of PATH_INFO. SCRIPT_NAME also becomes PHP_SELF.
- */
- lpECB->GetServerVariable(lpECB->ConnID, "SCRIPT_NAME", static_variable_buf, &scriptname_len);
- php_register_variable("SCRIPT_FILENAME", SG(request_info).path_translated, track_vars_array TSRMLS_CC);
- /* Adjust IIS' version of PATH_INFO, set PHP_SELF,
- * and generate REQUEST_URI
- * Get and adjust PATH_TRANSLATED to what PHP wants
- */
- if ( lpECB->GetServerVariable(lpECB->ConnID, "PATH_INFO", static_variable_buf, &variable_len) && static_variable_buf[0] ) {
- /* Chop off filename to get just the 'real' PATH_INFO' */
- php_register_variable( "ORIG_PATH_INFO", static_variable_buf, track_vars_array TSRMLS_CC );
- pathinfo_len = variable_len - scriptname_len;
- strncpy(path_info_buf, static_variable_buf + scriptname_len - 1, sizeof(path_info_buf)-1);
- php_register_variable( "PATH_INFO", path_info_buf, track_vars_array TSRMLS_CC );
- /* append query string to give url... extra byte for '?' */
- if ( strlen(lpECB->lpszQueryString) + variable_len + 1 < ISAPI_SERVER_VAR_BUF_SIZE ) {
- /* append query string only if it is present... */
- if ( strlen(lpECB->lpszQueryString) ) {
- static_variable_buf[ variable_len - 1 ] = '?';
- strcpy( static_variable_buf + variable_len, lpECB->lpszQueryString );
- }
- php_register_variable( "URL", static_variable_buf, track_vars_array TSRMLS_CC );
- php_register_variable( "REQUEST_URI", static_variable_buf, track_vars_array TSRMLS_CC );
- }
- variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
- if ( lpECB->GetServerVariable(lpECB->ConnID, "PATH_TRANSLATED", static_variable_buf, &variable_len) && static_variable_buf[0] ) {
- php_register_variable( "ORIG_PATH_TRANSLATED", static_variable_buf, track_vars_array TSRMLS_CC );
- }
- if (lpECB->ServerSupportFunction(lpECB->ConnID, HSE_REQ_MAP_URL_TO_PATH_EX, path_info_buf, &pathinfo_len, (LPDWORD) &humi)) {
- /* Remove trailing \ */
- if (humi.lpszPath[variable_len-2] == '\\') {
- humi.lpszPath[variable_len-2] = 0;
- }
- php_register_variable("PATH_TRANSLATED", humi.lpszPath, track_vars_array TSRMLS_CC);
- }
- }
- static_variable_buf[0] = '/';
- static_variable_buf[1] = 0;
- variable_len = 2;
- if (lpECB->ServerSupportFunction(lpECB->ConnID, HSE_REQ_MAP_URL_TO_PATH_EX, static_variable_buf, &variable_len, (LPDWORD) &humi)) {
- /* Remove trailing \ */
- if (humi.lpszPath[variable_len-2] == '\\') {
- humi.lpszPath[variable_len-2] = 0;
- }
- php_register_variable("DOCUMENT_ROOT", humi.lpszPath, track_vars_array TSRMLS_CC);
- }
- if (!SG(request_info).auth_user || !SG(request_info).auth_password ||
- !SG(request_info).auth_user[0] || !SG(request_info).auth_password[0]) {
- variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
- if (lpECB->GetServerVariable(lpECB->ConnID, "HTTP_AUTHORIZATION", static_variable_buf, &variable_len)
- && static_variable_buf[0]) {
- php_handle_auth_data(static_variable_buf TSRMLS_CC);
- }
- }
- if (SG(request_info).auth_user) {
- php_register_variable("PHP_AUTH_USER", SG(request_info).auth_user, track_vars_array TSRMLS_CC );
- }
- if (SG(request_info).auth_password) {
- php_register_variable("PHP_AUTH_PW", SG(request_info).auth_password, track_vars_array TSRMLS_CC );
- }
- }
- #endif
- static void sapi_isapi_register_server_variables2(char **server_variables, LPEXTENSION_CONTROL_BLOCK lpECB, zval *track_vars_array, char **recorded_values TSRMLS_DC)
- {
- char **p=server_variables;
- DWORD variable_len;
- char static_variable_buf[ISAPI_SERVER_VAR_BUF_SIZE];
- char *variable_buf;
- while (*p) {
- variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
- if (lpECB->GetServerVariable(lpECB->ConnID, *p, static_variable_buf, &variable_len)
- && static_variable_buf[0]) {
- php_register_variable(*p, static_variable_buf, track_vars_array TSRMLS_CC);
- if (recorded_values) {
- recorded_values[p-server_variables] = estrndup(static_variable_buf, variable_len);
- }
- } else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
- variable_buf = (char *) emalloc(variable_len+1);
- if (lpECB->GetServerVariable(lpECB->ConnID, *p, variable_buf, &variable_len)
- && variable_buf[0]) {
- php_register_variable(*p, variable_buf, track_vars_array TSRMLS_CC);
- }
- if (recorded_values) {
- recorded_values[p-server_variables] = variable_buf;
- } else {
- efree(variable_buf);
- }
- } else { /* for compatibility with Apache SAPIs */
- php_register_variable(*p, "", track_vars_array TSRMLS_CC);
- }
- p++;
- }
- }
- static void sapi_isapi_register_server_variables(zval *track_vars_array TSRMLS_DC)
- {
- DWORD variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
- char *variable;
- char *strtok_buf = NULL;
- char *isapi_special_server_variables[NUM_SPECIAL_VARS];
- LPEXTENSION_CONTROL_BLOCK lpECB;
- lpECB = (LPEXTENSION_CONTROL_BLOCK) SG(server_context);
- /* Register the special ISAPI variables */
- memset(isapi_special_server_variables, 0, sizeof(isapi_special_server_variables));
- sapi_isapi_register_server_variables2(isapi_special_server_variable_names, lpECB, track_vars_array, isapi_special_server_variables TSRMLS_CC);
- if (SG(request_info).cookie_data) {
- php_register_variable("HTTP_COOKIE", SG(request_info).cookie_data, track_vars_array TSRMLS_CC);
- }
- /* Register the standard ISAPI variables */
- sapi_isapi_register_server_variables2(isapi_server_variable_names, lpECB, track_vars_array, NULL TSRMLS_CC);
- if (isapi_special_server_variables[SPECIAL_VAR_HTTPS]
- && (atoi(isapi_special_server_variables[SPECIAL_VAR_HTTPS])
- || !strcasecmp(isapi_special_server_variables[SPECIAL_VAR_HTTPS], "on"))
- ) {
- /* Register SSL ISAPI variables */
- sapi_isapi_register_server_variables2(isapi_secure_server_variable_names, lpECB, track_vars_array, NULL TSRMLS_CC);
- }
- if (isapi_special_server_variables[SPECIAL_VAR_HTTPS]) {
- efree(isapi_special_server_variables[SPECIAL_VAR_HTTPS]);
- }
- #ifdef WITH_ZEUS
- sapi_isapi_register_zeus_variables(lpECB, track_vars_array TSRMLS_CC);
- #else
- sapi_isapi_register_iis_variables(lpECB, track_vars_array TSRMLS_CC);
- #endif
- /* PHP_SELF support */
- if (isapi_special_server_variables[SPECIAL_VAR_PHP_SELF]) {
- php_register_variable("PHP_SELF", isapi_special_server_variables[SPECIAL_VAR_PHP_SELF], track_vars_array TSRMLS_CC);
- efree(isapi_special_server_variables[SPECIAL_VAR_PHP_SELF]);
- }
- if (isapi_special_server_variables[SPECIAL_VAR_ALL_HTTP]) {
- /* Register the internal bits of ALL_HTTP */
- variable = php_strtok_r(isapi_special_server_variables[SPECIAL_VAR_ALL_HTTP], "\r\n", &strtok_buf);
- while (variable) {
- char *colon = strchr(variable, ':');
- if (colon) {
- char *value = colon+1;
- while (*value==' ') {
- value++;
- }
- *colon = 0;
- php_register_variable(variable, value, track_vars_array TSRMLS_CC);
- *colon = ':';
- }
- variable = php_strtok_r(NULL, "\r\n", &strtok_buf);
- }
- efree(isapi_special_server_variables[SPECIAL_VAR_ALL_HTTP]);
- }
- }
- static sapi_module_struct isapi_sapi_module = {
- "isapi", /* name */
- "ISAPI", /* pretty name */
-
- php_isapi_startup, /* startup */
- php_module_shutdown_wrapper, /* shutdown */
- NULL, /* activate */
- NULL, /* deactivate */
- sapi_isapi_ub_write, /* unbuffered write */
- NULL, /* flush */
- NULL, /* get uid */
- NULL, /* getenv */
- php_error, /* error handler */
- sapi_isapi_header_handler, /* header handler */
- sapi_isapi_send_headers, /* send headers handler */
- NULL, /* send header handler */
- sapi_isapi_read_post, /* read POST data */
- sapi_isapi_read_cookies, /* read Cookies */
- sapi_isapi_register_server_variables, /* register server variables */
- NULL, /* Log message */
- NULL, /* Get request time */
- NULL, /* Child terminate */
- STANDARD_SAPI_MODULE_PROPERTIES
- };
- BOOL WINAPI GetFilterVersion(PHTTP_FILTER_VERSION pFilterVersion)
- {
- bFilterLoaded = 1;
- pFilterVersion->dwFilterVersion = HTTP_FILTER_REVISION;
- strcpy(pFilterVersion->lpszFilterDesc, isapi_sapi_module.pretty_name);
- pFilterVersion->dwFlags= (SF_NOTIFY_AUTHENTICATION | SF_NOTIFY_PREPROC_HEADERS);
- return TRUE;
- }
- DWORD WINAPI HttpFilterProc(PHTTP_FILTER_CONTEXT pfc, DWORD notificationType, LPVOID pvNotification)
- {
- TSRMLS_FETCH();
- switch (notificationType) {
- case SF_NOTIFY_PREPROC_HEADERS:
- SG(request_info).auth_user = NULL;
- SG(request_info).auth_password = NULL;
- SG(request_info).auth_digest = NULL;
- break;
- case SF_NOTIFY_AUTHENTICATION: {
- char *auth_user = ((HTTP_FILTER_AUTHENT *) pvNotification)->pszUser;
- char *auth_password = ((HTTP_FILTER_AUTHENT *) pvNotification)->pszPassword;
- if (auth_user && auth_user[0]) {
- SG(request_info).auth_user = estrdup(auth_user);
- }
- if (auth_password && auth_password[0]) {
- SG(request_info).auth_password = estrdup(auth_password);
- }
- return SF_STATUS_REQ_HANDLED_NOTIFICATION;
- }
- break;
- }
- return SF_STATUS_REQ_NEXT_NOTIFICATION;
- }
- static void init_request_info(LPEXTENSION_CONTROL_BLOCK lpECB TSRMLS_DC)
- {
- DWORD variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
- char static_variable_buf[ISAPI_SERVER_VAR_BUF_SIZE];
- #ifndef WITH_ZEUS
- HSE_URL_MAPEX_INFO humi;
- #endif
- SG(request_info).request_method = lpECB->lpszMethod;
- SG(request_info).query_string = lpECB->lpszQueryString;
- SG(request_info).request_uri = lpECB->lpszPathInfo;
- SG(request_info).content_type = lpECB->lpszContentType;
- SG(request_info).content_length = lpECB->cbTotalBytes;
- SG(sapi_headers).http_response_code = 200; /* I think dwHttpStatusCode is invalid at this stage -RL */
- if (!bFilterLoaded) { /* we don't have valid ISAPI Filter information */
- SG(request_info).auth_user = SG(request_info).auth_password = SG(request_info).auth_digest = NULL;
- }
- #ifdef WITH_ZEUS
- /* PATH_TRANSLATED can contain extra PATH_INFO stuff after the
- * file being loaded, so we must use SCRIPT_FILENAME instead
- */
- if(lpECB->GetServerVariable(lpECB->ConnID, "SCRIPT_FILENAME", static_variable_buf, &variable_len)) {
- SG(request_info).path_translated = estrdup(static_variable_buf);
- } else
- #else
- /* happily, IIS gives us SCRIPT_NAME which is correct (without PATH_INFO stuff)
- so we can just map that to the physical path and we have our filename */
- lpECB->GetServerVariable(lpECB->ConnID, "SCRIPT_NAME", static_variable_buf, &variable_len);
- if (lpECB->ServerSupportFunction(lpECB->ConnID, HSE_REQ_MAP_URL_TO_PATH_EX, static_variable_buf, &variable_len, (LPDWORD) &humi)) {
- SG(request_info).path_translated = estrdup(humi.lpszPath);
- } else
- #endif
- /* if mapping fails, default to what the server tells us */
- SG(request_info).path_translated = estrdup(lpECB->lpszPathTranslated);
- /* some server configurations allow '..' to slip through in the
- translated path. We'll just refuse to handle such a path. */
- if (strstr(SG(request_info).path_translated,"..")) {
- SG(sapi_headers).http_response_code = 404;
- efree(SG(request_info).path_translated);
- SG(request_info).path_translated = NULL;
- }
- }
- static void php_isapi_report_exception(char *message, int message_len TSRMLS_DC)
- {
- if (!SG(headers_sent)) {
- HSE_SEND_HEADER_EX_INFO header_info;
- LPEXTENSION_CONTROL_BLOCK lpECB = (LPEXTENSION_CONTROL_BLOCK) SG(server_context);
- header_info.pszStatus = "500 Internal Server Error";
- header_info.cchStatus = strlen(header_info.pszStatus);
- header_info.pszHeader = "Content-Type: text/html\r\n\r\n";
- header_info.cchHeader = strlen(header_info.pszHeader);
- lpECB->dwHttpStatusCode = 500;
- lpECB->ServerSupportFunction(lpECB->ConnID, HSE_REQ_SEND_RESPONSE_HEADER_EX, &header_info, NULL, NULL);
- SG(headers_sent)=1;
- }
- sapi_isapi_ub_write(message, message_len TSRMLS_CC);
- }
- BOOL WINAPI GetExtensionVersion(HSE_VERSION_INFO *pVer)
- {
- pVer->dwExtensionVersion = HSE_VERSION;
- #ifdef WITH_ZEUS
- strncpy( pVer->lpszExtensionDesc, isapi_sapi_module.name, HSE_MAX_EXT_DLL_NAME_LEN);
- #else
- lstrcpyn(pVer->lpszExtensionDesc, isapi_sapi_module.name, HSE_MAX_EXT_DLL_NAME_LEN);
- #endif
- return TRUE;
- }
- static void my_endthread()
- {
- #ifdef PHP_WIN32
- if (bTerminateThreadsOnError) {
- _endthread();
- }
- #endif
- }
- #ifdef PHP_WIN32
- /* ep is accessible only in the context of the __except expression,
- * so we have to call this function to obtain it.
- */
- BOOL exceptionhandler(LPEXCEPTION_POINTERS *e, LPEXCEPTION_POINTERS ep)
- {
- *e=ep;
- return TRUE;
- }
- #endif
- DWORD WINAPI HttpExtensionProc(LPEXTENSION_CONTROL_BLOCK lpECB)
- {
- zend_file_handle file_handle;
- zend_bool stack_overflown=0;
- int retval = FAILURE;
- #ifdef PHP_ENABLE_SEH
- LPEXCEPTION_POINTERS e;
- #endif
- TSRMLS_FETCH();
- zend_first_try {
- #ifdef PHP_ENABLE_SEH
- __try {
- #endif
- init_request_info(lpECB TSRMLS_CC);
- SG(server_context) = lpECB;
- php_request_startup(TSRMLS_C);
- file_handle.filename = SG(request_info).path_translated;
- file_handle.free_filename = 0;
- file_handle.type = ZEND_HANDLE_FILENAME;
- file_handle.opened_path = NULL;
- /* open the script here so we can 404 if it fails */
- if (file_handle.filename)
- retval = php_fopen_primary_script(&file_handle TSRMLS_CC);
- if (!file_handle.filename || retval == FAILURE) {
- SG(sapi_headers).http_response_code = 404;
- PUTS("No input file specified.\n");
- } else {
- php_execute_script(&file_handle TSRMLS_CC);
- }
- if (SG(request_info).cookie_data) {
- efree(SG(request_info).cookie_data);
- }
- if (SG(request_info).path_translated)
- efree(SG(request_info).path_translated);
- #ifdef PHP_ENABLE_SEH
- } __except(exceptionhandler(&e, GetExceptionInformation())) {
- char buf[1024];
- if (_exception_code()==EXCEPTION_STACK_OVERFLOW) {
- LPBYTE lpPage;
- static SYSTEM_INFO si;
- static MEMORY_BASIC_INFORMATION mi;
- static DWORD dwOldProtect;
- GetSystemInfo(&si);
- /* Get page ESP is pointing to */
- _asm mov lpPage, esp;
- /* Get stack allocation base */
- VirtualQuery(lpPage, &mi, sizeof(mi));
- /* Go to the page below the current page */
- lpPage = (LPBYTE) (mi.BaseAddress) - si.dwPageSize;
- /* Free pages below current page */
- if (!VirtualFree(mi.AllocationBase, (LPBYTE)lpPage - (LPBYTE) mi.AllocationBase, MEM_DECOMMIT)) {
- _endthread();
- }
- /* Restore the guard page */
- if (!VirtualProtect(lpPage, si.dwPageSize, PAGE_GUARD | PAGE_READWRITE, &dwOldProtect)) {
- _endthread();
- }
- CG(unclean_shutdown)=1;
- _snprintf(buf, sizeof(buf)-1,"PHP has encountered a Stack overflow");
- php_isapi_report_exception(buf, strlen(buf) TSRMLS_CC);
- } else if (_exception_code()==EXCEPTION_ACCESS_VIOLATION) {
- _snprintf(buf, sizeof(buf)-1,"PHP has encountered an Access Violation at %p", e->ExceptionRecord->ExceptionAddress);
- php_isapi_report_exception(buf, strlen(buf) TSRMLS_CC);
- my_endthread();
- } else {
- _snprintf(buf, sizeof(buf)-1,"PHP has encountered an Unhandled Exception Code %d at %p", e->ExceptionRecord->ExceptionCode , e->ExceptionRecord->ExceptionAddress);
- php_isapi_report_exception(buf, strlen(buf) TSRMLS_CC);
- my_endthread();
- }
- }
- #endif
- #ifdef PHP_ENABLE_SEH
- __try {
- php_request_shutdown(NULL);
- } __except(EXCEPTION_EXECUTE_HANDLER) {
- my_endthread();
- }
- #else
- php_request_shutdown(NULL);
- #endif
- } zend_catch {
- zend_try {
- php_request_shutdown(NULL);
- } zend_end_try();
- return HSE_STATUS_ERROR;
- } zend_end_try();
- return HSE_STATUS_SUCCESS;
- }
- __declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
- {
- switch (fdwReason) {
- case DLL_PROCESS_ATTACH:
- #ifdef WITH_ZEUS
- tsrm_startup(128, 1, TSRM_ERROR_LEVEL_CORE, "TSRM.log");
- #else
- tsrm_startup(128, 1, TSRM_ERROR_LEVEL_CORE, "C:\\TSRM.log");
- #endif
- sapi_startup(&isapi_sapi_module);
- if (isapi_sapi_module.startup) {
- isapi_sapi_module.startup(&sapi_module);
- }
- break;
- case DLL_THREAD_ATTACH:
- break;
- case DLL_THREAD_DETACH:
- ts_free_thread();
- break;
- case DLL_PROCESS_DETACH:
- if (isapi_sapi_module.shutdown) {
- isapi_sapi_module.shutdown(&sapi_module);
- }
- sapi_shutdown();
- tsrm_shutdown();
- break;
- }
- return TRUE;
- }
- /*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- */
|