Annotation of embedaddon/php/sapi/pi3web/pi3web_sapi.c, revision 1.1.1.2

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: 
1.1.1.2 ! misho      24: /* $Id$ */
1.1       misho      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");
1.1.1.2 ! misho      60:        php_info_print_table_row(2, "Pi3Web SAPI module version", "$Id$");
1.1       misho      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>