Annotation of embedaddon/php/sapi/webjames/webjames.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:    | 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>