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>