ID:               22019
 Updated by:       [EMAIL PROTECTED]
 Reported By:      [EMAIL PROTECTED]
 Status:           Open
 Bug Type:         iPlanet related
 Operating System: Solaris 2.9
 PHP Version:      4.3.0
 New Comment:

Hi,

in the php-4.3.0 source tree, there's a file called
README.SUBMITTING_PATCH. It explains in detail, how to submit patches
for php.
Please use it, because posting it here is subject to all kinds of
formatting issues. Also - the maintainers cannot really see what you've
changed and asses the impact of your proposed changes.


Previous Comments:
------------------------------------------------------------------------

[2003-02-02 16:09:38] [EMAIL PROTECTED]

As a lot of variables are not transferred correctly to the PHP script
that runs in iPlanet Webserver (4 or 6), i rewrite a lot of code in
nsapi.c. It now transfers all variables from rc->rq->headers to
php_register_variable("HTTP_"+varname,...).
Also missing variables "SERVER_SOFTWARE" are added.

---- code begins here ----
/*
  
+----------------------------------------------------------------------+
   | 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]>                
  |
  
+----------------------------------------------------------------------+
*/

/*
 * 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 NSHEADER_BUF_SIZE 1024

/*
 * 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" },
        { "SCRIPT_NAME",                "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" },
        { "PATH_TRANSLATED",    "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 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);
        size_t i;
        char *value,*p;
        char c;
        char buf[NSHEADER_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,NSHEADER_BUF_SIZE,"HTTP_%s",entry->param->name);
                for(p = buf + 5; (c = *p); p++) {
                        c = toupper(c);
                        if(c < 'A' || c > 'Z') {
                                c = '_';
                        }
                        *p = c;
                }
                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 );
                }
        }

        value = session_dns(rc->sn);
        if (value) {
          php_register_variable("REMOTE_HOST", value, track_vars_array
TSRMLS_CC );
          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("", "");
        php_register_variable("SERVER_URL", value, track_vars_array TSRMLS_CC
);
        free(value);
        php_register_variable("HTTPS", (security_active ? "ON" : "OFF"),
track_vars_array TSRMLS_CC );
        php_register_variable("SERVER_SOFTWARE", system_version(),
track_vars_array TSRMLS_CC );

        value = pblock_findval("uri", rc->rq->reqpb);
        if (value) {
                php_register_variable("PHP_SELF", value, 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 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 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 *path_translated = pblock_findval("path", 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);

        if ((path_translated == NULL) && (uri != NULL))
                path_translated = request_translate_uri(uri, NSG(sn));

#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;
}


------------------------------------------------------------------------


-- 
Edit this bug report at http://bugs.php.net/?id=22019&edit=1

Reply via email to