Return to pi3web_sapi.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / sapi / pi3web |
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: */