I worked this afternon on rewriting a lot of things in the module which now gives the php script almost the same variables like the apache sapi module (as provided).
For comparison: same request on two different servers, one with apache other with iplanet:

iplanet:
_GET["huhu"] haha
_SERVER["QUERY_STRING"] huhu=haha
_SERVER["REQUEST_LINE"] GET /test.php/testpfad?huhu=haha HTTP/1.1
_SERVER["REQUEST_METHOD"] GET
_SERVER["PHP_SELF"] /test.php/testpfad
_SERVER["SERVER_PROTOCOL"] HTTP/1.1
_SERVER["HTTP_ACCEPT"] */*
_SERVER["HTTP_ACCEPT_LANGUAGE"] de
_SERVER["HTTP_ACCEPT_ENCODING"] gzip, deflate
_SERVER["HTTP_USER_AGENT"] Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0; T312461)
_SERVER["HTTP_HOST"] edvs0.awi-bremerhaven.de
_SERVER["HTTP_CONNECTION"] Keep-Alive
_SERVER["PATH_INFO"] /testpfad
_SERVER["SCRIPT_FILENAME"] /pangaea/webserver/docs/test.php
_SERVER["REMOTE_ADDR"] 217.81.211.4
_SERVER["REMOTE_HOST"] 217.81.211.4
_SERVER["SERVER_PORT"] 80
_SERVER["SERVER_NAME"] edvs0.awi-bremerhaven.de
_SERVER["SERVER_URL"] http://edvs0.awi-bremerhaven.de
_SERVER["SERVER_SOFTWARE"] iPlanet-WebServer-Enterprise/6.0
_SERVER["HTTPS"] OFF
_SERVER["GATEWAY_INTERFACE"] CGI/1.1
_SERVER["DOCUMENT_ROOT"] /pangaea/webserver/docs
_SERVER["PATH_TRANSLATED"] /pangaea/webserver/docs/testpfad
_SERVER["REQUEST_URI"] /test.php/testpfad?huhu=haha
_SERVER["SCRIPT_NAME"] /test.php

apache:
_GET["huhu"] haha
_SERVER["DOCUMENT_ROOT"] /data/web4u/html
_SERVER["HTTP_ACCEPT"] */*
_SERVER["HTTP_ACCEPT_ENCODING"] gzip, deflate
_SERVER["HTTP_ACCEPT_LANGUAGE"] de
_SERVER["HTTP_CONNECTION"] Keep-Alive
_SERVER["HTTP_HOST"] www.web4u.cz
_SERVER["HTTP_USER_AGENT"] Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0; T312461)
_SERVER["PATH"] /bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin
_SERVER["REMOTE_ADDR"] 217.81.211.4
_SERVER["REMOTE_PORT"] 58578
_SERVER["SCRIPT_FILENAME"] /data/web4u/html/phpinfo.php4
_SERVER["SERVER_ADDR"] 194.228.111.51
_SERVER["SERVER_ADMIN"] [EMAIL PROTECTED]
_SERVER["SERVER_NAME"] www.web4u.cz
_SERVER["SERVER_PORT"] 80
_SERVER["SERVER_SIGNATURE"] <ADDRESS>Apache/1.3.27 Server at www.web4u.cz Port 80</ADDRESS>
_SERVER["SERVER_SOFTWARE"] Apache/1.3.27 (Unix) PHP/4.2.3 (LD+WD4 patch) PHP/3.0.18 (CZ 0.33) (LD+FU+WD2 patch)
_SERVER["GATEWAY_INTERFACE"] CGI/1.1
_SERVER["SERVER_PROTOCOL"] HTTP/1.1
_SERVER["REQUEST_METHOD"] GET
_SERVER["QUERY_STRING"] huhu=haha
_SERVER["REQUEST_URI"] /phpinfo.php4/testpfad?huhu=haha
_SERVER["SCRIPT_NAME"] /phpinfo.php4
_SERVER["PATH_INFO"] /testpfad
_SERVER["PATH_TRANSLATED"] /data/web4u/html/testpfad
_SERVER["PHP_SELF"] /phpinfo.php4/testpfad

In the original module were also errors in the variables PATH_TRANSLATED (contained the full path, same as PHP_SELF) and SCRIPT_NAME.
Also one open issue is, as I see in your mailing list archive, DOCUMENT_ROOT: It works with my modification even with virtual servers.

If I can do any further improvements let me know it. I have some experience with NSAPI so I could help to make the module always up-to-date when new servers of iPlanet/SUN came on the market.

With this new file the memory leaks (webserver eats up memory during afew days running) are also disappeared (all by NSAPI allocated strings are freed).

Uwe

P.S.: I have attached the finished nsapi.c file (in complete) because a patch has almost the same size :)
The patch I send yesterday was not fully correct.

At 11:14 03.02.2003 -0800, Shane Caraveo wrote:
Excelent, The CGI vars are correct.  One less sapi module to deal with :)
Shane

Uwe Schindler wrote:
The variables you explain are surely there. But a lot of scripts depend on other headers, which the client sent.
The SAPI module only creates Variables for a subset of them (HTTP_USER_AGENT). But not for all like
the other SAPI modules. So with this patch you get for example the missing HTTP_HOST-Header (HTTP/1.1)
because the patch creates for every variable in the request a HTTP_XXX-Variable. So you can see all headers the client have sent.
This is the way the other SAPI modules (APACHE) and the normal CGI environment works. Without it about 50% of the currently available PHP scripts do not run correctly.
You can try it with: http://www.emarcon.net/test.php which runs the patched Version. Yo will see all headers sent by your client not only the ones explained below and HTTP_USER_AGENT and HTTP_ACCEPT_*
Greetings from Germany,
Uwe
At 15:52 02.02.2003 -0800, you wrote:

Hi Uwe,
I haven't looked at the patch, but I am wondering if the nsapi sapi module creates variables for php that conform to the cgi spec. Can you try the following url against a phpinfo(); script:

http://localhost/info.php/test/path?query=string

You should get:

PATH_INFO=/test/path
PATH_TRANSLATED=/your_web_document_root/test/path
QUERY_STRING=query=string
SCRIPT_NAME=/info.php
PHP_SELF=/info.php

If you do not, then the sapi module is not conformant to cgi spec, and still needs some work.
Shane

Uwe Schindler wrote:

I submit a patch for the NSAPI SAPI module and hope that it fixes a lot of problems I have (and others as seen in the bug database).
As a lot of variables which are needed by a lot of PHP scripts which use $_SERVER["..."] are not transferred correctly to the PHP script that runs in iPlanet Webserver (4 or 6). An example are the "Host" and "X-Forwarded" headers. This is so, because the transferred variables are static in the SAPI module.
The new nsapi.c file now transfers _ALL_ variables from rc->rq->headers to php_register_variable("HTTP_"+headername_uppercase, ...).
Also missing variables like "SERVER_SOFTWARE" are added.
A lot of customers complain about memory leaks in this module. I hope they are also fixed by freeing the by nsapi allocated strings (the return value of session_dns and http_uri2url).
The patch should work with Netscape/iPlanet Servers from version 3 on (I used no newer API calls).
If you are interested I could eventually create a patch for supporting the "virtual servers" in SunONE/iPlanet Web Server 6, because some vars only get the default-hostname not the real virtual server name (for example $_SERVER["SERVER_URL"] which is often used in scripts to refer together with $_SERVER["PHP_SELF"]). But this mut be done with #ifdefs because some new functions are in the nsapi since version 6. A good fix would be also to map $_SERVER["SERVER_URL"] to "http://$SERVER["HTTP_HOST"]";, because in iPlanet-Servers the Host variable is everytime available (if not in original HTTP-headers it is defined to be the default hostname).
Greetings,
Uwe
/*
   +----------------------------------------------------------------------+
   | PHP Version 4                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2003 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.02 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available at through the world-wide-web at                           |
   | http://www.php.net/license/2_02.txt.                                 |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | [EMAIL PROTECTED] so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Jayakumar Muthukumarasamy <[EMAIL PROTECTED]>                   |
   |         Uwe Schindler <[EMAIL PROTECTED]>                              |
   +----------------------------------------------------------------------+
*/

/*
 * PHP includes
 */
#define NSAPI 1

#include "php.h"
#include "php_variables.h"
#include "ext/standard/info.h"
#include "php_ini.h"
#include "php_globals.h"
#include "SAPI.h"
#include "php_main.h"
#include "php_version.h"
#include "TSRM.h"
#include "ext/standard/php_standard.h"

/*
 * If neither XP_UNIX not XP_WIN32 is defined, try to guess which one.
 * Ideally, this should be done by the configure script.
 */
#if !defined(XP_UNIX) && !defined(XP_WIN32)
        #if defined(WIN32)
                #define XP_WIN32
        #else
                #define XP_UNIX
        #endif
#endif

/*
 * NSAPI includes
 */
#include "nsapi.h"
#include "base/pblock.h"
#include "base/session.h"
#include "frame/req.h"
#include "frame/protocol.h"  /* protocol_start_response */
#include "base/util.h"       /* is_mozilla, getline */
#include "frame/log.h"       /* log_error */

/*
 * Timeout for net_read(). This should probably go into php.ini
 */
#define NSAPI_READ_TIMEOUT      60      /* 60 seconds */

#define NSLS_D          struct nsapi_request_context *request_context
#define NSLS_DC         , NSLS_D
#define NSLS_C          request_context
#define NSLS_CC         , NSLS_C
#define NSG(v)          (request_context->v)

#define NS_BUF_SIZE 2048

/*
 * ZTS needs to be defined for NSAPI to work
 */
#if !defined(ZTS)
        #error "NSAPI module needs ZTS to be defined"
#endif

/*
 * Structure to encapsulate the NSAPI request in SAPI
 */
typedef struct nsapi_request_context {
        pblock  *pb;
        Session *sn;
        Request *rq;
        int     read_post_bytes;
} nsapi_request_context;

/*
 * Mappings between NSAPI names and environment variables. This
 * mapping was obtained from the sample programs at the iplanet
 * website.
 */
typedef struct nsapi_equiv {
        const char *env_var;
        const char *nsapi_eq;
} nsapi_equiv;

static nsapi_equiv nsapi_headers[] = {
        { "CONTENT_LENGTH",                     "content-length" },
        { "CONTENT_TYPE",                       "content-type" }
};
static size_t nsapi_headers_size = sizeof(nsapi_headers)/sizeof(nsapi_headers[0]);

static nsapi_equiv nsapi_reqpb[] = {
        { "QUERY_STRING",               "query" },
        { "REQUEST_LINE",               "clf-request" },
        { "REQUEST_METHOD",             "method" },
        { "PHP_SELF",                   "uri" },
        { "SERVER_PROTOCOL",    "protocol" }
};
static size_t nsapi_reqpb_size = sizeof(nsapi_reqpb)/sizeof(nsapi_reqpb[0]);

static nsapi_equiv nsapi_vars[] = {
        { "PATH_INFO",                  "path-info" },
        { "SCRIPT_FILENAME",    "path" },
        { "AUTH_TYPE",                  "auth-type" },
        { "CLIENT_CERT",                "auth-cert" },
        { "REMOTE_USER",                "auth-user" }
};
static size_t nsapi_vars_size = sizeof(nsapi_vars)/sizeof(nsapi_vars[0]);

static nsapi_equiv nsapi_client[] = {
        { "HTTPS_KEYSIZE",              "keysize" },
        { "HTTPS_SECRETSIZE",   "secret-keysize" },
        { "REMOTE_ADDR",                "ip" },
        { "REMOTE_HOST",                "ip" }
};
static size_t nsapi_client_size = sizeof(nsapi_client)/sizeof(nsapi_client[0]);

static char *
nsapi_strdup(char *str)
{
        if (str != NULL)
                return STRDUP(str);
        return NULL;
}

static void
nsapi_free(void *addr)
{
        if (addr != NULL)
                FREE(addr);
}

static int
sapi_nsapi_ub_write(const char *str, unsigned int str_length TSRMLS_DC)
{
        int retval;
        nsapi_request_context *rc;

        rc = (nsapi_request_context *)SG(server_context);
        retval = net_write(rc->sn->csd, (char *)str, str_length);
        if (retval == IO_ERROR /*-1*/ || retval == IO_EOF /*0*/)
                php_handle_aborted_connection();
        return retval;
}

static int
sapi_nsapi_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct 
*sapi_headers TSRMLS_DC)
{
        char *header_name, *header_content, *p;
        nsapi_request_context *rc = (nsapi_request_context *)SG(server_context);

        header_name = sapi_header->header;
        header_content = p = strchr(header_name, ':');
        if (p == NULL) {
                efree(sapi_header->header);
                return 0;
        }

        *p = 0;
        do {
                header_content++;
        } while (*header_content==' ');

        if (!strcasecmp(header_name, "Content-Type")) {
                param_free(pblock_remove("content-type", rc->rq->srvhdrs));
                pblock_nvinsert("content-type", header_content, rc->rq->srvhdrs);
        } else if (!strcasecmp(header_name, "Set-Cookie")) {
                pblock_nvinsert("set-cookie", header_content, rc->rq->srvhdrs);
        } else {
                pblock_nvinsert(header_name, header_content, rc->rq->srvhdrs);
        }

        *p = ':';       /* restore '*p' */

        efree(sapi_header->header);

        return 0;       /* don't use the default SAPI mechanism, NSAPI duplicates this 
functionality */
}

static int
sapi_nsapi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
{
        int retval;
        nsapi_request_context *rc = (nsapi_request_context *)SG(server_context);

        /*
         * We could probably just do this in the header_handler. But, I
         * don't know what the implication of doing it there is.
         */
        if (SG(sapi_headers).send_default_content_type) {
                param_free(pblock_remove("content-type", rc->rq->srvhdrs));
                pblock_nvinsert("content-type", "text/html", rc->rq->srvhdrs);
        }

        protocol_status(rc->sn, rc->rq, SG(sapi_headers).http_response_code, NULL);
        retval = protocol_start_response(rc->sn, rc->rq);
        if (retval == REQ_PROCEED || retval == REQ_NOACTION)
                return SAPI_HEADER_SENT_SUCCESSFULLY;
        else
                return SAPI_HEADER_SEND_FAILED;
}

static int
sapi_nsapi_read_post(char *buffer, uint count_bytes TSRMLS_DC)
{
        nsapi_request_context *rc = (nsapi_request_context *)SG(server_context);
        char *read_ptr = buffer, *content_length_str = NULL;
        uint bytes_read = 0;
        int length, content_length = 0;
        netbuf *nbuf = rc->sn->inbuf;

        /*
         *      Yesss!
         */
        count_bytes = MIN(count_bytes, 
SG(request_info).content_length-rc->read_post_bytes);
        content_length = SG(request_info).content_length;

#if 0
        /*
         * Determine the content-length. This will tell us the limit we can read.
         */
        content_length_str = pblock_findval("content-length", rc->rq->headers);
        if (content_length_str != NULL) {
                content_length = strtol(content_length_str, 0, 0);
        }
#endif

        if (content_length <= 0)
                return 0;

        /*
         * Gobble any pending data in the netbuf.
         */
        length = nbuf->cursize - nbuf->pos;
        length = MIN(count_bytes, length);
        if (length > 0) {
                memcpy(read_ptr, nbuf->inbuf + nbuf->pos, length);
                bytes_read += length;
                read_ptr += length;
                content_length -= length;
                nbuf->pos += length;
        }

        /*
         * Read the remaining from the socket.
         */
        while (content_length > 0 && bytes_read < count_bytes) {
                int bytes_to_read = count_bytes - bytes_read;
                if (content_length < bytes_to_read)
                        bytes_to_read = content_length;

                length = net_read(rc->sn->csd, read_ptr, bytes_to_read, 
NSAPI_READ_TIMEOUT);
                if (length == IO_ERROR || length == IO_EOF)
                        break;

                bytes_read += length;
                read_ptr += length;
                content_length -= length;
        }

        if ( bytes_read > 0 )
                rc->read_post_bytes += bytes_read;
        return bytes_read;
}

static char *sapi_nsapi_read_cookies(TSRMLS_D)
{
        char *cookie_string;
        nsapi_request_context *rc = (nsapi_request_context *)SG(server_context);

        cookie_string = pblock_findval("cookie", rc->rq->headers);
        return cookie_string;
}

static void
sapi_nsapi_register_server_variables(zval *track_vars_array TSRMLS_DC)
{
        nsapi_request_context *rc = (nsapi_request_context *)SG(server_context);
        register size_t i;
        char *value,*p;
        char buf[NS_BUF_SIZE + 1];
        struct pb_entry *entry;

        for (i = 0; i < nsapi_reqpb_size; i++) {
                value = pblock_findval(nsapi_reqpb[i].nsapi_eq, rc->rq->reqpb);
                if (value) {
                        php_register_variable( (char *)nsapi_reqpb[i].env_var, value, 
track_vars_array TSRMLS_CC );
                }
        }

        for (i = 0; i < nsapi_headers_size; i++) {
                value = pblock_findval(nsapi_headers[i].nsapi_eq, rc->rq->headers);
                if (value) {
                        php_register_variable( (char *)nsapi_headers[i].env_var, 
value, track_vars_array TSRMLS_CC );
                }
        }

        for (i=0; i < rc->rq->headers->hsize; i++) {
                entry=rc->rq->headers->ht[i];
                while (entry) {
                        snprintf(buf,NS_BUF_SIZE,"HTTP_%s",entry->param->name);
                        for(p = buf + 5; *p; p++) {
                                *p = toupper(*p);
                                if(*p < 'A' || *p > 'Z') {
                                        *p = '_';
                                }
                        }
                        php_register_variable( buf, entry->param->value, 
track_vars_array TSRMLS_CC );
                        entry=entry->next;
                }
        }

        for (i = 0; i < nsapi_vars_size; i++) {
                value = pblock_findval(nsapi_vars[i].nsapi_eq, rc->rq->vars);
                if (value) {
                        php_register_variable( (char *)nsapi_vars[i].env_var, value, 
track_vars_array TSRMLS_CC );
                }
        }

        for (i = 0; i < nsapi_client_size; i++) {
                value = pblock_findval(nsapi_client[i].nsapi_eq, rc->sn->client);
                if (value) {
                        php_register_variable( (char *)nsapi_client[i].env_var, value, 
track_vars_array TSRMLS_CC );
                }
        }

        if (value = session_dns(rc->sn)) {
                php_register_variable("REMOTE_HOST", value, track_vars_array TSRMLS_CC 
);
                nsapi_free(value);
        }

        sprintf(buf, "%d", conf_getglobals()->Vport);
        php_register_variable("SERVER_PORT", buf, track_vars_array TSRMLS_CC );

        php_register_variable("SERVER_NAME", conf_getglobals()->Vserver_hostname, 
track_vars_array TSRMLS_CC );

        value = http_uri2url_dynamic("", "", rc->sn, rc->rq);
        php_register_variable("SERVER_URL", value, track_vars_array TSRMLS_CC );
        nsapi_free(value);

        php_register_variable("SERVER_SOFTWARE", system_version(), track_vars_array 
TSRMLS_CC );

        php_register_variable("HTTPS", (security_active ? "ON" : "OFF"), 
track_vars_array TSRMLS_CC );

        php_register_variable("GATEWAY_INTERFACE", "CGI/1.1", track_vars_array 
TSRMLS_CC );


        /* DOCUMENT_ROOT */
        if (value = request_translate_uri("/", rc->sn)) {
                value[strlen(value)-1]=0;
                php_register_variable("DOCUMENT_ROOT", value, track_vars_array 
TSRMLS_CC );
                nsapi_free(value);
        }

        /* PATH_TRANSLATED */
        if (value = pblock_findval("path-info", rc->rq->vars)) {
                if (value = request_translate_uri(value, rc->sn)) {
                        php_register_variable("PATH_TRANSLATED", value, 
track_vars_array TSRMLS_CC );
                        nsapi_free(value);
                }
        }

        /* Create full Request-URI */
        if (value = pblock_findval("uri", rc->rq->reqpb)) {
                snprintf(buf,NS_BUF_SIZE, "%s", value);
                if (value = pblock_findval("query", rc->rq->reqpb)) {
                        p=strchr(buf,0);
                        snprintf(p, NS_BUF_SIZE-(p-buf), "?%s", value);
                }
                php_register_variable("REQUEST_URI", buf, track_vars_array TSRMLS_CC );
        }

        /* Create Script-Name */
        if (value = pblock_findval("uri", rc->rq->reqpb)) {
                snprintf(buf,NS_BUF_SIZE, "%s", value);
                if (value = pblock_findval("path-info", rc->rq->vars)) {
                        buf[strlen(buf) - strlen(value)]=0;
                }
                php_register_variable("SCRIPT_NAME", buf, track_vars_array TSRMLS_CC );
        }
}

static void
nsapi_log_message(char *message)
{
        TSRMLS_FETCH();
        nsapi_request_context *rc = (nsapi_request_context *)SG(server_context);
        log_error(LOG_INFORM, "PHP module", rc->sn, rc->rq,
                "%s", message);
}


static int php_nsapi_startup(sapi_module_struct *sapi_module)
{
        if (php_module_startup(sapi_module, NULL, 0)==FAILURE) {
                return FAILURE;
        }
        return SUCCESS;
}


static sapi_module_struct nsapi_sapi_module = {
        "nsapi",                                /* name */
        "NSAPI",                                /* pretty name */

        php_nsapi_startup,                      /* startup */
        php_module_shutdown_wrapper,            /* shutdown */

        NULL,                                   /* activate */
        NULL,                                   /* deactivate */

        sapi_nsapi_ub_write,                    /* unbuffered write */
        NULL,                                   /* flush */
        NULL,                                   /* get uid */
        NULL,                                   /* getenv */

        php_error,                              /* error handler */

        sapi_nsapi_header_handler,              /* header handler */
        sapi_nsapi_send_headers,                /* send headers handler */
        NULL,                                   /* send header handler */

        sapi_nsapi_read_post,                   /* read POST data */
        sapi_nsapi_read_cookies,                /* read Cookies */

        sapi_nsapi_register_server_variables,   /* register server variables */
        nsapi_log_message,                      /* Log message */

        NULL,                                   /* Block interruptions */
        NULL,                                   /* Unblock interruptions */

        STANDARD_SAPI_MODULE_PROPERTIES
};

static void
nsapi_request_ctor(NSLS_D TSRMLS_DC)
{
        char *query_string = pblock_findval("query", NSG(rq)->reqpb);
        char *uri = pblock_findval("uri", NSG(rq)->reqpb);
        char *path_info = pblock_findval("path-info", NSG(rq)->vars);
        char *request_method = pblock_findval("method", NSG(rq)->reqpb);
        char *content_type = pblock_findval("content-type", NSG(rq)->headers);
        char *content_length = pblock_findval("content-length", NSG(rq)->headers);
        char *path_translated=pblock_findval("path", NSG(rq)->vars);;

#if defined(NSAPI_DEBUG)
        log_error(LOG_INFORM, "nsapi_request_ctor", NSG(sn), NSG(rq),
                "query_string = %s, "
                "uri = %s, "
                "path_info = %s, "
                "path_translated = %s, "
                "request_method = %s, "
                "content_type = %s, "
                "content_length = %s",
                query_string,
                uri,
                path_info,
                path_translated,
                request_method,
                content_type,
                content_length);
#endif

        SG(request_info).query_string = nsapi_strdup(query_string);
        SG(request_info).request_uri = nsapi_strdup(uri);
        SG(request_info).request_method = nsapi_strdup(request_method);
        SG(request_info).path_translated = nsapi_strdup(path_translated);
        SG(request_info).content_type = nsapi_strdup(content_type);
        SG(request_info).content_length = (content_length == NULL) ? 0 : 
strtoul(content_length, 0, 0);
        SG(sapi_headers).http_response_code = 200;
}

static void
nsapi_request_dtor(NSLS_D TSRMLS_DC)
{
        nsapi_free(SG(request_info).query_string);
        nsapi_free(SG(request_info).request_uri);
        nsapi_free(SG(request_info).request_method);
        nsapi_free(SG(request_info).path_translated);
        nsapi_free(SG(request_info).content_type);
}

int
nsapi_module_main(NSLS_D TSRMLS_DC)
{
        zend_file_handle file_handle;

        if (php_request_startup(TSRMLS_C) == FAILURE) {
                return FAILURE;
        }

        file_handle.type = ZEND_HANDLE_FILENAME;
        file_handle.filename = SG(request_info).path_translated;
        file_handle.free_filename = 0;
        file_handle.opened_path = NULL;

#if defined(NSAPI_DEBUG)
        log_error(LOG_INFORM, "nsapi_module_main", NSG(sn), NSG(rq),
                "Parsing [%s]", SG(request_info).path_translated);
#endif

        php_execute_script(&file_handle TSRMLS_CC);
        php_request_shutdown(NULL);

#if defined(NSAPI_DEBUG)
        log_error(LOG_INFORM, "nsapi_module_main", NSG(sn), NSG(rq),
                "PHP request finished Ok");
#endif
        return SUCCESS;
}

void NSAPI_PUBLIC
php4_close(void *vparam)
{
        if (nsapi_sapi_module.shutdown) {
                nsapi_sapi_module.shutdown(&nsapi_sapi_module);
        }
        tsrm_shutdown();
}

int NSAPI_PUBLIC
php4_init(pblock *pb, Session *sn, Request *rq)
{
        php_core_globals *core_globals;

        tsrm_startup(1, 1, 0, NULL);
        core_globals = ts_resource(core_globals_id);

        sapi_startup(&nsapi_sapi_module);
        nsapi_sapi_module.startup(&nsapi_sapi_module);

        log_error(LOG_INFORM, "php4_init", sn, rq, "Initialized PHP Module\n");
        return REQ_PROCEED;
}

int NSAPI_PUBLIC
php4_execute(pblock *pb, Session *sn, Request *rq)
{
        int retval;
        nsapi_request_context *request_context;

        TSRMLS_FETCH();

        request_context = (nsapi_request_context 
*)MALLOC(sizeof(nsapi_request_context));
        request_context->pb = pb;
        request_context->sn = sn;
        request_context->rq = rq;
        request_context->read_post_bytes = 0;

        SG(server_context) = request_context;

        nsapi_request_ctor(NSLS_C TSRMLS_CC);
        retval = nsapi_module_main(NSLS_C TSRMLS_CC);
        nsapi_request_dtor(NSLS_C TSRMLS_CC);

        FREE(request_context);

        return (retval == SUCCESS) ? REQ_PROCEED : REQ_EXIT;
}

/*********************************************************
/ authentication
/
/ we have to make a 'fake' authenticator for netscape so it
/ will pass authentication through to php, and allow us to
/ check authentication with our scripts.
/
/ php4_auth_trans
/   main function called from netscape server to authenticate
/   a line in obj.conf:
/               funcs=php4_auth_trans shlib="path/to/this/phpnsapi.dll"
/       and:
/               <Object ppath="path/to/be/authenticated/by/php/*">
/               AuthTrans fn="php4_auth_trans"
/*********************************************************/
int NSAPI_PUBLIC
php4_auth_trans(pblock * pb, Session * sn, Request * rq)
{
        /*This is a DO NOTHING function that allows authentication information
        to be passed through to PHP scripts.*/
        return REQ_PROCEED;
}

-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to