Annotation of embedaddon/php/sapi/pi3web/pi3web_sapi.c, revision 1.1
1.1 ! misho 1: /*
! 2: +----------------------------------------------------------------------+
! 3: | PHP Version 5 |
! 4: +----------------------------------------------------------------------+
! 5: | Copyright (c) 1997-2012 The PHP Group |
! 6: +----------------------------------------------------------------------+
! 7: | This source file is subject to version 3.01 of the PHP license, |
! 8: | that is bundled with this package in the file LICENSE, and is |
! 9: | available through the world-wide-web at the following url: |
! 10: | http://www.php.net/license/3_01.txt |
! 11: | If you did not receive a copy of the PHP license and are unable to |
! 12: | obtain it through the world-wide-web, please send a note to |
! 13: | license@php.net so we can mail you a copy immediately. |
! 14: +----------------------------------------------------------------------+
! 15: | Pi3Web version 2.0 |
! 16: +----------------------------------------------------------------------+
! 17: | This file is committed by the Pi3 development group. |
! 18: | (pi3web.sourceforge.net) |
! 19: | |
! 20: | Author: Holger Zimmermann (zimpel@users.sourceforge.net) |
! 21: +----------------------------------------------------------------------+
! 22: */
! 23:
! 24: /* $Id: pi3web_sapi.c 321634 2012-01-01 13:15:04Z felipe $ */
! 25:
! 26: #define ZEND_INCLUDE_FULL_WINDOWS_HEADERS
! 27:
! 28: #include "php.h"
! 29: #include "php_main.h"
! 30: #include "php_variables.h"
! 31: #include "SAPI.h"
! 32: #include "php_globals.h"
! 33: #include "ext/standard/info.h"
! 34: #include "zend_highlight.h"
! 35: #include "zend_indent.h"
! 36: #include "zend_alloc.h"
! 37: #include "ext/standard/basic_functions.h"
! 38: #include "TSRM/TSRM.h"
! 39: #include "PiAPI.h"
! 40: #include "Pi3API.h"
! 41:
! 42: #include "pi3web_sapi.h"
! 43:
! 44: #define PI3WEB_SERVER_VAR_BUF_SIZE 1024
! 45:
! 46: int IWasLoaded=0;
! 47:
! 48:
! 49: static void php_info_pi3web(ZEND_MODULE_INFO_FUNC_ARGS)
! 50: {
! 51: char variable_buf[PI3WEB_SERVER_VAR_BUF_SIZE];
! 52: DWORD variable_len;
! 53: LPCONTROL_BLOCK lpCB = (LPCONTROL_BLOCK) SG(server_context);
! 54: PIDB *pDB = (PIDB *)lpCB->GetVariableNames(lpCB->ConnID);
! 55: PIDBIterator *pIter = PIDB_getIterator( pDB, PIDBTYPE_STRING, 0, 0 );
! 56:
! 57: PUTS("<table border=0 cellpadding=3 cellspacing=1 width=600 align=center>\n");
! 58: PUTS("<tr><th colspan=2 bgcolor=\"" PHP_HEADER_COLOR "\">Pi3Web Server Information</th></tr>\n");
! 59: php_info_print_table_header(2, "Information Field", "Value");
! 60: php_info_print_table_row(2, "Pi3Web SAPI module version", "$Id: pi3web_sapi.c 321634 2012-01-01 13:15:04Z felipe $");
! 61: php_info_print_table_row(2, "Server Name Stamp", HTTPCore_getServerStamp());
! 62: snprintf(variable_buf, 511, "%d", HTTPCore_debugEnabled());
! 63: php_info_print_table_row(2, "Debug Enabled", variable_buf);
! 64: PIPlatform_getCurrentDirectory( variable_buf, PI3WEB_SERVER_VAR_BUF_SIZE);
! 65: php_info_print_table_row(2, "Current Path", variable_buf);
! 66: if (lpCB->GetServerVariable(lpCB->ConnID, "SERVER_NAME", variable_buf, &variable_len)
! 67: && variable_buf[0]) {
! 68: php_info_print_table_row(2, "Main Virtual Hostname", variable_buf);
! 69: };
! 70: snprintf(variable_buf, 511, "%d", PIPlatform_getProcessId());
! 71: php_info_print_table_row(2, "Server PID", variable_buf);
! 72: php_info_print_table_row(2, "Server Platform", PIPlatform_getDescription());
! 73:
! 74: PUTS("</table><br />");
! 75:
! 76: PUTS("<table border=0 cellpadding=3 cellspacing=1 width=600 align=center>\n");
! 77: PUTS("<tr><th colspan=2 bgcolor=\"" PHP_HEADER_COLOR "\">HTTP Request Information</th></tr>\n");
! 78: php_info_print_table_row(2, "HTTP Request Line", lpCB->lpszReq);
! 79: PUTS("<tr><th colspan=2 bgcolor=\"" PHP_HEADER_COLOR "\">HTTP Headers</th></tr>\n");
! 80: php_info_print_table_header(2, "Server Variable", "Value");
! 81:
! 82: /* --- loop over all registered server variables --- */
! 83: for(; pIter && PIDBIterator_atValidElement( pIter ); PIDBIterator_next( pIter ) )
! 84: {
! 85: PCHAR pKey;
! 86: PIDBIterator_current( pIter, &pKey );
! 87: if ( !pKey ) { /* sanity */ continue; };
! 88:
! 89: variable_len = PI3WEB_SERVER_VAR_BUF_SIZE;
! 90: if (lpCB->GetServerVariable(lpCB->ConnID, pKey, variable_buf, &variable_len)
! 91: && variable_buf[0]) {
! 92: php_info_print_table_row(2, pKey, variable_buf);
! 93: } else if (PIPlatform_getLastError() == PIAPI_EINVAL) {
! 94: char *tmp_variable_buf;
! 95:
! 96: tmp_variable_buf = (char *) emalloc(variable_len);
! 97: if (lpCB->GetServerVariable(lpCB->ConnID, pKey, tmp_variable_buf, &variable_len)
! 98: && variable_buf[0]) {
! 99: php_info_print_table_row(2, pKey, tmp_variable_buf);
! 100: }
! 101: efree(tmp_variable_buf);
! 102: }
! 103: }
! 104:
! 105: PUTS("</table>");
! 106: }
! 107:
! 108:
! 109: static zend_module_entry php_pi3web_module = {
! 110: STANDARD_MODULE_HEADER,
! 111: "PI3WEB",
! 112: NULL,
! 113: NULL,
! 114: NULL,
! 115: NULL,
! 116: NULL,
! 117: php_info_pi3web,
! 118: NULL,
! 119: STANDARD_MODULE_PROPERTIES
! 120: };
! 121:
! 122:
! 123: static int zend_pi3web_ub_write(const char *str, uint str_length TSRMLS_DC)
! 124: {
! 125: DWORD num_bytes = str_length;
! 126: LPCONTROL_BLOCK cb;
! 127:
! 128: cb = (LPCONTROL_BLOCK) SG(server_context);
! 129:
! 130: if ( !IWasLoaded ) return 0;
! 131: cb->WriteClient(cb->ConnID, (char *) str, &num_bytes, 0 );
! 132:
! 133: if (num_bytes != str_length)
! 134: php_handle_aborted_connection();
! 135: return num_bytes;
! 136: }
! 137:
! 138:
! 139: static int sapi_pi3web_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC)
! 140: {
! 141: return SAPI_HEADER_ADD;
! 142: }
! 143:
! 144:
! 145: static void accumulate_header_length(sapi_header_struct *sapi_header, uint *total_length TSRMLS_DC)
! 146: {
! 147: *total_length += sapi_header->header_len+2;
! 148: }
! 149:
! 150:
! 151: static void concat_header(sapi_header_struct *sapi_header, char **combined_headers_ptr TSRMLS_DC)
! 152: {
! 153: memcpy(*combined_headers_ptr, sapi_header->header, sapi_header->header_len);
! 154: *combined_headers_ptr += sapi_header->header_len;
! 155: **combined_headers_ptr = '\r';
! 156: (*combined_headers_ptr)++;
! 157: **combined_headers_ptr = '\n';
! 158: (*combined_headers_ptr)++;
! 159: }
! 160:
! 161:
! 162: static int sapi_pi3web_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
! 163: {
! 164: uint total_length = 2; /* account for the trailing \r\n */
! 165: char *combined_headers, *combined_headers_ptr;
! 166: LPCONTROL_BLOCK lpCB = (LPCONTROL_BLOCK) SG(server_context);
! 167: sapi_header_struct default_content_type;
! 168:
! 169: if ( !IWasLoaded ) return SAPI_HEADER_SENT_SUCCESSFULLY;
! 170:
! 171:
! 172: if (SG(sapi_headers).send_default_content_type) {
! 173: sapi_get_default_content_type_header(&default_content_type TSRMLS_CC);
! 174: accumulate_header_length(&default_content_type, (void *) &total_length TSRMLS_CC);
! 175: }
! 176: zend_llist_apply_with_argument(&SG(sapi_headers).headers, (llist_apply_with_arg_func_t) accumulate_header_length, (void *) &total_length TSRMLS_CC);
! 177:
! 178: /* Generate headers */
! 179: combined_headers = (char *) emalloc(total_length+1);
! 180: combined_headers_ptr = combined_headers;
! 181: if (SG(sapi_headers).send_default_content_type) {
! 182: concat_header(&default_content_type, (void *) &combined_headers_ptr TSRMLS_CC);
! 183: sapi_free_header(&default_content_type); /* we no longer need it */
! 184: }
! 185: zend_llist_apply_with_argument(&SG(sapi_headers).headers, (llist_apply_with_arg_func_t) concat_header, (void *) &combined_headers_ptr TSRMLS_CC);
! 186: *combined_headers_ptr++ = '\r';
! 187: *combined_headers_ptr++ = '\n';
! 188: *combined_headers_ptr = 0;
! 189:
! 190: lpCB->dwHttpStatusCode = SG(sapi_headers).http_response_code;
! 191: lpCB->SendHeaderFunction(lpCB->ConnID, &total_length, (LPDWORD) combined_headers);
! 192:
! 193: efree(combined_headers);
! 194: if (SG(sapi_headers).http_status_line) {
! 195: efree(SG(sapi_headers).http_status_line);
! 196: SG(sapi_headers).http_status_line = 0;
! 197: }
! 198: return SAPI_HEADER_SENT_SUCCESSFULLY;
! 199: }
! 200:
! 201:
! 202: static int php_pi3web_startup(sapi_module_struct *sapi_module)
! 203: {
! 204: if (php_module_startup(sapi_module, &php_pi3web_module, 1)==FAILURE) {
! 205: return FAILURE;
! 206: } else {
! 207: return SUCCESS;
! 208: }
! 209: }
! 210:
! 211:
! 212: static int sapi_pi3web_read_post(char *buffer, uint count_bytes TSRMLS_DC)
! 213: {
! 214: LPCONTROL_BLOCK lpCB = (LPCONTROL_BLOCK) SG(server_context);
! 215: DWORD read_from_buf=0;
! 216: DWORD read_from_input=0;
! 217: DWORD total_read=0;
! 218:
! 219: if ((DWORD)SG(read_post_bytes) < lpCB->cbAvailable) {
! 220: read_from_buf = MIN(lpCB->cbAvailable-SG(read_post_bytes), count_bytes);
! 221: memcpy(buffer, lpCB->lpbData+SG(read_post_bytes), read_from_buf);
! 222: total_read += read_from_buf;
! 223: }
! 224: if (read_from_buf<count_bytes
! 225: && (SG(read_post_bytes)+read_from_buf) < lpCB->cbTotalBytes) {
! 226: DWORD cbRead=0, cbSize;
! 227:
! 228: read_from_input = MIN(count_bytes-read_from_buf, lpCB->cbTotalBytes-SG(read_post_bytes)-read_from_buf);
! 229: while (cbRead < read_from_input) {
! 230: cbSize = read_from_input - cbRead;
! 231: if (!lpCB->ReadClient(lpCB->ConnID, buffer+read_from_buf+cbRead, &cbSize) || cbSize==0) {
! 232: break;
! 233: }
! 234: cbRead += cbSize;
! 235: }
! 236: total_read += cbRead;
! 237: }
! 238:
! 239: /* removed after re-testing POST with Pi3Web 2.0.2 */
! 240: /* SG(read_post_bytes) += total_read; */
! 241: return total_read;
! 242: }
! 243:
! 244:
! 245: static char *sapi_pi3web_read_cookies(TSRMLS_D)
! 246: {
! 247: LPCONTROL_BLOCK lpCB = (LPCONTROL_BLOCK) SG(server_context);
! 248: char variable_buf[PI3WEB_SERVER_VAR_BUF_SIZE];
! 249: DWORD variable_len = PI3WEB_SERVER_VAR_BUF_SIZE;
! 250:
! 251: if (lpCB->GetServerVariable(lpCB->ConnID, "HTTP_COOKIE", variable_buf, &variable_len)) {
! 252: return estrndup(variable_buf, variable_len);
! 253: } else if (PIPlatform_getLastError()==PIAPI_EINVAL) {
! 254: char *tmp_variable_buf = (char *) emalloc(variable_len+1);
! 255:
! 256: if (lpCB->GetServerVariable(lpCB->ConnID, "HTTP_COOKIE", tmp_variable_buf, &variable_len)) {
! 257: tmp_variable_buf[variable_len] = 0;
! 258: return tmp_variable_buf;
! 259: } else {
! 260: efree(tmp_variable_buf);
! 261: }
! 262: }
! 263: return NULL;
! 264: }
! 265:
! 266: static void init_request_info(LPCONTROL_BLOCK lpCB TSRMLS_DC)
! 267: {
! 268: SG(server_context) = lpCB;
! 269: SG(request_info).request_method = lpCB->lpszMethod;
! 270: SG(request_info).query_string = lpCB->lpszQueryString;
! 271: SG(request_info).path_translated = lpCB->lpszPathTranslated;
! 272: SG(request_info).request_uri = lpCB->lpszUri;
! 273: SG(request_info).content_type = lpCB->lpszContentType;
! 274: SG(request_info).content_length = lpCB->cbTotalBytes;
! 275: SG(request_info).auth_user = (lpCB->lpszUser) ? (char *)estrdup((const char *)(lpCB->lpszUser)) : 0;
! 276: SG(request_info).auth_password = (lpCB->lpszPassword) ? (char *)estrdup((const char *)(lpCB->lpszPassword)) : 0;
! 277: SG(sapi_headers).http_response_code = 200;
! 278: }
! 279:
! 280: static void sapi_pi3web_register_variables(zval *track_vars_array TSRMLS_DC)
! 281: {
! 282: char static_variable_buf[PI3WEB_SERVER_VAR_BUF_SIZE];
! 283: char *variable_buf;
! 284: DWORD variable_len = PI3WEB_SERVER_VAR_BUF_SIZE;
! 285: LPCONTROL_BLOCK lpCB = (LPCONTROL_BLOCK) SG(server_context);
! 286: PIDB *pDB = (PIDB *)lpCB->GetVariableNames(lpCB->ConnID);
! 287: PIDBIterator *pIter = PIDB_getIterator( pDB, PIDBTYPE_STRING, 0, 0 );
! 288:
! 289: /* --- loop over all registered server variables --- */
! 290: for(; pIter && PIDBIterator_atValidElement( pIter ); PIDBIterator_next( pIter ) )
! 291: {
! 292: PCHAR pKey;
! 293: PIDBIterator_current( pIter, &pKey );
! 294: if ( !pKey ) { /* sanity */ continue; };
! 295:
! 296: variable_len = PI3WEB_SERVER_VAR_BUF_SIZE;
! 297: if (lpCB->GetServerVariable(lpCB->ConnID, pKey, static_variable_buf, &variable_len)
! 298: && (variable_len > 1)) {
! 299: php_register_variable(pKey, static_variable_buf, track_vars_array TSRMLS_CC);
! 300: } else if (PIPlatform_getLastError()==PIAPI_EINVAL) {
! 301: variable_buf = (char *) emalloc(variable_len);
! 302: if (lpCB->GetServerVariable(lpCB->ConnID, pKey, variable_buf, &variable_len)) {
! 303: php_register_variable(pKey, variable_buf, track_vars_array TSRMLS_CC);
! 304: }
! 305: efree(variable_buf);
! 306: }
! 307:
! 308: }
! 309:
! 310:
! 311: /* PHP_SELF support */
! 312: variable_len = PI3WEB_SERVER_VAR_BUF_SIZE;
! 313: if (lpCB->GetServerVariable(lpCB->ConnID, "SCRIPT_NAME", static_variable_buf, &variable_len)
! 314: && (variable_len > 1)) {
! 315: php_register_variable("PHP_SELF", static_variable_buf, track_vars_array TSRMLS_CC);
! 316: }
! 317: }
! 318:
! 319: static sapi_module_struct pi3web_sapi_module = {
! 320: "pi3web", /* name */
! 321: "PI3WEB", /* pretty name */
! 322:
! 323: php_pi3web_startup, /* startup */
! 324: php_module_shutdown_wrapper, /* shutdown */
! 325: NULL, /* activate */
! 326: NULL, /* deactivate */
! 327: zend_pi3web_ub_write, /* unbuffered write */
! 328: NULL, /* flush */
! 329: NULL, /* get uid */
! 330: NULL, /* getenv */
! 331: php_error, /* error handler */
! 332: sapi_pi3web_header_handler, /* header handler */
! 333: sapi_pi3web_send_headers, /* send headers handler */
! 334: NULL, /* send header handler */
! 335: sapi_pi3web_read_post, /* read POST data */
! 336: sapi_pi3web_read_cookies, /* read Cookies */
! 337: sapi_pi3web_register_variables, /* register server variables */
! 338: NULL, /* Log message */
! 339: NULL, /* Get request time */
! 340: NULL, /* Child terminate */
! 341:
! 342: STANDARD_SAPI_MODULE_PROPERTIES
! 343: };
! 344:
! 345: MODULE_API DWORD PHP5_wrapper(LPCONTROL_BLOCK lpCB)
! 346: {
! 347: zend_file_handle file_handle = {0};
! 348: int iRet = PIAPI_COMPLETED;
! 349: TSRMLS_FETCH();
! 350:
! 351: zend_first_try {
! 352: file_handle.filename = lpCB->lpszFileName;
! 353: file_handle.free_filename = 0;
! 354: file_handle.type = ZEND_HANDLE_FILENAME;
! 355: file_handle.opened_path = NULL;
! 356:
! 357: init_request_info(lpCB TSRMLS_CC);
! 358: php_request_startup(TSRMLS_C);
! 359:
! 360: switch ( lpCB->dwBehavior ) {
! 361: case PHP_MODE_STANDARD:
! 362: iRet = ( php_execute_script( &file_handle TSRMLS_CC ) ) ?
! 363: PIAPI_COMPLETED : PIAPI_ERROR;
! 364: break;
! 365: case PHP_MODE_HIGHLIGHT: {
! 366: zend_syntax_highlighter_ini syntax_highlighter_ini;
! 367: if ( open_file_for_scanning( &file_handle TSRMLS_CC ) == SUCCESS )
! 368: {
! 369: php_get_highlight_struct( &syntax_highlighter_ini );
! 370: zend_highlight( &syntax_highlighter_ini TSRMLS_CC );
! 371: }
! 372: else
! 373: {
! 374: iRet = PIAPI_ERROR;
! 375: };
! 376: };
! 377: break;
! 378: case PHP_MODE_INDENT: {
! 379: sapi_header_line ctr = {0};
! 380:
! 381: ctr.line = "Content-Type: text/plain";
! 382: ctr.line_len = strlen(ctr.line);
! 383:
! 384: sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC);
! 385: }
! 386: if ( open_file_for_scanning( &file_handle TSRMLS_CC ) == SUCCESS )
! 387: {
! 388: zend_indent();
! 389: }
! 390: else
! 391: {
! 392: iRet = PIAPI_ERROR;
! 393: };
! 394: break;
! 395: case PHP_MODE_LINT:
! 396: iRet = (php_lint_script(&file_handle TSRMLS_CC) == SUCCESS) ?
! 397: PIAPI_COMPLETED : PIAPI_ERROR;
! 398: break;
! 399: default:
! 400: iRet = PIAPI_ERROR;;
! 401: }
! 402:
! 403: if (SG(request_info).cookie_data) {
! 404: efree(SG(request_info).cookie_data);
! 405: };
! 406:
! 407: php_request_shutdown(NULL);
! 408: } zend_catch {
! 409: iRet = PIAPI_ERROR;
! 410: } zend_end_try();
! 411: return iRet;
! 412: }
! 413:
! 414: MODULE_API BOOL PHP5_startup() {
! 415: tsrm_startup(1, 1, 0, NULL);
! 416: sapi_startup(&pi3web_sapi_module);
! 417: if (pi3web_sapi_module.startup) {
! 418: pi3web_sapi_module.startup(&pi3web_sapi_module);
! 419: };
! 420: IWasLoaded = 1;
! 421: return IWasLoaded;
! 422: };
! 423:
! 424: MODULE_API BOOL PHP5_shutdown() {
! 425: if (pi3web_sapi_module.shutdown) {
! 426: pi3web_sapi_module.shutdown(&pi3web_sapi_module);
! 427: };
! 428: sapi_shutdown();
! 429: tsrm_shutdown();
! 430: IWasLoaded = 0;
! 431: return !IWasLoaded;
! 432: };
! 433:
! 434: /*
! 435: * Local variables:
! 436: * tab-width: 4
! 437: * c-basic-offset: 4
! 438: * End:
! 439: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>