tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Steven Velez <sve...@alventive.com>
Subject RE: [PATCH] Fixing Interoperability problem in iis connector
Date Wed, 13 Nov 2002 13:06:54 GMT
OK... I wasn't sure if that was an acceptable solution.  In that case, the
patch for existing files is one attachment and the two new files are two
other attachments.  They need to go in
jakarta-tomcat-connectors\jk\native\iis.  Thanks.

----------------------------
  .-.    | Steven Velez
  oo|    | Software Engineer
 /`'\    | alventive
(\_;/)   | 678-202-2226






-----Original Message-----
From: Bill Barker [mailto:wbarker@wilshire.com]
Sent: Tuesday, November 12, 2002 2:24 PM
To: Tomcat Developers List
Subject: Re: [PATCH] Fixing Interoperability problem in iis connector


Post the patch as an attachment.

----- Original Message -----
From: "Steven Velez" <svelez@alventive.com>
To: "'Tomcat Developers List'" <tomcat-dev@jakarta.apache.org>
Sent: Tuesday, November 12, 2002 10:00 AM
Subject: RE: [PATCH] Fixing Interoperability problem in iis connector


> OK.. this time I sent a test before posting... and the post still has
> problems.... it seems the list server (or something) is wrapping long
> lines..... how do I deal with this?
>
>
> ----------------------------
>   .-.    | Steven Velez
>   oo|    | Software Engineer
>  /`'\    | alventive
> (\_;/)   | 678-202-2226
>
>
>
>
>
>
> -----Original Message-----
> From: Steven Velez [mailto:svelez@alventive.com]
> Sent: Tuesday, November 12, 2002 12:23 PM
> To: 'Tomcat Developers List'
> Subject: RE: [PATCH] Fixing Interoperability problem in iis connector
>
>
> This should, hopefully, be correctly formatted.
>
>
> Index: isapi.dsp
> ===================================================================
> RCS file:
> /home/cvspublic/jakarta-tomcat-connectors/jk/native/iis/isapi.dsp,v
> retrieving revision 1.9
> diff -u -r1.9 isapi.dsp
> --- isapi.dsp 9 Apr 2002 23:06:52 -0000 1.9
> +++ isapi.dsp 12 Nov 2002 16:58:07 -0000
> @@ -170,6 +170,10 @@
>
>  SOURCE=..\common\jk_worker.c
>  # End Source File
> +# Begin Source File
> +
> +SOURCE=.\req_info.c
> +# End Source File
>  # End Group
>  # Begin Group "Header Files"
>
> @@ -265,6 +269,10 @@
>  # Begin Source File
>
>  SOURCE=..\common\jk_worker.h
> +# End Source File
> +# Begin Source File
> +
> +SOURCE=.\req_info.h
>  # End Source File
>  # End Group
>  # Begin Group "Resource Files"
> Index: jk_isapi_plugin.c
> ===================================================================
> RCS file:
>
/home/cvspublic/jakarta-tomcat-connectors/jk/native/iis/jk_isapi_plugin.c,v
> retrieving revision 1.18
> diff -u -r1.18 jk_isapi_plugin.c
> --- jk_isapi_plugin.c 25 Sep 2002 00:49:40 -0000 1.18
> +++ jk_isapi_plugin.c 12 Nov 2002 16:58:07 -0000
> @@ -78,6 +78,8 @@
>  #include "jk_worker.h"
>  #include "jk_uri_worker_map.h"
>
> +#include "req_info.h"
> +
>  #define VERSION_STRING "Jakarta/ISAPI/" JK_VERSTRING
>
>  #define DEFAULT_WORKER_NAME ("ajp13")
> @@ -109,6 +111,8 @@
>  #define URI_SELECT_UNPARSED_VERB    ("unparsed")
>  #define URI_SELECT_ESCAPED_VERB     ("escaped")
>
> +#define SHMEM_REQUEST_INFO_TAG  ("use_shared_mem")
> +
>  #define BAD_REQUEST -1
>  #define BAD_PATH -2
>  #define MAX_SERVERNAME 128
> @@ -142,6 +146,17 @@
>      }           \
>  }\
>
> +#define GET_REQ_INFO_VALUE(ri, name, var) { \
> +    char *temp; \
> +    if (temp = rinfo_get_##name (ri)) \
> +    { \
> +        (var) = jk_pool_strdup(&private_data->p, temp); \
> +    } else { \
> +        (var) = NULL; \
> +    } \
> +} \
> +
> +
>  static char  ini_file_name[MAX_PATH];
>  static int   using_ini_file = JK_FALSE;
>  static int   is_inited = JK_FALSE;
> @@ -159,6 +174,7 @@
>  static int  log_level = JK_LOG_EMERG_LEVEL;
>  static char worker_file[MAX_PATH * 2];
>  static char worker_mount_file[MAX_PATH * 2];
> +static int  shmem_enabled = JK_FALSE;
>
>  #define URI_SELECT_OPT_PARSED       0
>  #define URI_SELECT_OPT_UNPARSED     1
> @@ -670,6 +686,7 @@
>          char Host[INTERNET_MAX_URL_LENGTH]="";
>          char Port[INTERNET_MAX_URL_LENGTH]="";
>          char Translate[INTERNET_MAX_URL_LENGTH];
> +        char target_uri_buff[INTERNET_MAX_URL_LENGTH]="";
>   BOOL (WINAPI * GetHeader)
>   (struct _HTTP_FILTER_CONTEXT * pfc, LPSTR lpszName,
> LPVOID lpvBuffer, LPDWORD lpdwSize );
>   BOOL (WINAPI * SetHeader)
> @@ -681,6 +698,8 @@
>          DWORD szHost = sizeof(Host);
>          DWORD szPort = sizeof(Port);
>          DWORD szTranslate = sizeof(Translate);
> + request_information_t *p_request_info = NULL;
> +        request_info_name_t info_name = 0;
>
>   if (iis5) {
>
> GetHeader=((PHTTP_FILTER_AUTH_COMPLETE_INFO)pvNotification)->GetHeader;
> @@ -700,11 +719,13 @@
>          /*
>           * Just in case somebody set these headers in the request!
>           */
> -        SetHeader(pfc, URI_HEADER_NAME, NULL);
> -        SetHeader(pfc, QUERY_HEADER_NAME, NULL);
> -        SetHeader(pfc, WORKER_HEADER_NAME, NULL);
> -        SetHeader(pfc, TOMCAT_TRANSLATE_HEADER_NAME, NULL);
> -
> +        if (!shmem_enabled) {
> +            SetHeader(pfc, URI_HEADER_NAME, NULL);
> +            SetHeader(pfc, QUERY_HEADER_NAME, NULL);
> +            SetHeader(pfc, WORKER_HEADER_NAME, NULL);
> +            SetHeader(pfc, TOMCAT_TRANSLATE_HEADER_NAME, NULL);
> +        }
> +
>          if (!GetHeader(pfc, "url", (LPVOID)uri, (LPDWORD)&sz)) {
>              jk_log(logger, JK_LOG_ERROR,
>                     "HttpFilterProc error while getting the url\n");
> @@ -802,14 +823,30 @@
>                      forwardURI = uri;
>                  }
>
> -                if(!AddHeader(pfc, URI_HEADER_NAME, forwardURI) ||
> -                   ( (query != NULL && strlen(query) > 0)
> -                           ? !AddHeader(pfc, QUERY_HEADER_NAME, query) :
> FALSE ) ||
> -                   !AddHeader(pfc, WORKER_HEADER_NAME, worker) ||
> -                   !SetHeader(pfc, "url", extension_uri)) {
> -                    jk_log(logger, JK_LOG_ERROR,
> -                           "HttpFilterProc error while adding request
> headers\n");
> -                    return SF_STATUS_REQ_ERROR;
> +                if (!shmem_enabled) {
> +                    if(!AddHeader(pfc, URI_HEADER_NAME, forwardURI) ||
> +                       ( (query != NULL && strlen(query) > 0)
> +                               ? !AddHeader(pfc, QUERY_HEADER_NAME,
query)
> : FALSE ) ||
> +                       !AddHeader(pfc, WORKER_HEADER_NAME, worker) ||
> +                       !SetHeader(pfc, "url", extension_uri)) {
> +                        jk_log(logger, JK_LOG_ERROR,
> +                               "HttpFilterProc error while adding request
> headers\n");
> +                        return SF_STATUS_REQ_ERROR;
> +                    }
> +                }
> +                else {
> +                    p_request_info = rinfo_new();
> +                    if (p_request_info == NULL) {
> +                        jk_log(logger, JK_LOG_ERROR, "HttpFilterProc
failed
> allocating memory "
> +                         "for request information\n");
> +                        return SF_STATUS_REQ_ERROR;
> +                    }
> +
> +                    rinfo_set_uri(p_request_info, forwardURI);
> +                    if (query != NULL && strlen(query) > 0) {
> +                     rinfo_set_query_string(p_request_info, query);
> +                    }
> +                    rinfo_set_worker(p_request_info, worker);
>                  }
>
>                  /* Move Translate: header to a temporary header so
> @@ -821,9 +858,33 @@
>                      if (!AddHeader(pfc, TOMCAT_TRANSLATE_HEADER_NAME,
> Translate)) {
>                          jk_log(logger, JK_LOG_ERROR,
>                            "HttpFilterProc error while adding
> Tomcat-Translate headers\n");
> +                        rinfo_delete(p_request_info);
>                          return SF_STATUS_REQ_ERROR;
>                      }
> -                SetHeader(pfc, "Translate:", NULL);
> +
> +                    SetHeader(pfc, "Translate:", NULL);
> +                }
> +
> +
> +                if (shmem_enabled) {
> +                    if ((info_name = rinfo_map_insert(p_request_info)) ==
> REQUEST_INFO_ERR_NAME) {
> +                        rinfo_delete(p_request_info);
> +                        jk_log(logger, JK_LOG_ERROR,
> +                               "HttpFilterProc failed to set the request
> info\n");
> +                        return SF_STATUS_REQ_ERROR;
> +                    }
> +
> +                    if (!SetHeader(pfc, "url",
> +
rinfo_append_name_to_uri(extension_uri,
> info_name,
> +
> target_uri_buff,
> +
> INTERNET_MAX_URL_LENGTH)
> +                                   )) {
> +
> +                        rinfo_delete(p_request_info);
> +                        jk_log(logger, JK_LOG_ERROR,
> +                               "HttpFilterProc error while adding request
> headers\n");
> +                        return SF_STATUS_REQ_ERROR;
> +                    }
>                  }
>              } else {
>                  jk_log(logger, JK_LOG_DEBUG,
> @@ -961,6 +1022,12 @@
>   uri_worker_map_free(&uw_map, logger);
>   is_mapread = JK_FALSE;
>   }
> +
> +        if (shmem_enabled)
> +        {
> +     rinfo_close_map();
> +        }
> +
>          wc_close(logger);
>          if (logger) {
>              jk_close_file_logger(&logger);
> @@ -1023,6 +1090,10 @@
>      jk_log(logger, JK_LOG_DEBUG, "Using worker file %s.\n", worker_file);
>      jk_log(logger, JK_LOG_DEBUG, "Using worker mount file %s.\n",
> worker_mount_file);
>      jk_log(logger, JK_LOG_DEBUG, "Using uri select %d.\n",
> uri_select_option);
> +    if (shmem_enabled) {
> +        jk_log(logger, JK_LOG_DEBUG, "Using shared memory to pass
> information from "
> +               "the filter to the extension.\n");
> +    }
>
>      if (map_alloc(&map)) {
>          if (map_read_properties(map, worker_mount_file)) {
> @@ -1079,6 +1150,11 @@
>          }
>      }
>
> + if (rc && shmem_enabled)
> + {
> + rc = rinfo_init_map(logger);
> + }
> +
>      return rc;
>  }
>
> @@ -1108,6 +1184,32 @@
>      return -1;
>  }
>
> +
> +int parse_enable_shmem(const char *shmem)
> +{
> +    char *shmem_indicators[] = {"on", "true", "enable", NULL};
> +    int ret =  JK_FALSE;
> +    int sh_mem_int = 0;
> +    char **cur_indicator = shmem_indicators;
> +
> +    if (sscanf(shmem, "%d", &sh_mem_int) != EOF && sh_mem_int)
> +    {
> +        ret = JK_TRUE;
> +    }
> +
> +
> +    while (!ret && *cur_indicator)
> +    {
> +        if (stricmp(shmem, *(cur_indicator++)) == 0)
> +        {
> +            ret = JK_TRUE;
> +        }
> +    }
> +
> +    return ret;
> +}
> +
> +
>  static int read_registry_init_data(void)
>  {
>      char tmpbuf[INTERNET_MAX_URL_LENGTH];
> @@ -1162,6 +1264,10 @@
>                  ok = JK_FALSE;
>              }
>          }
> +        tmp = map_get_string(map, SHMEM_REQUEST_INFO_TAG, NULL);
> +        if (tmp) {
> +            shmem_enabled = parse_enable_shmem(tmp);
> +        }
>
>      } else {
>          rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
> @@ -1230,6 +1336,13 @@
>              }
>          }
>
> +        if (get_registry_config_parameter(hkey,
> +                                          SHMEM_REQUEST_INFO_TAG,
> +                                          tmpbuf,
> +                                          sizeof(tmpbuf))) {
> +            shmem_enabled = parse_enable_shmem(tmpbuf);
> +        }
> +
>          RegCloseKey(hkey);
>      }
>      return ok;
> @@ -1263,6 +1376,8 @@
>                             char **worker_name)
>  {
>      char huge_buf[16 * 1024]; /* should be enough for all */
> +    request_information_t *preq_info = NULL;
> +    request_info_name_t name = 0;
>
>      DWORD huge_buf_sz;
>
> @@ -1272,17 +1387,40 @@
>      s->read = read;
>      s->write = write;
>
> -    GET_SERVER_VARIABLE_VALUE(HTTP_WORKER_HEADER_NAME, (*worker_name));
>
> -    GET_SERVER_VARIABLE_VALUE(HTTP_URI_HEADER_NAME, s->req_uri);
> -    GET_SERVER_VARIABLE_VALUE(HTTP_QUERY_HEADER_NAME, s->query_string);
>
> -
> -    if (s->req_uri == NULL) {
> -        s->query_string = private_data->lpEcb->lpszQueryString;
> -        *worker_name    = DEFAULT_WORKER_NAME;
> -        GET_SERVER_VARIABLE_VALUE("URL", s->req_uri);
> -        if (unescape_url(s->req_uri) < 0)
> +    if (! shmem_enabled) {
> +        GET_SERVER_VARIABLE_VALUE(HTTP_WORKER_HEADER_NAME,
(*worker_name));
>
> +        GET_SERVER_VARIABLE_VALUE(HTTP_URI_HEADER_NAME, s->req_uri);
> +        GET_SERVER_VARIABLE_VALUE(HTTP_QUERY_HEADER_NAME,
s->query_string);
>
> +
> +        if (s->req_uri == NULL) {
> +            s->query_string = private_data->lpEcb->lpszQueryString;
> +            *worker_name    = DEFAULT_WORKER_NAME;
> +            GET_SERVER_VARIABLE_VALUE("URL", s->req_uri);
> +            if (unescape_url(s->req_uri) < 0)
> +                return JK_FALSE;
> +            getparents(s->req_uri);
> +        }
> +    }
> +    else {
> +
> +        if ((name =
> rinfo_name_from_query(private_data->lpEcb->lpszQueryString)) ==
> +            REQUEST_INFO_ERR_NAME) {
> +
> +            jk_log(logger, JK_LOG_ERROR, "Failed to read request name
from
> "
> +                   "query string\n");
>              return JK_FALSE;
> -        getparents(s->req_uri);
> +        }
> +
> +        if (!(preq_info = rinfo_map_remove_at(name))) {
> +
> +            jk_log(logger, JK_LOG_ERROR, "Failed to find and remove the
> named "
> +                   "request: %d.\n", name);
> +            return JK_FALSE;
> +        }
> +
> +        GET_REQ_INFO_VALUE(preq_info, worker, (*worker_name));
> +        GET_REQ_INFO_VALUE(preq_info, uri, s->req_uri);
> +        GET_REQ_INFO_VALUE(preq_info, query_string, s->query_string);
>      }
>
>      GET_SERVER_VARIABLE_VALUE("AUTH_TYPE", s->auth_type);
> @@ -1406,7 +1544,10 @@
>              unsigned len_of_http_prefix = strlen("HTTP_");
>              BOOL need_content_length_header = (s->content_length == 0);
>
> -            cnt -= 2; /* For our two special headers */
> +            if (!shmem_enabled) {
> +                cnt -= 2; /* For our two special headers */
> +            }
> +
>              /* allocate an extra header slot in case we need to add a
> content-length header */
>              s->headers_names  = jk_pool_alloc(&private_data->p, (cnt + 1)
*
> sizeof(char *));
>              s->headers_values = jk_pool_alloc(&private_data->p, (cnt + 1)
*
> sizeof(char *));
>
>
>
>
>
>
>
> File: /home/cvspublic/jakarta-tomcat-connectors/jk/native/iis/req_info.h
> /*
=========================================================================
> *
>  *
> *
>  *                 The Apache Software License,  Version 1.1
> *
>  *
> *
>  *          Copyright (c) 1999-2001 The Apache Software Foundation.
> *
>  *                           All rights reserved.
> *
>  *
> *
>  *
=========================================================================
> *
>  *
> *
>  * Redistribution and use in source and binary forms,  with or without
modi-
> *
>  * fication, are permitted provided that the following conditions are met:
> *
>  *
> *
>  * 1. Redistributions of source code  must retain the above copyright
notice
> *
>  *    notice, this list of conditions and the following disclaimer.
> *
>  *
> *
>  * 2. Redistributions  in binary  form  must  reproduce the  above
copyright
> *
>  *    notice,  this list of conditions  and the following  disclaimer in
the
> *
>  *    documentation and/or other materials provided with the distribution.
> *
>  *
> *
>  * 3. The end-user documentation  included with the redistribution,  if
any,
> *
>  *    must include the following acknowlegement:
> *
>  *
> *
>  *       "This product includes  software developed  by the Apache
Software
> *
>  *        Foundation <http://www.apache.org/>."
> *
>  *
> *
>  *    Alternately, this acknowlegement may appear in the software itself,
if
> *
>  *    and wherever such third-party acknowlegements normally appear.
> *
>  *
> *
>  * 4. The names  "The  Jakarta  Project",  "Jk",  and  "Apache  Software
> *
>  *    Foundation"  must not be used  to endorse or promote  products
derived
> *
>  *    from this  software without  prior  written  permission.  For
written
> *
>  *    permission, please contact <apache@apache.org>.
> *
>  *
> *
>  * 5. Products derived from this software may not be called "Apache" nor
may
> *
>  *    "Apache" appear in their names without prior written permission of
the
> *
>  *    Apache Software Foundation.
> *
>  *
> *
>  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
WARRANTIES
> *
>  * INCLUDING, BUT NOT LIMITED TO,  THE IMPLIED WARRANTIES OF
MERCHANTABILITY
> *
>  * AND FITNESS FOR  A PARTICULAR PURPOSE  ARE DISCLAIMED.  IN NO EVENT
SHALL
> *
>  * THE APACHE  SOFTWARE  FOUNDATION OR  ITS CONTRIBUTORS  BE LIABLE  FOR
ANY
> *
>  * DIRECT,  INDIRECT,   INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR
CONSEQUENTIAL
> *
>  * DAMAGES (INCLUDING,  BUT NOT LIMITED TO,  PROCUREMENT OF SUBSTITUTE
GOODS
> *
>  * OR SERVICES;  LOSS OF USE,  DATA,  OR PROFITS;  OR BUSINESS
INTERRUPTION)
> *
>  * HOWEVER CAUSED AND  ON ANY  THEORY  OF  LIABILITY,  WHETHER IN
CONTRACT,
> *
>  * STRICT LIABILITY, OR TORT  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN
> *
>  * ANY  WAY  OUT OF  THE  USE OF  THIS  SOFTWARE,  EVEN  IF  ADVISED  OF
THE
> *
>  * POSSIBILITY OF SUCH DAMAGE.
> *
>  *
> *
>  *
=========================================================================
> *
>  *
> *
>  * This software  consists of voluntary  contributions made  by many
indivi-
> *
>  * duals on behalf of the  Apache Software Foundation.  For more
information
> *
>  * on the Apache Software Foundation, please see <http://www.apache.org/>.
> *
>  *
> *
>  *
=========================================================================
> */
>
>
/***************************************************************************
>  * Description: Utilities to to keep track of request information
*
>  * Author:      Steven Velez <svelez@alventive.com>
*
>
>  * Version:     $Revision:     $
*
>
>
***************************************************************************/
>
>
> #ifndef REQ_INFO_H
> #define REQ_INFO_H
>
> #include "jk_pool.h"
> #include "jk_logger.h"
>
> #ifdef __cpluplus
> extern "C"
> {
> #endif
>
> /*
>  * The information 'class' that will store information
>  * for a particular request.  This information will be set in the filter
>  * and read in the extension.
>  */
> struct _request_information
> {
>     /* The name of the worker selected by the filter.
>      * Relaces "TOMCATWORKER:" */
>     char *worker_name;
>     /* The uri of the original request.
>      * Replaces "TOMCATURI:" */
> char *uri;
>     /* The query string of the original request.
>      * Replaces "TOMCATQUERY:" */
> char *query_string;
>
>     /** For keeping track of the various allocations of member data */
>     jk_pool_t p;
>     jk_pool_atom_t buff[BIG_POOL_SIZE];
> };
> typedef struct _request_information request_information_t;
> typedef unsigned long request_info_name_t;
>
> #define REQUEST_INFO_ERR_NAME (0)
>
> /* Management functions to intialize and destroy a global request info map
> */
> int rinfo_init_map(jk_logger_t *log);
> int rinfo_close_map();
>
> /* Insert a request information object in the map */
> request_info_name_t rinfo_map_insert(request_information_t * ri);
> /* Find the request information object related to the given request.
>  * This function returns 'NULL' if the object can not be found */
> request_information_t *rinfo_map_at(request_info_name_t req);
> /* Find the requwst information object related to the give request.
>  * This function will also remove the object from the map. */
> request_information_t *rinfo_map_remove_at(request_info_name_t req);
>
> /* utility function to append a request info name to a uri
>  * the return value of the function is a pointer to the caller-supplied
>  * buffer */
> char *rinfo_append_name_to_uri(char *uri, request_info_name_t req,
>                char *buff, size_t size);
> /* Utiltity function to retreive a request info name from
>  * a query string */
> request_info_name_t rinfo_name_from_query(char *query);
>
> /* Object lifetime management functions... these should be used to
>  * create and destroy a request_info object */
> request_information_t *rinfo_new();
> void rinfo_delete(request_information_t * ri);
>
> /* functions to set data in the request info object.  These functions
>  * duplicate the parameters, so it will remain the responsibility of
>  * the caller to manage the memory pointed to in the second parameter. */
> void rinfo_set_worker(request_information_t * ri, char *name);
> void rinfo_set_uri(request_information_t * ri, char *uri);
> void rinfo_set_query_string(request_information_t * ri, char *qs);
>
> /* functions to access data in the request info object.
>  * They return poitners to internal buffers, so callers should not
> manipulate
>  * them directly. */
> char *rinfo_get_worker(request_information_t * ri);
> char *rinfo_get_uri(request_information_t * ri);
> char *rinfo_get_query_string(request_information_t * ri);
>
> #ifdef __cplusplus
> }
> #endif
> #endif
>
>
>
>
>
> File: /home/cvspublic/jakarta-tomcat-connectors/jk/native/iis/req_info.c
> /*
=========================================================================
> *
>  *
> *
>  *                 The Apache Software License,  Version 1.1
> *
>  *
> *
>  *          Copyright (c) 1999-2001 The Apache Software Foundation.
> *
>  *                           All rights reserved.
> *
>  *
> *
>  *
=========================================================================
> *
>  *
> *
>  * Redistribution and use in source and binary forms,  with or without
modi-
> *
>  * fication, are permitted provided that the following conditions are met:
> *
>  *
> *
>  * 1. Redistributions of source code  must retain the above copyright
notice
> *
>  *    notice, this list of conditions and the following disclaimer.
> *
>  *
> *
>  * 2. Redistributions  in binary  form  must  reproduce the  above
copyright
> *
>  *    notice,  this list of conditions  and the following  disclaimer in
the
> *
>  *    documentation and/or other materials provided with the distribution.
> *
>  *
> *
>  * 3. The end-user documentation  included with the redistribution,  if
any,
> *
>  *    must include the following acknowlegement:
> *
>  *
> *
>  *       "This product includes  software developed  by the Apache
Software
> *
>  *        Foundation <http://www.apache.org/>."
> *
>  *
> *
>  *    Alternately, this acknowlegement may appear in the software itself,
if
> *
>  *    and wherever such third-party acknowlegements normally appear.
> *
>  *
> *
>  * 4. The names  "The  Jakarta  Project",  "Jk",  and  "Apache  Software
> *
>  *    Foundation"  must not be used  to endorse or promote  products
derived
> *
>  *    from this  software without  prior  written  permission.  For
written
> *
>  *    permission, please contact <apache@apache.org>.
> *
>  *
> *
>  * 5. Products derived from this software may not be called "Apache" nor
may
> *
>  *    "Apache" appear in their names without prior written permission of
the
> *
>  *    Apache Software Foundation.
> *
>  *
> *
>  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
WARRANTIES
> *
>  * INCLUDING, BUT NOT LIMITED TO,  THE IMPLIED WARRANTIES OF
MERCHANTABILITY
> *
>  * AND FITNESS FOR  A PARTICULAR PURPOSE  ARE DISCLAIMED.  IN NO EVENT
SHALL
> *
>  * THE APACHE  SOFTWARE  FOUNDATION OR  ITS CONTRIBUTORS  BE LIABLE  FOR
ANY
> *
>  * DIRECT,  INDIRECT,   INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR
CONSEQUENTIAL
> *
>  * DAMAGES (INCLUDING,  BUT NOT LIMITED TO,  PROCUREMENT OF SUBSTITUTE
GOODS
> *
>  * OR SERVICES;  LOSS OF USE,  DATA,  OR PROFITS;  OR BUSINESS
INTERRUPTION)
> *
>  * HOWEVER CAUSED AND  ON ANY  THEORY  OF  LIABILITY,  WHETHER IN
CONTRACT,
> *
>  * STRICT LIABILITY, OR TORT  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN
> *
>  * ANY  WAY  OUT OF  THE  USE OF  THIS  SOFTWARE,  EVEN  IF  ADVISED  OF
THE
> *
>  * POSSIBILITY OF SUCH DAMAGE.
> *
>  *
> *
>  *
=========================================================================
> *
>  *
> *
>  * This software  consists of voluntary  contributions made  by many
indivi-
> *
>  * duals on behalf of the  Apache Software Foundation.  For more
information
> *
>  * on the Apache Software Foundation, please see <http://www.apache.org/>.
> *
>  *
> *
>  *
=========================================================================
> */
>
>
/***************************************************************************
>  * Description: Utilities to to keep track of request information
*
>  * Author:      Steven Velez <svelez@alventive.com>
*
>
>  * Version:     $Revision:     $
*
>
>
***************************************************************************/
>
> #include "req_info.h"
> #include "jk_mt.h"
> #include "jk_util.h"
>
> #include <limits.h>
> #include <stddef.h>
>
> /*
>  * A node defination for a linked list
>  * that will implement a custom map data structure.
>  * I am using this as opposed to the jk_map because we need more
>  * precise control of memory allocation for the sake of iffeciency since
>  * this will be used as a global structure.
>  */
> static struct _request_map_node
> {
>     request_info_name_t name;
>     request_information_t *ri;
>     struct _request_map_node *next;
> };
>
> /* use a define instead of a typedef so that this definition
>  * will not be accessible outside this file */
> #define NODE_T struct _request_map_node
> /* The querystring variable that will hold a request_info_name */
> #define QUERY_VAR "REQ_INFO_NAME"
>
> #if defined(_DEBUG)
> /* Helper macros for logging */
> #define LOG_CRIT_SEC(action, result) {\
>     if (!result) { \
>         jk_log(logger, JK_LOG_INFO, "Did not " #action \
>                " the critical section\n"); \
>     } \
> } \
>
> #define LOG_ENTER(func_name) { \
>     jk_log(logger, JK_LOG_DEBUG, "--> ENTERING " #func_name " <---\n");\
> }\
>
> #define LOG_EXIT(func_name) { \
>     jk_log(logger, JK_LOG_DEBUG, "--> EXITING " #func_name " <---\n");\
> }\
>
> #else
> #define LOG_CRIT_SEC(action, result)
> #define LOG_ENTER(func_name)
> #define LOG_EXIT(func_name)
> #endif
>
>
> /* The root of the map */
> static NODE_T *g_map_head = NULL;
> /* The insertion point of the map */
> static NODE_T *g_map_tail = NULL;
> /* Synchronization structure */
> static JK_CRIT_SEC g_crit_sec;
> /* The next name value */
> static request_info_name_t g_next_name = 0;
> /* logging object */
> jk_logger_t *logger = NULL;
>
> int rinfo_init_map(jk_logger_t *l)
> {
>     int success = JK_FALSE;
>     LOG_ENTER(rinfo_init_map);
>
>     if (l == NULL) {
>         LOG_EXIT(rinfo_init_map);
>         return JK_FALSE;
>     }
>     logger = l;
>
>     JK_INIT_CS(&g_crit_sec, success);
>     if (success == JK_FALSE) {
>         jk_log(logger, JK_LOG_ERROR, "Failed to initialize the map
critical
> "
>                "section\n");
>         LOG_EXIT(rinfo_init_map);
>         return JK_FALSE;
>     }
>
>     g_map_head = NULL;
>     g_map_tail = g_map_head;
>
>     LOG_EXIT(rinfo_init_map);
>     return JK_TRUE;
> }
>
>
> int rinfo_close_map()
> {
>     int success = JK_FALSE;
>     NODE_T *pcurrent = g_map_head;
>     NODE_T *ptemp = NULL;
>     LOG_ENTER(rinfo_init_map);
>
>     /* remove the current entries */
>     JK_ENTER_CS(&g_crit_sec, success);
>     if (success == JK_FALSE) {
>     /* we are in big trouble; however, I guess a memory leak on
> shutdown
>          * is better than a crash */
>         jk_log(logger, JK_LOG_INFO, "Did not obtain a critical section
> object "
>                "for freeing map resources.\n");
>         LOG_EXIT(rinfo_init_map);
>     return JK_FALSE;
>     }
>
>     while (pcurrent != NULL) {
>         rinfo_delete(pcurrent->ri);
>         ptemp = pcurrent;
>         pcurrent = pcurrent->next;
>
>         if (ptemp != NULL) {
>         free((void *) ptemp);
>         }
>     }
>
>     g_map_head = NULL;
>     g_map_tail = NULL;
>
>     JK_LEAVE_CS(&g_crit_sec, success);
>     LOG_CRIT_SEC(leave, success);
>
>     /* get rid of the critical section */
>     JK_DELETE_CS(&g_crit_sec, success);
>     if (!success) {
>         jk_log(logger, JK_LOG_INFO, "Failed to delete critical section
> object "
>                "after freeing map resources.\n");
>     }
>
>     LOG_EXIT(rinfo_init_map);
>     return JK_TRUE;
> }
>
>
> request_info_name_t rinfo_map_insert(request_information_t * ri)
> {
>     int success = JK_FALSE;
>     request_info_name_t new_name = REQUEST_INFO_ERR_NAME;
>     NODE_T *new_node = NULL;
>     LOG_ENTER(rinfo_map_insert);
>
>     JK_ENTER_CS(&g_crit_sec, success);
>     if (success == JK_FALSE) {
>         LOG_CRIT_SEC(enter, success);
>         LOG_EXIT(rinfo_map_insert);
>         return REQUEST_INFO_ERR_NAME;
>     }
>
>     g_next_name = (++g_next_name) % ULONG_MAX;
>     g_next_name = REQUEST_INFO_ERR_NAME == g_next_name ?
>                   g_next_name++ : g_next_name;
>     new_name = g_next_name;
>
>     new_node = (NODE_T *) malloc(sizeof(NODE_T));
>     if (new_node == NULL) {
>         jk_log(logger, JK_LOG_EMERG, "Failed to allocate memory for a "
>                "new map entry\n");
>
>         JK_LEAVE_CS(&g_crit_sec, success);
>         LOG_CRIT_SEC(leave, success);
>
>         LOG_EXIT(rinfo_map_insert);
>         return REQUEST_INFO_ERR_NAME;
>     }
>
>     new_node->name = new_name;
>     new_node->ri = ri;
>     new_node->next = NULL;
>
>     if (g_map_head == NULL) {
>         g_map_head = new_node;
>     }
>     else {
>         g_map_tail->next = new_node;
>     }
>
>     g_map_tail = new_node;
>
>     jk_log(logger, JK_LOG_DEBUG, "Added req: %d\nhead = 0x%x tail =
0x%x\n",
>
>            new_name, g_map_head, g_map_tail);
>     JK_LEAVE_CS(&g_crit_sec, success);
>     LOG_CRIT_SEC(leave, success);
>
>     LOG_EXIT(rinfo_map_insert);
>     return new_name;
> }
>
>
> /* centralize the retrieval of data */
> static NODE_T **internal_map_at(request_info_name_t req)
> {
>     NODE_T **ppreturn = NULL;
>     NODE_T **ppcurrent = &g_map_head;
>
>     while (*ppcurrent) {
>         if ((*ppcurrent)->name == req) {
>             ppreturn = ppcurrent;
>             break;
>         }
>
>         ppcurrent = &((*ppcurrent)->next);
>     }
>
>     if (!ppreturn) {
>         jk_log(logger, JK_LOG_DEBUG, "Did not find info named: %d\n",
>                req);
>     }
>
>     return ppreturn;
> }
>
>
> request_information_t *rinfo_map_at(request_info_name_t req)
> {
>     int success = JK_FALSE;
>     NODE_T **ppresult = NULL;
>     LOG_ENTER(rinfo_map_at);
>
>     JK_ENTER_CS(&g_crit_sec, success);
>     if (success == JK_FALSE) {
>         LOG_CRIT_SEC(enter, success);
>         LOG_EXIT(rinfo_map_at);
>         return NULL;
>     }
>
>     ppresult = internal_map_at(req);
>
>     JK_LEAVE_CS(&g_crit_sec, success);
>     LOG_CRIT_SEC(leave, success);
>
>     LOG_EXIT(rinfo_map_at);
>     return ppresult ? (*ppresult)->ri : NULL;
> }
>
>
> request_information_t *rinfo_map_remove_at(request_info_name_t req)
> {
>     int success = JK_FALSE;
>     NODE_T **ppresult = NULL;
>     NODE_T *ptemp;
>     request_information_t *preturn = NULL;
>     LOG_ENTER(rinfo_map_remove_at);
>
>     JK_ENTER_CS(&g_crit_sec, success);
>     if (success == JK_FALSE) {
>         LOG_CRIT_SEC(enter, success);
>         LOG_EXIT(rinfo_map_remove_at);
>         return NULL;
>     }
>
>     ppresult = internal_map_at(req);
>     if (ppresult) {
>        jk_log(logger, JK_LOG_DEBUG, "Removing request: %d\nhead = 0x%x
tail
> = 0x%x\n",
>               req, g_map_head, g_map_tail);
>
>         preturn = (*ppresult)->ri;
>
>         /*
>          * This removal part is a little tricky, so here I try to explain
> it.
>          * If someone finds out that it's not doing what it's supposed to,
>          * then keep these notes in mind.
>          *
>          * What we are getting from the search function is not a
>          * pointer to a node, but instead a pointer to a pointer to a
node.
>          * The reasoning for this return value is so that the node can be
>          * removed without having to return two pointers:  a pointer to
the
>          * found node and a pointer to the node before that.  In my
opinion,
>          * this allows for a more graceful implementation... even though
the
>          * pointer stuff is a little hard to manage.
>          *
>          * So, it's established that we have a pointer to a pointer.
>          * To remove the node, we first need to create a temporary
reference
> to
>          * it. A simple pointer will do here.  We just don't want to lose
a
>          * handle on the node.  Once we have safely stored a reference to
> the
>          * node, we check to see if the found node is the last node in
list.
>          * If it is, then we check for the special case: that there is a
>          * one-element list. The tail pointer is zeroed.  In the more
> general
>          * case (the list is two or more nodes long), we need to back the
>          * tail up.  Since what we have is a pointer to a pointer to a
node,
>          * we can't just assign the value of ppresult to the tail.  We
need
> to
>          * find the memory location of the node that contains the "next"
>          * pointer that ppresult is pointing to.  We use the the offsetof
>          * macro to find out how far back from the next pointer the node
>          * pointer needs to be. Then we calculate the location of the node
>          * pointer based on the location of the next pointer.  This should
>          * be safe because the search function can only return a pointer
to
>          * head or to a next field (which is in a node) and we already
> checked
>          * for the first case.
>          *
>          * Once we deal with the tail, the rest just falls out.  The value
>          * of the pointer that ppresult points to (be it head or next
> field),
>          * is reassigned to point to the next node in the list.
>          *
>          * The node is then deleted.
>          */
>         ptemp = *ppresult;
>         if (ptemp == g_map_tail) {
>             if (g_map_tail == g_map_head) {
>                 g_map_tail = NULL;
>             }
>             else {
>                 g_map_tail = (NODE_T *)(
>                     ((jk_uintptr_t)(ppresult)) - offsetof(NODE_T, next));
>             }
>         }
>
>         *ppresult = (*ppresult)->next;
>
>         free((void *) ptemp);
>
>        jk_log(logger, JK_LOG_DEBUG, "Removed request: %d\nhead = 0x%x tail
=
> 0x%x\n", req,
>               g_map_head, g_map_tail);
>     }
>
>     JK_LEAVE_CS(&g_crit_sec, success);
>     LOG_CRIT_SEC(leave, success);
>
>     LOG_EXIT(rinfo_map_remove_at);
>     return preturn;
> }
>
>
> char *rinfo_append_name_to_uri(char *uri, request_info_name_t req,
>                char *buff, size_t size)
> {
> char sep = '?';
>     LOG_ENTER(rinfo_append_name_to_uri);
>
> if (buff == NULL) {
>         LOG_EXIT(rinfo_append_name_to_uri);
>         return NULL;
> }
>
> if (strchr(uri, sep)) {
>         sep = '&';
> }
>
> snprintf(buff, size, "%s%c" QUERY_VAR "=%d", uri, sep, req);
>
>     LOG_EXIT(rinfo_append_name_to_uri);
> return buff;
> }
>
>
> request_info_name_t rinfo_name_from_query(char *query)
> {
>     int numconverted = 0;
>     request_info_name_t name = REQUEST_INFO_ERR_NAME;
>     LOG_ENTER(rinfo_name_from_query);
>
>     query = strstr(query, QUERY_VAR);
>     if (!query) {
>         jk_log(logger, JK_LOG_ERROR, "Did not find the variable \""
>             QUERY_VAR "\" in the query string.\n");
>         LOG_EXIT(rinfo_name_from_query);
>         return REQUEST_INFO_ERR_NAME;
>     }
>
>     if (sscanf(query, QUERY_VAR "=%d", &name) != 1) {
>         jk_log(logger, JK_LOG_ERROR, "Query string could not be scanned "
>                "for a name.\n");
>         LOG_EXIT(rinfo_name_from_query);
>         return REQUEST_INFO_ERR_NAME;
>     }
>
>     LOG_EXIT(rinfo_name_from_query);
>     return name;
> }
>
>
> /* Create a new request info object */
> request_information_t *rinfo_new()
> {
>     request_information_t *pinfo =
> (request_information_t *) malloc(sizeof(request_information_t));
>     LOG_ENTER(rinfo_new);
>
>     if (pinfo == NULL) {
>         jk_log(logger, JK_LOG_EMERG, "Failed to allocate memory for a "
>                "new request information object.\n");
>         LOG_EXIT(rinfo_new);
>         return NULL;
>     }
>
>     memset((void *) pinfo, 0, sizeof(request_information_t));
>     jk_open_pool(&pinfo->p, pinfo->buff, sizeof(pinfo->buff));
>
>     LOG_EXIT(rinfo_new);
>     return pinfo;
> }
>
>
> /* destroy a request info object */
> void rinfo_delete(request_information_t * ri)
> {
>     LOG_ENTER(rinfo_delete);
>
>     if (ri == NULL) {
>         LOG_EXIT(rinfo_delete);
>         return;
>     }
>
>     jk_close_pool(&ri->p);
>     free((void *) ri);
>
>     /* This is not sufficient, caller must do this too */
>     ri = NULL;
>
>     LOG_EXIT(rinfo_delete);
> }
>
>
> /* helper to set string memebers */
> static internal_set_string(request_information_t * ri, char **member,
>    char *value)
> {
>     if (value) {
>         *member = jk_pool_strdup(&ri->p, value);
>     }
>     else {
>         *member = NULL;
>     }
> }
>
> void rinfo_set_worker(request_information_t * ri, char *name)
> {
>     LOG_ENTER(rinfo_set_worker);
>
>     /* protection */
>     if (ri == NULL) {
>         LOG_EXIT(rinfo_set_worker);
>         return;
>     }
>
>     internal_set_string(ri, &(ri->worker_name), name);
>
>     LOG_EXIT(rinfo_set_worker);
> }
>
>
> void rinfo_set_uri(request_information_t * ri, char *uri)
> {
>     LOG_ENTER(rinfo_set_uri);
>
>     /* protection */
>     if (ri == NULL) {
>         LOG_EXIT(rinfo_set_uri);
>         return;
>     }
>
>     internal_set_string(ri, &(ri->uri), uri);
>
>     LOG_EXIT(rinfo_set_uri);
> }
>
>
> void rinfo_set_query_string(request_information_t * ri, char *qs)
> {
>     LOG_ENTER(rinfo_set_query_string);
>
>     /* protection */
>     if (ri == NULL) {
>         LOG_EXIT(rinfo_set_query_string);
>         return;
>     }
>
>     internal_set_string(ri, &(ri->query_string), qs);
>
>     LOG_EXIT(rinfo_set_query_string);
> }
>
>
> char *rinfo_get_worker(request_information_t * ri)
> {
>     LOG_ENTER(rinfo_get_worker);
>
>     if (ri == NULL) {
>         LOG_EXIT(rinfo_get_worker);
>         return NULL;
>     }
>
>     jk_log(logger, JK_LOG_DEBUG, "Retreived: %s\n", ri->worker_name);
>     LOG_EXIT(rinfo_get_worker);
>     return ri->worker_name;
> }
>
>
> char *rinfo_get_uri(request_information_t * ri)
> {
>     LOG_ENTER(rinfo_get_uri);
>
>     if (ri == NULL) {
>         LOG_EXIT(rinfo_get_uri);
>         return NULL;
>     }
>
>     jk_log(logger, JK_LOG_DEBUG, "Retreived: %s\n", ri->uri);
>     LOG_EXIT(rinfo_get_uri);
>     return ri->uri;
> }
>
>
> char *rinfo_get_query_string(request_information_t * ri)
> {
>     LOG_ENTER(rinfo_get_query_string);
>
>     if (ri == NULL) {
>         LOG_EXIT(rinfo_get_query_string);
>         return NULL;
>     }
>
>     jk_log(logger, JK_LOG_DEBUG, "Retreived: %s\n", ri->query_string);
>     LOG_EXIT(rinfo_get_query_string);
>     return ri->query_string;
> }
>
>
>
>
> ----------------------------
>   .-.    | Steven Velez
>   oo|    | Software Engineer
>  /`'\    | alventive
> (\_;/)   | 678-202-2226
>
>
>
>
>
>
> -----Original Message-----
> From: Steven Velez [mailto:svelez@alventive.com]
> Sent: Tuesday, November 12, 2002 12:15 PM
> To: 'Tomcat Developers List'
> Subject: RE: [PATCH] Fixing Interoperability problem in iis connector
>
>
> :( My mail client warpped the code inappropriately.. I will remedy this
and
> re-post.
>
> Thanks,
> Steven
>
> ----------------------------
>   .-.    | Steven Velez
>   oo|    | Software Engineer
>  /`'\    | alventive
> (\_;/)   | 678-202-2226
>
>
>
> -----Original Message-----
> From: Steven Velez [mailto:svelez@alventive.com]
> Sent: Tuesday, November 12, 2002 12:15 PM
> To: 'Tomcat Developers List'
> Subject: RE: [PATCH] Fixing Interoperability problem in iis connector
>
>
> :( My mail client warpped the code inappropriately.. I will remedy this
and
> re-post.
>
> Thanks,
> Steven
>
>


--
To unsubscribe, e-mail:   <mailto:tomcat-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:tomcat-dev-help@jakarta.apache.org>


Mime
View raw message