Annotation of embedaddon/php/sapi/nsapi/nsapi.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: Jayakumar Muthukumarasamy <jk@kasenna.com>                   |
        !            16:    |         Uwe Schindler <uwe@thetaphi.de>                              |
        !            17:    +----------------------------------------------------------------------+
        !            18: */
        !            19: 
        !            20: /* $Id: nsapi.c 321634 2012-01-01 13:15:04Z felipe $ */
        !            21: 
        !            22: /*
        !            23:  * PHP includes
        !            24:  */
        !            25: #define NSAPI 1
        !            26: 
        !            27: #ifdef HAVE_CONFIG_H
        !            28: #include "config.h"
        !            29: #endif
        !            30: 
        !            31: #include "php.h"
        !            32: #include "php_variables.h"
        !            33: #include "ext/standard/info.h"
        !            34: #include "php_ini.h"
        !            35: #include "php_globals.h"
        !            36: #include "SAPI.h"
        !            37: #include "php_main.h"
        !            38: #include "php_version.h"
        !            39: #include "TSRM.h"
        !            40: #include "ext/standard/php_standard.h"
        !            41: #include <sys/types.h>
        !            42: #include <sys/stat.h>
        !            43: 
        !            44: #ifndef RTLD_DEFAULT
        !            45: #define RTLD_DEFAULT NULL
        !            46: #endif
        !            47: 
        !            48: /*
        !            49:  * If neither XP_UNIX not XP_WIN32 is defined use PHP_WIN32
        !            50:  */
        !            51: #if !defined(XP_UNIX) && !defined(XP_WIN32)
        !            52: #ifdef PHP_WIN32
        !            53: #define XP_WIN32
        !            54: #else
        !            55: #define XP_UNIX
        !            56: #endif
        !            57: #endif
        !            58: 
        !            59: /*
        !            60:  * The manual define of HPUX is to fix bug #46020, nsapi.h needs this to detect HPUX
        !            61:  */
        !            62: #ifdef __hpux
        !            63: #define HPUX
        !            64: #endif
        !            65:  
        !            66: /*
        !            67:  * NSAPI includes
        !            68:  */
        !            69: #include "nsapi.h"
        !            70: 
        !            71: /* fix for gcc4 visibility issue */
        !            72: #ifndef PHP_WIN32
        !            73: # undef NSAPI_PUBLIC
        !            74: # define NSAPI_PUBLIC PHPAPI
        !            75: #endif
        !            76: 
        !            77: #define NSLS_D         struct nsapi_request_context *request_context
        !            78: #define NSLS_DC                , NSLS_D
        !            79: #define NSLS_C         request_context
        !            80: #define NSLS_CC                , NSLS_C
        !            81: #define NSG(v)         (request_context->v)
        !            82: 
        !            83: /*
        !            84:  * ZTS needs to be defined for NSAPI to work
        !            85:  */
        !            86: #if !defined(ZTS)
        !            87: #error "NSAPI module needs ZTS to be defined"
        !            88: #endif
        !            89: 
        !            90: /*
        !            91:  * Structure to encapsulate the NSAPI request in SAPI
        !            92:  */
        !            93: typedef struct nsapi_request_context {
        !            94:        pblock  *pb;
        !            95:        Session *sn;
        !            96:        Request *rq;
        !            97:        int     read_post_bytes;
        !            98:        char *path_info;
        !            99:        int fixed_script; /* 0 if script is from URI, 1 if script is from "script" parameter */
        !           100:        short http_error; /* 0 in normal mode; for errors the HTTP error code */
        !           101: } nsapi_request_context;
        !           102: 
        !           103: /*
        !           104:  * Mappings between NSAPI names and environment variables. This
        !           105:  * mapping was obtained from the sample programs at the iplanet
        !           106:  * website.
        !           107:  */
        !           108: typedef struct nsapi_equiv {
        !           109:        const char *env_var;
        !           110:        const char *nsapi_eq;
        !           111: } nsapi_equiv;
        !           112: 
        !           113: static nsapi_equiv nsapi_reqpb[] = {
        !           114:        { "QUERY_STRING",               "query" },
        !           115:        { "REQUEST_LINE",               "clf-request" },
        !           116:        { "REQUEST_METHOD",             "method" },
        !           117:        { "PHP_SELF",                   "uri" },
        !           118:        { "SERVER_PROTOCOL",    "protocol" }
        !           119: };
        !           120: static size_t nsapi_reqpb_size = sizeof(nsapi_reqpb)/sizeof(nsapi_reqpb[0]);
        !           121: 
        !           122: static nsapi_equiv nsapi_vars[] = {
        !           123:        { "AUTH_TYPE",                  "auth-type" },
        !           124:        { "CLIENT_CERT",                "auth-cert" },
        !           125:        { "REMOTE_USER",                "auth-user" }
        !           126: };
        !           127: static size_t nsapi_vars_size = sizeof(nsapi_vars)/sizeof(nsapi_vars[0]);
        !           128: 
        !           129: static nsapi_equiv nsapi_client[] = {
        !           130:        { "HTTPS_KEYSIZE",              "keysize" },
        !           131:        { "HTTPS_SECRETSIZE",   "secret-keysize" },
        !           132:        { "REMOTE_ADDR",                "ip" },
        !           133:        { "REMOTE_HOST",                "ip" }
        !           134: };
        !           135: static size_t nsapi_client_size = sizeof(nsapi_client)/sizeof(nsapi_client[0]);
        !           136: 
        !           137: /* this parameters to "Service"/"Error" are NSAPI ones which should not be php.ini keys and are excluded */
        !           138: static char *nsapi_exclude_from_ini_entries[] = { "fn", "type", "method", "directive", "code", "reason", "script", "bucket", NULL };
        !           139: 
        !           140: static void nsapi_free(void *addr)
        !           141: {
        !           142:        if (addr != NULL) {
        !           143:                FREE(addr);
        !           144:        }
        !           145: }
        !           146: 
        !           147: 
        !           148: /*******************/
        !           149: /* PHP module part */
        !           150: /*******************/
        !           151: 
        !           152: PHP_MINIT_FUNCTION(nsapi);
        !           153: PHP_MSHUTDOWN_FUNCTION(nsapi);
        !           154: PHP_RINIT_FUNCTION(nsapi);
        !           155: PHP_RSHUTDOWN_FUNCTION(nsapi);
        !           156: PHP_MINFO_FUNCTION(nsapi);
        !           157: 
        !           158: PHP_FUNCTION(nsapi_virtual);
        !           159: PHP_FUNCTION(nsapi_request_headers);
        !           160: PHP_FUNCTION(nsapi_response_headers);
        !           161: 
        !           162: ZEND_BEGIN_MODULE_GLOBALS(nsapi)
        !           163:        long read_timeout;
        !           164: ZEND_END_MODULE_GLOBALS(nsapi)
        !           165: 
        !           166: ZEND_DECLARE_MODULE_GLOBALS(nsapi)
        !           167: 
        !           168: #define NSAPI_G(v) TSRMG(nsapi_globals_id, zend_nsapi_globals *, v)
        !           169: 
        !           170: 
        !           171: /* {{{ arginfo */
        !           172: ZEND_BEGIN_ARG_INFO_EX(arginfo_nsapi_virtual, 0, 0, 1)
        !           173:        ZEND_ARG_INFO(0, uri)
        !           174: ZEND_END_ARG_INFO()
        !           175: 
        !           176: ZEND_BEGIN_ARG_INFO(arginfo_nsapi_request_headers, 0)
        !           177: ZEND_END_ARG_INFO()
        !           178: 
        !           179: ZEND_BEGIN_ARG_INFO(arginfo_nsapi_response_headers, 0)
        !           180: ZEND_END_ARG_INFO()
        !           181: /* }}} */
        !           182: 
        !           183: /* {{{ nsapi_functions[]
        !           184:  *
        !           185:  * Every user visible function must have an entry in nsapi_functions[].
        !           186:  */
        !           187: const zend_function_entry nsapi_functions[] = {
        !           188:        PHP_FE(nsapi_virtual,   arginfo_nsapi_virtual)                                          /* Make subrequest */
        !           189:        PHP_FALIAS(virtual, nsapi_virtual, arginfo_nsapi_virtual)                       /* compatibility */
        !           190:        PHP_FE(nsapi_request_headers, arginfo_nsapi_request_headers)            /* get request headers */
        !           191:        PHP_FALIAS(getallheaders, nsapi_request_headers, arginfo_nsapi_request_headers) /* compatibility */
        !           192:        PHP_FALIAS(apache_request_headers, nsapi_request_headers, arginfo_nsapi_request_headers)        /* compatibility */
        !           193:        PHP_FE(nsapi_response_headers, arginfo_nsapi_response_headers)          /* get response headers */
        !           194:        PHP_FALIAS(apache_response_headers, nsapi_response_headers, arginfo_nsapi_response_headers)     /* compatibility */
        !           195:        {NULL, NULL, NULL}
        !           196: };
        !           197: /* }}} */
        !           198: 
        !           199: /* {{{ nsapi_module_entry
        !           200:  */
        !           201: zend_module_entry nsapi_module_entry = {
        !           202:        STANDARD_MODULE_HEADER,
        !           203:        "nsapi",
        !           204:        nsapi_functions,
        !           205:        PHP_MINIT(nsapi),
        !           206:        PHP_MSHUTDOWN(nsapi),
        !           207:        NULL,
        !           208:        NULL,
        !           209:        PHP_MINFO(nsapi),
        !           210:        NO_VERSION_YET,
        !           211:        STANDARD_MODULE_PROPERTIES
        !           212: };
        !           213: /* }}} */
        !           214: 
        !           215: /* {{{ PHP_INI
        !           216:  */
        !           217: PHP_INI_BEGIN()
        !           218:     STD_PHP_INI_ENTRY("nsapi.read_timeout", "60", PHP_INI_ALL, OnUpdateLong, read_timeout, zend_nsapi_globals, nsapi_globals)
        !           219: PHP_INI_END()
        !           220: /* }}} */
        !           221: 
        !           222: /* newer servers hide this functions from the programmer so redefine the functions dynamically
        !           223:    thanks to Chris Elving from Sun for the function declarations */
        !           224: typedef int (*nsapi_servact_prototype)(Session *sn, Request *rq);
        !           225: nsapi_servact_prototype nsapi_servact_uri2path = NULL;
        !           226: nsapi_servact_prototype nsapi_servact_pathchecks = NULL;
        !           227: nsapi_servact_prototype nsapi_servact_fileinfo = NULL;
        !           228: nsapi_servact_prototype nsapi_servact_service = NULL;
        !           229: 
        !           230: #ifdef PHP_WIN32
        !           231: /* The following dll-names for nsapi are in use at this time. The undocumented
        !           232:  * servact_* functions are always in the newest one, older ones are supported by
        !           233:  * the server only by wrapping the function table nothing else. So choose
        !           234:  * the newest one found in process space for dynamic linking */
        !           235: static char *nsapi_dlls[] = { "ns-httpd40.dll", "ns-httpd36.dll", "ns-httpd35.dll", "ns-httpd30.dll", NULL };
        !           236: /* if user specifies an other dll name by server_lib parameter 
        !           237:  * it is placed in the following variable and only this DLL is
        !           238:  * checked for the servact_* functions */
        !           239: char *nsapi_dll = NULL;
        !           240: #endif
        !           241: 
        !           242: /* {{{ php_nsapi_init_dynamic_symbols
        !           243:  */
        !           244: static void php_nsapi_init_dynamic_symbols(void)
        !           245: {
        !           246:        /* find address of internal NSAPI functions */
        !           247: #ifdef PHP_WIN32
        !           248:        register int i;
        !           249:        DL_HANDLE module = NULL;
        !           250:        if (nsapi_dll) {
        !           251:                /* try user specified server_lib */
        !           252:                module = GetModuleHandle(nsapi_dll);
        !           253:                if (!module) {
        !           254:                        log_error(LOG_WARN, "php5_init", NULL, NULL, "Cannot find DLL specified by server_lib parameter: %s", nsapi_dll);
        !           255:                }
        !           256:        } else {
        !           257:                /* find a LOADED dll module from nsapi_dlls */
        !           258:                for (i=0; nsapi_dlls[i]; i++) {
        !           259:                        if (module = GetModuleHandle(nsapi_dlls[i])) {
        !           260:                                break;
        !           261:                        }
        !           262:                }
        !           263:        }
        !           264:        if (!module) return;
        !           265: #else
        !           266:        DL_HANDLE module = RTLD_DEFAULT;
        !           267: #endif
        !           268:        nsapi_servact_uri2path = (nsapi_servact_prototype)DL_FETCH_SYMBOL(module, "INTservact_uri2path");
        !           269:        nsapi_servact_pathchecks = (nsapi_servact_prototype)DL_FETCH_SYMBOL(module, "INTservact_pathchecks");
        !           270:        nsapi_servact_fileinfo = (nsapi_servact_prototype)DL_FETCH_SYMBOL(module, "INTservact_fileinfo");
        !           271:        nsapi_servact_service = (nsapi_servact_prototype)DL_FETCH_SYMBOL(module, "INTservact_service");
        !           272:        if (!(nsapi_servact_uri2path && nsapi_servact_pathchecks && nsapi_servact_fileinfo && nsapi_servact_service)) {
        !           273:                /* not found - could be cause they are undocumented */
        !           274:                nsapi_servact_uri2path = NULL;
        !           275:                nsapi_servact_pathchecks = NULL;
        !           276:                nsapi_servact_fileinfo = NULL;
        !           277:                nsapi_servact_service = NULL;
        !           278:        }
        !           279: }
        !           280: /* }}} */
        !           281: 
        !           282: /* {{{ php_nsapi_init_globals
        !           283:  */
        !           284: static void php_nsapi_init_globals(zend_nsapi_globals *nsapi_globals)
        !           285: {
        !           286:        nsapi_globals->read_timeout = 60;
        !           287: }
        !           288: /* }}} */
        !           289: 
        !           290: /* {{{ PHP_MINIT_FUNCTION
        !           291:  */
        !           292: PHP_MINIT_FUNCTION(nsapi)
        !           293: {
        !           294:        php_nsapi_init_dynamic_symbols();
        !           295:        ZEND_INIT_MODULE_GLOBALS(nsapi, php_nsapi_init_globals, NULL);
        !           296:        REGISTER_INI_ENTRIES();
        !           297:        return SUCCESS;
        !           298: }
        !           299: /* }}} */
        !           300: 
        !           301: /* {{{ PHP_MSHUTDOWN_FUNCTION
        !           302:  */
        !           303: PHP_MSHUTDOWN_FUNCTION(nsapi)
        !           304: {
        !           305:        UNREGISTER_INI_ENTRIES();
        !           306:        return SUCCESS;
        !           307: }
        !           308: /* }}} */
        !           309: 
        !           310: /* {{{ PHP_MINFO_FUNCTION
        !           311:  */
        !           312: PHP_MINFO_FUNCTION(nsapi)
        !           313: {
        !           314:        php_info_print_table_start();
        !           315:        php_info_print_table_row(2, "NSAPI Module Revision", "$Revision: 321634 $");
        !           316:        php_info_print_table_row(2, "Server Software", system_version());
        !           317:        php_info_print_table_row(2, "Sub-requests with nsapi_virtual()",
        !           318:         (nsapi_servact_service)?((zend_ini_long("zlib.output_compression", sizeof("zlib.output_compression"), 0))?"not supported with zlib.output_compression":"enabled"):"not supported on this platform" );
        !           319:        php_info_print_table_end();
        !           320: 
        !           321:        DISPLAY_INI_ENTRIES();
        !           322: }
        !           323: /* }}} */
        !           324: 
        !           325: /* {{{ proto bool nsapi_virtual(string uri)
        !           326:    Perform an NSAPI sub-request */
        !           327: /* This function is equivalent to <!--#include virtual...-->
        !           328:  * in SSI. It does an NSAPI sub-request. It is useful
        !           329:  * for including CGI scripts or .shtml files, or anything else
        !           330:  * that you'd parse through webserver.
        !           331:  */
        !           332: PHP_FUNCTION(nsapi_virtual)
        !           333: {
        !           334:        int uri_len,rv;
        !           335:        char *uri,*value;
        !           336:        Request *rq;
        !           337:        nsapi_request_context *rc = (nsapi_request_context *)SG(server_context);
        !           338: 
        !           339:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &uri, &uri_len) == FAILURE) {
        !           340:                return;
        !           341:        }
        !           342: 
        !           343:        if (!nsapi_servact_service) {
        !           344:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to include uri '%s' - Sub-requests not supported on this platform", uri);
        !           345:                RETURN_FALSE;
        !           346:        } else if (zend_ini_long("zlib.output_compression", sizeof("zlib.output_compression"), 0)) {
        !           347:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to include uri '%s' - Sub-requests do not work with zlib.output_compression", uri);
        !           348:                RETURN_FALSE;
        !           349:        } else {
        !           350:                php_end_ob_buffers(1 TSRMLS_CC);
        !           351:                php_header(TSRMLS_C);
        !           352: 
        !           353:                /* do the sub-request */
        !           354:                /* thanks to Chris Elving from Sun for this code sniplet */
        !           355:                if ((rq = request_restart_internal(uri, NULL)) == NULL) {
        !           356:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to include uri '%s' - Internal request creation failed", uri);
        !           357:                        RETURN_FALSE;
        !           358:                }
        !           359: 
        !           360:                /* insert host of current request to get page from same vhost */
        !           361:                param_free(pblock_remove("host", rq->headers));
        !           362:                if (value = pblock_findval("host", rc->rq->headers)) {
        !           363:                        pblock_nvinsert("host", value, rq->headers);
        !           364:                }
        !           365: 
        !           366:                /* go through the normal request stages as given in obj.conf,
        !           367:                   but leave out the logging/error section */
        !           368:                do {
        !           369:                        rv = (*nsapi_servact_uri2path)(rc->sn, rq);
        !           370:                        if (rv != REQ_PROCEED) {
        !           371:                                continue;
        !           372:                        }
        !           373: 
        !           374:                        rv = (*nsapi_servact_pathchecks)(rc->sn, rq);
        !           375:                        if (rv != REQ_PROCEED) {
        !           376:                                continue;
        !           377:                        }
        !           378: 
        !           379:                        rv = (*nsapi_servact_fileinfo)(rc->sn, rq);
        !           380:                        if (rv != REQ_PROCEED) {
        !           381:                                continue;
        !           382:                        }
        !           383: 
        !           384:                        rv = (*nsapi_servact_service)(rc->sn, rq);
        !           385:                } while (rv == REQ_RESTART);
        !           386: 
        !           387:                if (rq->status_num != 200) {
        !           388:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to include uri '%s' - HTTP status code %d during subrequest", uri, rq->status_num);
        !           389:                        request_free(rq);
        !           390:                        RETURN_FALSE;
        !           391:                }
        !           392: 
        !           393:                request_free(rq);
        !           394: 
        !           395:                RETURN_TRUE;
        !           396:        }
        !           397: }
        !           398: /* }}} */
        !           399: 
        !           400: /* {{{ proto array nsapi_request_headers(void)
        !           401:    Get all headers from the request */
        !           402: PHP_FUNCTION(nsapi_request_headers)
        !           403: {
        !           404:        register int i;
        !           405:        struct pb_entry *entry;
        !           406:        nsapi_request_context *rc = (nsapi_request_context *)SG(server_context);
        !           407: 
        !           408:        if (zend_parse_parameters_none() == FAILURE) {
        !           409:                return;
        !           410:        }
        !           411:        
        !           412:        array_init(return_value);
        !           413: 
        !           414:        for (i=0; i < rc->rq->headers->hsize; i++) {
        !           415:                entry=rc->rq->headers->ht[i];
        !           416:                while (entry) {
        !           417:                        if (!PG(safe_mode) || strncasecmp(entry->param->name, "authorization", 13)) {
        !           418:                                add_assoc_string(return_value, entry->param->name, entry->param->value, 1);
        !           419:                        }
        !           420:                        entry=entry->next;
        !           421:                }
        !           422:        }
        !           423: }
        !           424: /* }}} */
        !           425: 
        !           426: /* {{{ proto array nsapi_response_headers(void)
        !           427:    Get all headers from the response */
        !           428: PHP_FUNCTION(nsapi_response_headers)
        !           429: {
        !           430:        register int i;
        !           431:        struct pb_entry *entry;
        !           432:        nsapi_request_context *rc = (nsapi_request_context *)SG(server_context);
        !           433: 
        !           434:        if (zend_parse_parameters_none() == FAILURE) {
        !           435:                return;
        !           436:        }
        !           437:        
        !           438:        array_init(return_value);
        !           439: 
        !           440:        for (i=0; i < rc->rq->srvhdrs->hsize; i++) {
        !           441:                entry=rc->rq->srvhdrs->ht[i];
        !           442:                while (entry) {
        !           443:                        add_assoc_string(return_value, entry->param->name, entry->param->value, 1);
        !           444:                        entry=entry->next;
        !           445:                }
        !           446:        }
        !           447: }
        !           448: /* }}} */
        !           449: 
        !           450: 
        !           451: /*************/
        !           452: /* SAPI part */
        !           453: /*************/
        !           454: 
        !           455: static int sapi_nsapi_ub_write(const char *str, unsigned int str_length TSRMLS_DC)
        !           456: {
        !           457:        int retval;
        !           458:        nsapi_request_context *rc = (nsapi_request_context *)SG(server_context);
        !           459:        
        !           460:        if (!SG(headers_sent)) {
        !           461:                sapi_send_headers(TSRMLS_C);
        !           462:        }
        !           463: 
        !           464:        retval = net_write(rc->sn->csd, (char *)str, str_length);
        !           465:        if (retval == IO_ERROR /* -1 */ || retval == IO_EOF /* 0 */) {
        !           466:                php_handle_aborted_connection();
        !           467:        }
        !           468:        return retval;
        !           469: }
        !           470: 
        !           471: /* modified version of apache2 */
        !           472: static void sapi_nsapi_flush(void *server_context)
        !           473: {
        !           474:        nsapi_request_context *rc = (nsapi_request_context *)server_context;
        !           475:        TSRMLS_FETCH();
        !           476:        
        !           477:        if (!rc) {
        !           478:                /* we have no context, so no flushing needed. This fixes a SIGSEGV on shutdown */
        !           479:                return;
        !           480:        }
        !           481: 
        !           482:        if (!SG(headers_sent)) {
        !           483:                sapi_send_headers(TSRMLS_C);
        !           484:        }
        !           485: 
        !           486:        /* flushing is only supported in iPlanet servers from version 6.1 on, make it conditional */
        !           487: #if NSAPI_VERSION >= 302
        !           488:        if (net_flush(rc->sn->csd) < 0) {
        !           489:                php_handle_aborted_connection();
        !           490:        }
        !           491: #endif
        !           492: }
        !           493: 
        !           494: /* callback for zend_llist_apply on SAPI_HEADER_DELETE_ALL operation */
        !           495: static int php_nsapi_remove_header(sapi_header_struct *sapi_header TSRMLS_DC)
        !           496: {
        !           497:        char *header_name, *p;
        !           498:        nsapi_request_context *rc = (nsapi_request_context *)SG(server_context);
        !           499:        
        !           500:        /* copy the header, because NSAPI needs reformatting and we do not want to change the parameter */
        !           501:        header_name = pool_strdup(rc->sn->pool, sapi_header->header);
        !           502: 
        !           503:        /* extract name, this works, if only the header without ':' is given, too */
        !           504:        if (p = strchr(header_name, ':')) {
        !           505:                *p = 0;
        !           506:        }
        !           507:        
        !           508:        /* header_name to lower case because NSAPI reformats the headers and wants lowercase */
        !           509:        for (p=header_name; *p; p++) {
        !           510:                *p=tolower(*p);
        !           511:        }
        !           512:        
        !           513:        /* remove the header */
        !           514:        param_free(pblock_remove(header_name, rc->rq->srvhdrs));
        !           515:        pool_free(rc->sn->pool, header_name);
        !           516:        
        !           517:        return ZEND_HASH_APPLY_KEEP;
        !           518: }
        !           519: 
        !           520: static int sapi_nsapi_header_handler(sapi_header_struct *sapi_header, sapi_header_op_enum op, sapi_headers_struct *sapi_headers TSRMLS_DC)
        !           521: {
        !           522:        char *header_name, *header_content, *p;
        !           523:        nsapi_request_context *rc = (nsapi_request_context *)SG(server_context);
        !           524: 
        !           525:        switch(op) {
        !           526:                case SAPI_HEADER_DELETE_ALL:
        !           527:                        /* this only deletes headers set or overwritten by PHP, headers previously set by NSAPI are left intact */
        !           528:                        zend_llist_apply(&sapi_headers->headers, (llist_apply_func_t) php_nsapi_remove_header TSRMLS_CC);
        !           529:                        return 0;
        !           530: 
        !           531:                case SAPI_HEADER_DELETE:
        !           532:                        /* reuse the zend_llist_apply callback function for this, too */
        !           533:                        php_nsapi_remove_header(sapi_header TSRMLS_CC);
        !           534:                        return 0;
        !           535: 
        !           536:                case SAPI_HEADER_ADD:
        !           537:                case SAPI_HEADER_REPLACE:
        !           538:                        /* copy the header, because NSAPI needs reformatting and we do not want to change the parameter */
        !           539:                        header_name = pool_strdup(rc->sn->pool, sapi_header->header);
        !           540: 
        !           541:                        /* split header and align pointer for content */
        !           542:                        header_content = strchr(header_name, ':');
        !           543:                        if (header_content) {
        !           544:                                *header_content = 0;
        !           545:                                do {
        !           546:                                        header_content++;
        !           547:                                } while (*header_content==' ');
        !           548:                                
        !           549:                                /* header_name to lower case because NSAPI reformats the headers and wants lowercase */
        !           550:                                for (p=header_name; *p; p++) {
        !           551:                                        *p=tolower(*p);
        !           552:                                }
        !           553: 
        !           554:                                /* if REPLACE, remove first.  "Content-type" is always removed, as SAPI has a bug according to this */
        !           555:                                if (op==SAPI_HEADER_REPLACE || strcmp(header_name, "content-type")==0) {
        !           556:                                        param_free(pblock_remove(header_name, rc->rq->srvhdrs));
        !           557:                                }
        !           558:                                /* ADD header to nsapi table */
        !           559:                                pblock_nvinsert(header_name, header_content, rc->rq->srvhdrs);
        !           560:                        }
        !           561:                        
        !           562:                        pool_free(rc->sn->pool, header_name);
        !           563:                        return SAPI_HEADER_ADD;
        !           564:                        
        !           565:                default:
        !           566:                        return 0;
        !           567:        }
        !           568: }
        !           569: 
        !           570: static int sapi_nsapi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
        !           571: {
        !           572:        int retval;
        !           573:        nsapi_request_context *rc = (nsapi_request_context *)SG(server_context);
        !           574: 
        !           575:        if (SG(sapi_headers).send_default_content_type) {
        !           576:                char *hd;
        !           577:                param_free(pblock_remove("content-type", rc->rq->srvhdrs));
        !           578:                hd = sapi_get_default_content_type(TSRMLS_C);
        !           579:                pblock_nvinsert("content-type", hd, rc->rq->srvhdrs);
        !           580:                efree(hd);
        !           581:        }
        !           582: 
        !           583:        protocol_status(rc->sn, rc->rq, SG(sapi_headers).http_response_code, NULL);
        !           584:        retval = protocol_start_response(rc->sn, rc->rq);
        !           585: 
        !           586:        if (retval == REQ_PROCEED || retval == REQ_NOACTION) {
        !           587:                return SAPI_HEADER_SENT_SUCCESSFULLY;
        !           588:        } else {
        !           589:                return SAPI_HEADER_SEND_FAILED;
        !           590:        }
        !           591: }
        !           592: 
        !           593: static int sapi_nsapi_read_post(char *buffer, uint count_bytes TSRMLS_DC)
        !           594: {
        !           595:        nsapi_request_context *rc = (nsapi_request_context *)SG(server_context);
        !           596:        char *read_ptr = buffer, *content_length_str = NULL;
        !           597:        uint bytes_read = 0;
        !           598:        int length, content_length = 0;
        !           599:        netbuf *nbuf = rc->sn->inbuf;
        !           600: 
        !           601:        /*
        !           602:         *      Yesss!
        !           603:         */
        !           604:        count_bytes = MIN(count_bytes, SG(request_info).content_length-rc->read_post_bytes);
        !           605:        content_length = SG(request_info).content_length;
        !           606: 
        !           607:        if (content_length <= 0) {
        !           608:                return 0;
        !           609:        }
        !           610: 
        !           611:        /*
        !           612:         * Gobble any pending data in the netbuf.
        !           613:         */
        !           614:        length = nbuf->cursize - nbuf->pos;
        !           615:        length = MIN(count_bytes, length);
        !           616:        if (length > 0) {
        !           617:                memcpy(read_ptr, nbuf->inbuf + nbuf->pos, length);
        !           618:                bytes_read += length;
        !           619:                read_ptr += length;
        !           620:                content_length -= length;
        !           621:                nbuf->pos += length;
        !           622:        }
        !           623: 
        !           624:        /*
        !           625:         * Read the remaining from the socket.
        !           626:         */
        !           627:        while (content_length > 0 && bytes_read < count_bytes) {
        !           628:                int bytes_to_read = count_bytes - bytes_read;
        !           629: 
        !           630:                if (content_length < bytes_to_read) {
        !           631:                        bytes_to_read = content_length;
        !           632:                }
        !           633: 
        !           634:                length = net_read(rc->sn->csd, read_ptr, bytes_to_read, NSAPI_G(read_timeout));
        !           635: 
        !           636:                if (length == IO_ERROR || length == IO_EOF) {
        !           637:                        break;
        !           638:                }
        !           639: 
        !           640:                bytes_read += length;
        !           641:                read_ptr += length;
        !           642:                content_length -= length;
        !           643:        }
        !           644: 
        !           645:        if ( bytes_read > 0 ) {
        !           646:                rc->read_post_bytes += bytes_read;
        !           647:        }
        !           648:        return bytes_read;
        !           649: }
        !           650: 
        !           651: static char *sapi_nsapi_read_cookies(TSRMLS_D)
        !           652: {
        !           653:        char *cookie_string;
        !           654:        nsapi_request_context *rc = (nsapi_request_context *)SG(server_context);
        !           655: 
        !           656:        cookie_string = pblock_findval("cookie", rc->rq->headers);
        !           657:        return cookie_string;
        !           658: }
        !           659: 
        !           660: static void sapi_nsapi_register_server_variables(zval *track_vars_array TSRMLS_DC)
        !           661: {
        !           662:        nsapi_request_context *rc = (nsapi_request_context *)SG(server_context);
        !           663:        register size_t i;
        !           664:        int pos;
        !           665:        char *value,*p;
        !           666:        char buf[32];
        !           667:        struct pb_entry *entry;
        !           668: 
        !           669:        for (i = 0; i < nsapi_reqpb_size; i++) {
        !           670:                value = pblock_findval(nsapi_reqpb[i].nsapi_eq, rc->rq->reqpb);
        !           671:                if (value) {
        !           672:                        php_register_variable((char *)nsapi_reqpb[i].env_var, value, track_vars_array TSRMLS_CC);
        !           673:                }
        !           674:        }
        !           675: 
        !           676:        for (i=0; i < rc->rq->headers->hsize; i++) {
        !           677:                entry=rc->rq->headers->ht[i];
        !           678:                while (entry) {
        !           679:                        if (!PG(safe_mode) || strncasecmp(entry->param->name, "authorization", 13)) {
        !           680:                                if (strcasecmp(entry->param->name, "content-length")==0 || strcasecmp(entry->param->name, "content-type")==0) {
        !           681:                                        value=estrdup(entry->param->name);
        !           682:                                        pos = 0;
        !           683:                                } else {
        !           684:                                        spprintf(&value, 0, "HTTP_%s", entry->param->name);
        !           685:                                        pos = 5;
        !           686:                                }
        !           687:                                if (value) {
        !           688:                                        for(p = value + pos; *p; p++) {
        !           689:                                                *p = toupper(*p);
        !           690:                                                if (!isalnum(*p)) {
        !           691:                                                        *p = '_';
        !           692:                                                }
        !           693:                                        }
        !           694:                                        php_register_variable(value, entry->param->value, track_vars_array TSRMLS_CC);
        !           695:                                        efree(value);
        !           696:                                }
        !           697:                        }
        !           698:                        entry=entry->next;
        !           699:                }
        !           700:        }
        !           701: 
        !           702:        for (i = 0; i < nsapi_vars_size; i++) {
        !           703:                value = pblock_findval(nsapi_vars[i].nsapi_eq, rc->rq->vars);
        !           704:                if (value) {
        !           705:                        php_register_variable((char *)nsapi_vars[i].env_var, value, track_vars_array TSRMLS_CC);
        !           706:                }
        !           707:        }
        !           708: 
        !           709:        for (i = 0; i < nsapi_client_size; i++) {
        !           710:                value = pblock_findval(nsapi_client[i].nsapi_eq, rc->sn->client);
        !           711:                if (value) {
        !           712:                        php_register_variable((char *)nsapi_client[i].env_var, value, track_vars_array TSRMLS_CC);
        !           713:                }
        !           714:        }
        !           715: 
        !           716:        if (value = session_dns(rc->sn)) {
        !           717:                php_register_variable("REMOTE_HOST", value, track_vars_array TSRMLS_CC);
        !           718:                nsapi_free(value);
        !           719:        }
        !           720: 
        !           721:        slprintf(buf, sizeof(buf), "%d", conf_getglobals()->Vport);
        !           722:        php_register_variable("SERVER_PORT", buf, track_vars_array TSRMLS_CC);
        !           723:        php_register_variable("SERVER_NAME", conf_getglobals()->Vserver_hostname, track_vars_array TSRMLS_CC);
        !           724: 
        !           725:        value = http_uri2url_dynamic("", "", rc->sn, rc->rq);
        !           726:        php_register_variable("SERVER_URL", value, track_vars_array TSRMLS_CC);
        !           727:        nsapi_free(value);
        !           728: 
        !           729:        php_register_variable("SERVER_SOFTWARE", system_version(), track_vars_array TSRMLS_CC);
        !           730:        if (security_active) {
        !           731:                php_register_variable("HTTPS", "ON", track_vars_array TSRMLS_CC);
        !           732:        }
        !           733:        php_register_variable("GATEWAY_INTERFACE", "CGI/1.1", track_vars_array TSRMLS_CC);
        !           734: 
        !           735:        /* DOCUMENT_ROOT */
        !           736:        if (value = request_translate_uri("/", rc->sn)) {
        !           737:                pos = strlen(value);
        !           738:                php_register_variable_safe("DOCUMENT_ROOT", value, pos-1, track_vars_array TSRMLS_CC);
        !           739:                nsapi_free(value);
        !           740:        }
        !           741: 
        !           742:        /* PATH_INFO / PATH_TRANSLATED */
        !           743:        if (rc->path_info) {
        !           744:                if (value = request_translate_uri(rc->path_info, rc->sn)) {
        !           745:                        php_register_variable("PATH_TRANSLATED", value, track_vars_array TSRMLS_CC);
        !           746:                        nsapi_free(value);
        !           747:                }
        !           748:                php_register_variable("PATH_INFO", rc->path_info, track_vars_array TSRMLS_CC);
        !           749:        }
        !           750: 
        !           751:        /* Create full Request-URI & Script-Name */
        !           752:        if (SG(request_info).request_uri) {
        !           753:                pos = strlen(SG(request_info).request_uri);
        !           754:                
        !           755:                if (SG(request_info).query_string) {
        !           756:                        spprintf(&value, 0, "%s?%s", SG(request_info).request_uri, SG(request_info).query_string);
        !           757:                        if (value) {
        !           758:                                php_register_variable("REQUEST_URI", value, track_vars_array TSRMLS_CC);
        !           759:                                efree(value);
        !           760:                        }
        !           761:                } else {
        !           762:                        php_register_variable_safe("REQUEST_URI", SG(request_info).request_uri, pos, track_vars_array TSRMLS_CC);
        !           763:                }
        !           764: 
        !           765:                if (rc->path_info) {
        !           766:                        pos -= strlen(rc->path_info);
        !           767:                        if (pos<0) {
        !           768:                                pos = 0;
        !           769:                        }
        !           770:                }
        !           771:                php_register_variable_safe("SCRIPT_NAME", SG(request_info).request_uri, pos, track_vars_array TSRMLS_CC);
        !           772:        }
        !           773:        php_register_variable("SCRIPT_FILENAME", SG(request_info).path_translated, track_vars_array TSRMLS_CC);
        !           774: 
        !           775:        /* special variables in error mode */
        !           776:        if (rc->http_error) {
        !           777:                slprintf(buf, sizeof(buf), "%d", rc->http_error);
        !           778:                php_register_variable("ERROR_TYPE", buf, track_vars_array TSRMLS_CC);
        !           779:        }
        !           780: }
        !           781: 
        !           782: static void nsapi_log_message(char *message)
        !           783: {
        !           784:        TSRMLS_FETCH();
        !           785:        nsapi_request_context *rc = (nsapi_request_context *)SG(server_context);
        !           786: 
        !           787:        if (rc) {
        !           788:                log_error(LOG_INFORM, pblock_findval("fn", rc->pb), rc->sn, rc->rq, "%s", message);
        !           789:        } else {
        !           790:                log_error(LOG_INFORM, "php5", NULL, NULL, "%s", message);
        !           791:        }
        !           792: }
        !           793: 
        !           794: static time_t sapi_nsapi_get_request_time(TSRMLS_D)
        !           795: {
        !           796:        return REQ_TIME( ((nsapi_request_context *)SG(server_context))->rq );
        !           797: }
        !           798: 
        !           799: static int php_nsapi_startup(sapi_module_struct *sapi_module)
        !           800: {
        !           801:        if (php_module_startup(sapi_module, &nsapi_module_entry, 1)==FAILURE) {
        !           802:                return FAILURE;
        !           803:        }
        !           804:        return SUCCESS;
        !           805: }
        !           806: 
        !           807: static struct stat* sapi_nsapi_get_stat(TSRMLS_D)
        !           808: {
        !           809:        return request_stat_path(
        !           810:                SG(request_info).path_translated,
        !           811:                ((nsapi_request_context *)SG(server_context))->rq
        !           812:        );
        !           813: }
        !           814: 
        !           815: static sapi_module_struct nsapi_sapi_module = {
        !           816:        "nsapi",                                /* name */
        !           817:        "NSAPI",                                /* pretty name */
        !           818: 
        !           819:        php_nsapi_startup,                      /* startup */
        !           820:        php_module_shutdown_wrapper,            /* shutdown */
        !           821: 
        !           822:        NULL,                                   /* activate */
        !           823:        NULL,                                   /* deactivate */
        !           824: 
        !           825:        sapi_nsapi_ub_write,                    /* unbuffered write */
        !           826:        sapi_nsapi_flush,                       /* flush */
        !           827:        sapi_nsapi_get_stat,                    /* get uid/stat */
        !           828:        NULL,                                   /* getenv */
        !           829: 
        !           830:        php_error,                              /* error handler */
        !           831: 
        !           832:        sapi_nsapi_header_handler,              /* header handler */
        !           833:        sapi_nsapi_send_headers,                /* send headers handler */
        !           834:        NULL,                                   /* send header handler */
        !           835: 
        !           836:        sapi_nsapi_read_post,                   /* read POST data */
        !           837:        sapi_nsapi_read_cookies,                /* read Cookies */
        !           838: 
        !           839:        sapi_nsapi_register_server_variables,   /* register server variables */
        !           840:        nsapi_log_message,                      /* Log message */
        !           841:        sapi_nsapi_get_request_time,                    /* Get request time */
        !           842:        NULL,                                                                   /* Child terminate */
        !           843: 
        !           844:        NULL,                                   /* Block interruptions */
        !           845:        NULL,                                   /* Unblock interruptions */
        !           846: 
        !           847:        STANDARD_SAPI_MODULE_PROPERTIES
        !           848: };
        !           849: 
        !           850: static void nsapi_php_ini_entries(NSLS_D TSRMLS_DC)
        !           851: {
        !           852:        struct pb_entry *entry;
        !           853:        register int i,j,ok;
        !           854: 
        !           855:        for (i=0; i < NSG(pb)->hsize; i++) {
        !           856:                entry=NSG(pb)->ht[i];
        !           857:                while (entry) {
        !           858:                        /* exclude standard entries given to "Service" which should not go into ini entries */
        !           859:                        ok=1;
        !           860:                        for (j=0; nsapi_exclude_from_ini_entries[j]; j++) {
        !           861:                                ok&=(strcasecmp(entry->param->name, nsapi_exclude_from_ini_entries[j])!=0);
        !           862:                        }
        !           863: 
        !           864:                        if (ok) {
        !           865:                                /* change the ini entry */
        !           866:                                if (zend_alter_ini_entry(entry->param->name, strlen(entry->param->name)+1,
        !           867:                                 entry->param->value, strlen(entry->param->value),
        !           868:                                 PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE)==FAILURE) {
        !           869:                                        log_error(LOG_WARN, pblock_findval("fn", NSG(pb)), NSG(sn), NSG(rq), "Cannot change php.ini key \"%s\" to \"%s\"", entry->param->name, entry->param->value);
        !           870:                                }
        !           871:                        }
        !           872:                        entry=entry->next;
        !           873:                }
        !           874:        }
        !           875: }
        !           876: 
        !           877: void NSAPI_PUBLIC php5_close(void *vparam)
        !           878: {
        !           879:        if (nsapi_sapi_module.shutdown) {
        !           880:                nsapi_sapi_module.shutdown(&nsapi_sapi_module);
        !           881:        }
        !           882: 
        !           883:        if (nsapi_sapi_module.php_ini_path_override) {
        !           884:                free(nsapi_sapi_module.php_ini_path_override);
        !           885:        }
        !           886:        
        !           887: #ifdef PHP_WIN32
        !           888:        if (nsapi_dll) {
        !           889:                free(nsapi_dll);
        !           890:                nsapi_dll = NULL;
        !           891:        }
        !           892: #endif 
        !           893: 
        !           894:        sapi_shutdown();
        !           895:        tsrm_shutdown();
        !           896: 
        !           897:        log_error(LOG_INFORM, "php5_close", NULL, NULL, "Shutdown PHP Module");
        !           898: }
        !           899: 
        !           900: /*********************************************************
        !           901: / init SAF
        !           902: /
        !           903: / Init fn="php5_init" [php_ini="/path/to/php.ini"] [server_lib="ns-httpdXX.dll"]
        !           904: /   Initialize the NSAPI module in magnus.conf
        !           905: /
        !           906: / php_ini: gives path to php.ini file
        !           907: / server_lib: (only Win32) gives name of DLL (without path) to look for
        !           908: /  servact_* functions
        !           909: /
        !           910: /*********************************************************/
        !           911: int NSAPI_PUBLIC php5_init(pblock *pb, Session *sn, Request *rq)
        !           912: {
        !           913:        php_core_globals *core_globals;
        !           914:        char *strval;
        !           915:        int threads=128; /* default for server */
        !           916: 
        !           917:        /* fetch max threads from NSAPI and initialize TSRM with it */
        !           918:        threads=conf_getglobals()->Vpool_maxthreads;
        !           919:        if (threads<1) {
        !           920:                threads=128; /* default for server */
        !           921:        }
        !           922:        tsrm_startup(threads, 1, 0, NULL);
        !           923: 
        !           924:        core_globals = ts_resource(core_globals_id);
        !           925: 
        !           926:        /* look if php_ini parameter is given to php5_init */
        !           927:        if (strval = pblock_findval("php_ini", pb)) {
        !           928:                nsapi_sapi_module.php_ini_path_override = strdup(strval);
        !           929:        }
        !           930:        
        !           931: #ifdef PHP_WIN32
        !           932:        /* look if server_lib parameter is given to php5_init
        !           933:         * (this disables the automatic search for the newest ns-httpdXX.dll) */
        !           934:        if (strval = pblock_findval("server_lib", pb)) {
        !           935:                nsapi_dll = strdup(strval);
        !           936:        }
        !           937: #endif 
        !           938: 
        !           939:        /* start SAPI */
        !           940:        sapi_startup(&nsapi_sapi_module);
        !           941:        nsapi_sapi_module.startup(&nsapi_sapi_module);
        !           942: 
        !           943:        daemon_atrestart(&php5_close, NULL);
        !           944: 
        !           945:        log_error(LOG_INFORM, pblock_findval("fn", pb), sn, rq, "Initialized PHP Module (%d threads expected)", threads);
        !           946:        return REQ_PROCEED;
        !           947: }
        !           948: 
        !           949: /*********************************************************
        !           950: / normal use in Service directive:
        !           951: /
        !           952: / Service fn="php5_execute" type=... method=... [inikey=inivalue inikey=inivalue...]
        !           953: /
        !           954: / use in Service for a directory to supply a php-made directory listing instead of server default:
        !           955: /
        !           956: / Service fn="php5_execute" type="magnus-internal/directory" script="/path/to/script.php" [inikey=inivalue inikey=inivalue...]
        !           957: /
        !           958: / use in Error SAF to display php script as error page:
        !           959: /
        !           960: / Error fn="php5_execute" code=XXX script="/path/to/script.php" [inikey=inivalue inikey=inivalue...]
        !           961: / Error fn="php5_execute" reason="Reason" script="/path/to/script.php" [inikey=inivalue inikey=inivalue...]
        !           962: /
        !           963: /*********************************************************/
        !           964: int NSAPI_PUBLIC php5_execute(pblock *pb, Session *sn, Request *rq)
        !           965: {
        !           966:        int retval;
        !           967:        nsapi_request_context *request_context;
        !           968:        zend_file_handle file_handle = {0};
        !           969:        struct stat *fst;
        !           970: 
        !           971:        char *path_info;
        !           972:        char *query_string    = pblock_findval("query", rq->reqpb);
        !           973:        char *uri             = pblock_findval("uri", rq->reqpb);
        !           974:        char *request_method  = pblock_findval("method", rq->reqpb);
        !           975:        char *content_type    = pblock_findval("content-type", rq->headers);
        !           976:        char *content_length  = pblock_findval("content-length", rq->headers);
        !           977:        char *directive       = pblock_findval("Directive", pb);
        !           978:        int error_directive   = (directive && !strcasecmp(directive, "error"));
        !           979:        int fixed_script      = 1;
        !           980: 
        !           981:        /* try to use script parameter -> Error or Service for directory listing */
        !           982:        char *path_translated = pblock_findval("script", pb);
        !           983: 
        !           984:        TSRMLS_FETCH();
        !           985: 
        !           986:        /* if script parameter is missing: normal use as Service SAF  */
        !           987:        if (!path_translated) {
        !           988:                path_translated = pblock_findval("path", rq->vars);
        !           989:                path_info       = pblock_findval("path-info", rq->vars);
        !           990:                fixed_script = 0;
        !           991:                if (error_directive) {
        !           992:                        /* go to next error directive if script parameter is missing */
        !           993:                        log_error(LOG_WARN, pblock_findval("fn", pb), sn, rq, "Missing 'script' parameter");
        !           994:                        return REQ_NOACTION;
        !           995:                }
        !           996:        } else {
        !           997:                /* in error the path_info is the uri to the requested page */
        !           998:                path_info = pblock_findval("uri", rq->reqpb);
        !           999:        }
        !          1000: 
        !          1001:        /* check if this uri was included in an other PHP script with nsapi_virtual()
        !          1002:           by looking for a request context in the current thread */
        !          1003:        if (SG(server_context)) {
        !          1004:                /* send 500 internal server error */
        !          1005:                log_error(LOG_WARN, pblock_findval("fn", pb), sn, rq, "Cannot make nesting PHP requests with nsapi_virtual()");
        !          1006:                if (error_directive) {
        !          1007:                        return REQ_NOACTION;
        !          1008:                } else {
        !          1009:                        protocol_status(sn, rq, 500, NULL);
        !          1010:                        return REQ_ABORTED;
        !          1011:                }
        !          1012:        }
        !          1013: 
        !          1014:        request_context = (nsapi_request_context *)pool_malloc(sn->pool, sizeof(nsapi_request_context));
        !          1015:        if (!request_context) {
        !          1016:                log_error(LOG_CATASTROPHE, pblock_findval("fn", pb), sn, rq, "Insufficient memory to process PHP request!");
        !          1017:                return REQ_ABORTED;
        !          1018:        }
        !          1019:        request_context->pb = pb;
        !          1020:        request_context->sn = sn;
        !          1021:        request_context->rq = rq;
        !          1022:        request_context->read_post_bytes = 0;
        !          1023:        request_context->fixed_script = fixed_script;
        !          1024:        request_context->http_error = (error_directive) ? rq->status_num : 0;
        !          1025:        request_context->path_info = path_info;
        !          1026: 
        !          1027:        SG(server_context) = request_context;
        !          1028:        SG(request_info).query_string = query_string;
        !          1029:        SG(request_info).request_uri = uri;
        !          1030:        SG(request_info).request_method = request_method;
        !          1031:        SG(request_info).path_translated = path_translated;
        !          1032:        SG(request_info).content_type = content_type;
        !          1033:        SG(request_info).content_length = (content_length == NULL) ? 0 : strtoul(content_length, 0, 0);
        !          1034:        SG(sapi_headers).http_response_code = (error_directive) ? rq->status_num : 200;
        !          1035:        
        !          1036:        nsapi_php_ini_entries(NSLS_C TSRMLS_CC);
        !          1037: 
        !          1038:        if (!PG(safe_mode)) php_handle_auth_data(pblock_findval("authorization", rq->headers) TSRMLS_CC);
        !          1039: 
        !          1040:        file_handle.type = ZEND_HANDLE_FILENAME;
        !          1041:        file_handle.filename = SG(request_info).path_translated;
        !          1042:        file_handle.free_filename = 0;
        !          1043:        file_handle.opened_path = NULL;
        !          1044: 
        !          1045:        fst = request_stat_path(SG(request_info).path_translated, rq);
        !          1046:        if (fst && S_ISREG(fst->st_mode)) {
        !          1047:                if (php_request_startup(TSRMLS_C) == SUCCESS) {
        !          1048:                        php_execute_script(&file_handle TSRMLS_CC);
        !          1049:                        php_request_shutdown(NULL);
        !          1050:                        retval=REQ_PROCEED;
        !          1051:                } else {
        !          1052:                        /* send 500 internal server error */
        !          1053:                        log_error(LOG_WARN, pblock_findval("fn", pb), sn, rq, "Cannot prepare PHP engine!");
        !          1054:                        if (error_directive) {
        !          1055:                                retval=REQ_NOACTION;
        !          1056:                        } else {
        !          1057:                                protocol_status(sn, rq, 500, NULL);
        !          1058:                                retval=REQ_ABORTED;
        !          1059:                        }
        !          1060:                }
        !          1061:        } else {
        !          1062:                /* send 404 because file not found */
        !          1063:                log_error(LOG_WARN, pblock_findval("fn", pb), sn, rq, "Cannot execute PHP script: %s (File not found)", SG(request_info).path_translated);
        !          1064:                if (error_directive) {
        !          1065:                        retval=REQ_NOACTION;
        !          1066:                } else {
        !          1067:                        protocol_status(sn, rq, 404, NULL);
        !          1068:                        retval=REQ_ABORTED;
        !          1069:                }
        !          1070:        }
        !          1071: 
        !          1072:        pool_free(sn->pool, request_context);
        !          1073:        SG(server_context) = NULL;
        !          1074: 
        !          1075:        return retval;
        !          1076: }
        !          1077: 
        !          1078: /*********************************************************
        !          1079: / authentication
        !          1080: /
        !          1081: / we have to make a 'fake' authenticator for netscape so it
        !          1082: / will pass authentication through to php, and allow us to
        !          1083: / check authentication with our scripts.
        !          1084: /
        !          1085: / php5_auth_trans
        !          1086: /   main function called from netscape server to authenticate
        !          1087: /   a line in obj.conf:
        !          1088: /              funcs=php5_auth_trans shlib="path/to/this/phpnsapi.dll"
        !          1089: /      and:
        !          1090: /              <Object ppath="path/to/be/authenticated/by/php/*">
        !          1091: /              AuthTrans fn="php5_auth_trans"
        !          1092: /*********************************************************/
        !          1093: int NSAPI_PUBLIC php5_auth_trans(pblock * pb, Session * sn, Request * rq)
        !          1094: {
        !          1095:        /* This is a DO NOTHING function that allows authentication
        !          1096:         * information
        !          1097:         * to be passed through to PHP scripts.
        !          1098:         */
        !          1099:        return REQ_PROCEED;
        !          1100: }
        !          1101: 
        !          1102: /*
        !          1103:  * Local variables:
        !          1104:  * tab-width: 4
        !          1105:  * c-basic-offset: 4
        !          1106:  * End:
        !          1107:  * vim600: sw=4 ts=4 fdm=marker
        !          1108:  * vim<600: sw=4 ts=4
        !          1109:  */

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