Annotation of embedaddon/php/sapi/webjames/webjames.c, revision 1.1.1.2

1.1       misho       1: /*
                      2:    +----------------------------------------------------------------------+
                      3:    | PHP Version 5                                                        |
                      4:    +----------------------------------------------------------------------+
1.1.1.2 ! misho       5:    | Copyright (c) 1997-2013 The PHP Group                                |
1.1       misho       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:    | Author: Alex Waugh <alex@alexwaugh.com>                              |
                     16:    +----------------------------------------------------------------------+
                     17: */
                     18: 
                     19: 
                     20: #include "php.h"
                     21: #include "SAPI.h"
                     22: #include "php_main.h"
                     23: #include "php_variables.h"
                     24: 
                     25: #define WEBJAMES_PHP_ONLY
                     26: #include "php_webjames.h"
                     27: 
                     28: #include <unixlib/local.h>
                     29: 
                     30: #define WEBJAMES_SAPI_VERSION "1.0.2"
                     31: 
                     32: typedef struct {
                     33:        struct connection *conn; /*structure holding all the details of the current request*/
                     34:        int bodyread; /*amount of POST body read*/
                     35:        closefn oldclose; /*function to call to close the connection*/
                     36: } php_webjames_globals;
                     37: 
                     38: static php_webjames_globals webjames_globals;
                     39: 
                     40: #define WG(v) (webjames_globals.v)
                     41: 
                     42: static int sapi_webjames_ub_write(const char *str, uint str_length TSRMLS_DC)
                     43: /*unbuffered write - send data straight out to socket*/
                     44: {
                     45:        int totalbytes = 0;
                     46: 
                     47:        do {
                     48:                int bytes;
                     49:                bytes = webjames_writebuffer(WG(conn),str,str_length);
                     50:                if (bytes<0) {
                     51:                        PG(connection_status) = PHP_CONNECTION_ABORTED;
                     52:                        if (!PG(ignore_user_abort)) {
                     53:                                zend_bailout();
                     54:                        }
                     55:                        return bytes;
                     56:                }
                     57:                str += bytes;
                     58:                str_length -= bytes;
                     59:                totalbytes += bytes;
                     60:        } while (str_length);
                     61:        return totalbytes;
                     62: }
                     63: 
                     64: static void sapi_webjames_send_header(sapi_header_struct *sapi_header, void *server_context TSRMLS_DC)
                     65: /*send an HTTP header*/
                     66: {
                     67:        char *header = sapi_header->header;
                     68:        int len = sapi_header->header_len;
                     69:        if (WG(conn)->flags.outputheaders) {
                     70:                while (sapi_header && len > 0) {
                     71:                        int bytes;
                     72:                        bytes = webjames_writebuffer(WG(conn), header, len);
                     73:                        if (bytes<0) {
                     74:                                PG(connection_status) = PHP_CONNECTION_ABORTED;
                     75:                                if (!PG(ignore_user_abort)) {
                     76:                                        zend_bailout();
                     77:                                }
                     78:                                return;
                     79:                        }
                     80:                        header += bytes;
                     81:                        len -= bytes;
                     82:                }
                     83:                webjames_writestring(WG(conn), "\r\n");
                     84:        }
                     85: }
                     86: 
                     87: static int sapi_webjames_read_post(char *buffer, uint count_bytes TSRMLS_DC)
                     88: /*read some of the post data*/
                     89: {
                     90:        if (WG(conn)->body==NULL) return 0;
                     91:        if (count_bytes+WG(bodyread)>WG(conn)->bodysize) count_bytes=WG(conn)->bodysize-WG(bodyread);
                     92:        memcpy(buffer, WG(conn)->body+WG(bodyread), count_bytes);
                     93:        WG(bodyread)+=count_bytes;
                     94:        return count_bytes;
                     95: }
                     96: 
                     97: static char *sapi_webjames_read_cookies(TSRMLS_D)
                     98: {
                     99:        return WG(conn)->cookie;
                    100: }
                    101: 
                    102: #define BUF_SIZE 512
                    103: #define ADD_STRING(name,string)\
                    104:        php_register_variable(name, string, track_vars_array TSRMLS_CC)
                    105: 
                    106: #define ADD_NUM(name,field) {\
                    107:        snprintf(buf, BUF_SIZE, "%d", WG(conn)->field);\
                    108:        php_register_variable(name, buf, track_vars_array TSRMLS_CC);\
                    109: }
                    110: 
                    111: #define ADD_FIELD(name, field) \
                    112:        if (WG(conn)->field) { \
                    113:                php_register_variable(name, WG(conn)->field, track_vars_array TSRMLS_CC); \
                    114:        }
                    115: 
                    116: static void sapi_webjames_register_variables(zval *track_vars_array TSRMLS_DC)
                    117: {
                    118:        char buf[BUF_SIZE + 1];
                    119:        char *docroot;
                    120: 
                    121:        buf[BUF_SIZE] = '\0';
                    122: 
                    123:        ADD_STRING("SERVER_SOFTWARE", configuration.server);
                    124:        ADD_STRING("SERVER_NAME", configuration.serverip);
                    125:        ADD_FIELD("SERVER_PROTOCOL", protocol);
                    126:        ADD_NUM("SERVER_PORT", port);
                    127:        ADD_STRING("SERVER_ADMIN",configuration.webmaster);
                    128:        ADD_STRING("GATEWAY_INTERFACE", "CGI/1.1");
                    129: 
                    130:        docroot = __unixify(WG(conn)->homedir,0,NULL,1024,0);
                    131:        if (docroot) ADD_STRING("DOCUMENT_ROOT", docroot);
                    132: 
                    133:        ADD_FIELD("REQUEST_METHOD", methodstr);
                    134:        ADD_FIELD("REQUEST_URI", requesturi);
                    135:        ADD_STRING("PATH_TRANSLATED", SG(request_info).path_translated);
                    136:        ADD_FIELD("SCRIPT_NAME", uri);
                    137:        ADD_FIELD("PHP_SELF", uri);
                    138:        ADD_FIELD("QUERY_STRING", args);
                    139: 
                    140:        
                    141:        snprintf(buf, BUF_SIZE, "%d.%d.%d.%d", WG(conn)->ipaddr[0], WG(conn)->ipaddr[1], WG(conn)->ipaddr[2], WG(conn)->ipaddr[3]);
                    142:        ADD_STRING("REMOTE_ADDR", buf);
                    143:        if (WG(conn)->dnsstatus == DNS_OK) ADD_FIELD("REMOTE_HOST", host);
                    144: 
                    145:        if ((WG(conn)->method == METHOD_POST) || (WG(conn)->method == METHOD_PUT)) {
                    146:                ADD_NUM("CONTENT_LENGTH", bodysize);
                    147:                ADD_FIELD("CONTENT_TYPE", type);
                    148:        }
                    149: 
                    150:        if ((WG(conn)->method == METHOD_PUT) || (WG(conn)->method == METHOD_DELETE)) ADD_FIELD("ENTITY_PATH", requesturi);
                    151: 
                    152:        if (WG(conn)->pwd) {
                    153:                ADD_STRING("AUTH_TYPE", "basic");
                    154:                ADD_FIELD("REMOTE_USER", authorization);
                    155:        }
                    156: 
                    157:        ADD_FIELD("HTTP_COOKIE", cookie);
                    158:        ADD_FIELD("HTTP_USER_AGENT", useragent);
                    159:        ADD_FIELD("HTTP_REFERER", referer);
                    160:        ADD_FIELD("HTTP_ACCEPT", accept);
                    161:        ADD_FIELD("HTTP_ACCEPT_LANGUAGE", acceptlanguage);
                    162:        ADD_FIELD("HTTP_ACCEPT_CHARSET", acceptcharset);
                    163:        ADD_FIELD("HTTP_ACCEPT_ENCODING", acceptencoding);
                    164: }
                    165: 
                    166: static void webjames_module_main(TSRMLS_D)
                    167: {
                    168:        zend_file_handle file_handle;
                    169:        FILE *fp=NULL;
                    170:        char *path;
                    171: 
                    172:        /* Convert filename to Unix format*/
                    173:        __riscosify_control|=__RISCOSIFY_STRICT_UNIX_SPECS;
                    174:        path = __unixify(WG(conn)->filename,0,NULL,1024,0);
                    175:        if (path) SG(request_info).path_translated = estrdup(path);
                    176: 
                    177:        SG(request_info).query_string = WG(conn)->args;
                    178:        SG(request_info).request_uri = WG(conn)->requesturi;
                    179:        SG(request_info).request_method = WG(conn)->methodstr;
                    180:        if (WG(conn)->method==METHOD_HEAD) {
                    181:                SG(request_info).headers_only = 1;
                    182:        } else {
                    183:                SG(request_info).headers_only = 0;
                    184:        }
                    185:        SG(sapi_headers).http_response_code = 200;
                    186:        SG(request_info).content_type = WG(conn)->type;
                    187:        SG(request_info).content_length = WG(conn)->bodysize;
                    188: 
                    189:        SG(request_info).auth_user = NULL;
                    190:        SG(request_info).auth_password = NULL;
                    191:        if (WG(conn)->authorization) {
                    192:                char *colon=strchr(WG(conn)->authorization,':');
                    193:                if (colon) {
                    194:                        SG(request_info).auth_user = emalloc(colon-WG(conn)->authorization+1);
                    195:                        if (SG(request_info).auth_user) {
                    196:                                memcpy(SG(request_info).auth_user,WG(conn)->authorization,colon-WG(conn)->authorization);
                    197:                                SG(request_info).auth_user[colon-WG(conn)->authorization]='\0';
                    198:                                SG(request_info).auth_password = estrdup(colon+1);
                    199:                        }
                    200:                }
                    201:        }
                    202: 
                    203:        /*ensure that syslog calls get logged separately from WebJames' main log */
                    204:        openlog("PHP",0,0);
                    205: 
                    206:        file_handle.type = ZEND_HANDLE_FILENAME;
                    207:        file_handle.filename = SG(request_info).path_translated;
                    208:        file_handle.free_filename = 0;
                    209:        file_handle.opened_path = NULL;
                    210: 
                    211:        if (php_request_startup(TSRMLS_C) == FAILURE) {
                    212:                return;
                    213:        }
                    214:        
                    215:        php_execute_script(&file_handle TSRMLS_CC);
                    216:        php_request_shutdown(NULL);
                    217: }
                    218: 
                    219: static void webjames_php_close(struct connection *conn, int force)
                    220: /*called by webjames if it wants to close the connection*/
                    221: {
                    222:        TSRMLS_FETCH();
                    223: 
                    224:        php_request_shutdown(NULL);
                    225:        WG(oldclose)(conn,force);
                    226: }
                    227: 
                    228: void webjames_php_request(struct connection *conn)
                    229: /*called by WebJames to start handler*/
                    230: {
                    231:        TSRMLS_FETCH();
                    232: 
                    233:        WG(conn) = conn;
                    234:        WG(bodyread) = 0;
                    235:        WG(oldclose) = conn->close;
                    236:        conn->close=webjames_php_close;
                    237: 
                    238:        webjames_module_main(TSRMLS_C);
                    239: 
                    240:        WG(oldclose)(WG(conn), 0);
                    241: }
                    242: 
                    243: static void php_info_webjames(ZEND_MODULE_INFO_FUNC_ARGS)
                    244: {
                    245:        php_info_print_table_start();
                    246:        php_info_print_table_row(2, "SAPI module version", WEBJAMES_SAPI_VERSION);
                    247:        php_info_print_table_row(2, "WebJames version", WEBJAMES_VERSION " (" WEBJAMES_DATE ")");
                    248:        php_info_print_table_end();
                    249: }
                    250: 
                    251: static zend_module_entry php_webjames_module = {
                    252: #if ZEND_MODULE_API_NO >= 20010901
                    253:     STANDARD_MODULE_HEADER,
                    254: #endif
                    255:   "WebJames",
                    256:   NULL,
                    257:   NULL,
                    258:   NULL,
                    259:   NULL,
                    260:   NULL,
                    261:   php_info_webjames,
                    262: #if ZEND_MODULE_API_NO >= 20010901
                    263:   WEBJAMES_SAPI_VERSION,          
                    264: #endif
                    265:   STANDARD_MODULE_PROPERTIES
                    266: };
                    267: 
                    268: 
                    269: static int php_webjames_startup(sapi_module_struct *sapi_module)
                    270: {
                    271:   if(php_module_startup(sapi_module, &php_webjames_module, 1) == FAILURE) {
                    272:     return FAILURE;
                    273:   } else {
                    274:     return SUCCESS;
                    275:   }
                    276: }
                    277: 
                    278: static sapi_module_struct sapi_module = {
                    279:        "webjames",                             /* name */
                    280:        "WebJames",                             /* pretty name */
                    281: 
                    282:        php_webjames_startup,                   /* startup */
                    283:        php_module_shutdown_wrapper,            /* shutdown */
                    284: 
                    285:        NULL,                                                                   /* activate */
                    286:        NULL,                                                                   /* deactivate */
                    287: 
                    288:        sapi_webjames_ub_write,                 /* unbuffered write */
                    289:        NULL,                                   /* flush */
                    290:        NULL,                                                                   /* get uid */
                    291:        NULL,                                                                   /* getenv */
                    292: 
                    293:        php_error,                              /* error handler */
                    294: 
                    295:        NULL,                                   /* header handler */
                    296:        NULL,                                                           /* send headers handler */
                    297:        sapi_webjames_send_header,              /* send header handler */
                    298:        sapi_webjames_read_post,                /* read POST data */
                    299:        sapi_webjames_read_cookies,             /* read Cookies */
                    300: 
                    301:        sapi_webjames_register_variables,       /* register server variables */
                    302:        NULL,                                                                   /* Log message */
                    303:        NULL,                                                                   /* Get request time */
                    304:        NULL,                                                                   /* Child terminate */
                    305: 
                    306:        STANDARD_SAPI_MODULE_PROPERTIES
                    307: };
                    308: 
                    309: int webjames_php_init(void)
                    310: /*called when WebJames initialises*/
                    311: {
                    312:        TSRMLS_FETCH();
                    313:        if (strcmp(configuration.webjames_h_revision,WEBJAMES_H_REVISION)!=0) {
                    314:                /*This file was compiled against a different revision of
                    315:                  webjames.h than webjames was, which could be bad news*/
                    316:                webjames_writelog(0,"PHP module is compiled for WebJames (%s) and was linked with a different version (%s)",WEBJAMES_H_REVISION,configuration.webjames_h_revision);
                    317:                return 0; /*failed to initialise*/
                    318:        }
                    319:        sapi_startup(&sapi_module);
                    320:        sapi_module.startup(&sapi_module);
                    321:        SG(server_context) = (void *) 1;
                    322:        return 1; /*initialised correctly*/
                    323: }
                    324: 
                    325: void webjames_php_shutdown(void)
                    326: /*called when WebJames is about to quit*/
                    327: {
                    328:        sapi_module.shutdown(&sapi_module);
                    329:        sapi_shutdown();
                    330: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>