Post the patch as an attachment. ----- Original Message ----- From: "Steven Velez" <[EMAIL PROTECTED]> To: "'Tomcat Developers List'" <[EMAIL PROTECTED]> 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 <[EMAIL PROTECTED]>. > * > * > * > * 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 <[EMAIL PROTECTED]> * > > * 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 <[EMAIL PROTECTED]>. > * > * > * > * 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 <[EMAIL PROTECTED]> * > > * 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>