diff options
Diffstat (limited to 'rubbos/app/tomcat-connectors-1.2.32-src/native/common/jk_uri_worker_map.c')
-rw-r--r-- | rubbos/app/tomcat-connectors-1.2.32-src/native/common/jk_uri_worker_map.c | 1191 |
1 files changed, 0 insertions, 1191 deletions
diff --git a/rubbos/app/tomcat-connectors-1.2.32-src/native/common/jk_uri_worker_map.c b/rubbos/app/tomcat-connectors-1.2.32-src/native/common/jk_uri_worker_map.c deleted file mode 100644 index d652f769..00000000 --- a/rubbos/app/tomcat-connectors-1.2.32-src/native/common/jk_uri_worker_map.c +++ /dev/null @@ -1,1191 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************** - * Description: URI to worker map object. * - * * - * Author: Gal Shachor <shachor@il.ibm.com> * - * Author: Mladen Turk <mturk@apache.org> * - * Version: $Revision: 890739 $ * - ***************************************************************************/ - -#include "jk_pool.h" -#include "jk_util.h" -#include "jk_map.h" -#include "jk_mt.h" -#include "jk_uri_worker_map.h" -#include "jk_worker.h" -#include "jk_lb_worker.h" - -#ifdef WIN32 -#define JK_STRCMP strcasecmp -#define JK_STRNCMP strnicmp -#else -#define JK_STRCMP strcmp -#define JK_STRNCMP strncmp -#endif - -#define JK_UWMAP_EXTENSION_REPLY_TIMEOUT "reply_timeout=" -#define JK_UWMAP_EXTENSION_ACTIVE "active=" -#define JK_UWMAP_EXTENSION_DISABLED "disabled=" -#define JK_UWMAP_EXTENSION_STOPPED "stopped=" -#define JK_UWMAP_EXTENSION_FAIL_ON_STATUS "fail_on_status=" -#define JK_UWMAP_EXTENSION_USE_SRV_ERRORS "use_server_errors=" - -#define IND_SWITCH(x) (((x)+1) % 2) -#define IND_THIS(x) ((x)[uw_map->index]) -#define IND_NEXT(x) ((x)[IND_SWITCH(uw_map->index)]) - -#define STRNULL_FOR_NULL(x) ((x) ? (x) : "(null)") - -static const char *uri_worker_map_source_type[] = { - "unknown", - SOURCE_TYPE_TEXT_WORKERDEF, - SOURCE_TYPE_TEXT_JKMOUNT, - SOURCE_TYPE_TEXT_URIMAP, - SOURCE_TYPE_TEXT_DISCOVER, - NULL -}; - - -/* Return the string representation of the uwr source */ -const char *uri_worker_map_get_source(uri_worker_record_t *uwr, jk_logger_t *l) -{ - return uri_worker_map_source_type[uwr->source_type]; -} - -/* Return the string representation of the uwr match type */ -char *uri_worker_map_get_match(uri_worker_record_t *uwr, char *buf, jk_logger_t *l) -{ - unsigned int match; - - buf[0] = '\0'; - match = uwr->match_type; - - if (match & MATCH_TYPE_DISABLED) - strcat(buf, "Disabled "); -/* deprecated - if (match & MATCH_TYPE_STOPPED) - strcat(buf, "Stopped "); - */ - if (match & MATCH_TYPE_NO_MATCH) - strcat(buf, "Unmount "); - if (match & MATCH_TYPE_EXACT) - strcat(buf, "Exact"); - else if (match & MATCH_TYPE_WILDCHAR_PATH) - strcat(buf, "Wildchar"); -/* deprecated - else if (match & MATCH_TYPE_CONTEXT) - strcat(buf, "Context"); - else if (match & MATCH_TYPE_CONTEXT_PATH) - strcat(buf, "Context Path"); - else if (match & MATCH_TYPE_SUFFIX) - strcat(buf, "Suffix"); - else if (match & MATCH_TYPE_GENERAL_SUFFIX) - return "General Suffix"; - */ - else - strcat(buf, "Unknown"); - return buf; -} - -/* - * Given context uri, count the number of path tokens. - * - * Servlet specification 2.4, SRV.11.1 says - - * The container will recursively try tomatch the longest - * path-prefix. This is done by stepping down the path tree a - * directory at a time, using the / character as a path - * separator. The longest match determines the servlet selected. - * - * The implication seems to be `most uri path elements is most exact'. - * This is a little helper function to count uri tokens, so we can - * keep the worker map sorted with most specific first. - */ -static int worker_count_context_uri_tokens(const char * context) -{ - const char * c = context; - int count = 0; - while (c && *c) { - if ('/' == *c++) - count++; - } - return count; -} - -static int worker_compare(const void *elem1, const void *elem2) -{ - uri_worker_record_t *e1 = *(uri_worker_record_t **)elem1; - uri_worker_record_t *e2 = *(uri_worker_record_t **)elem2; - int e1_tokens = 0; - int e2_tokens = 0; - - e1_tokens = worker_count_context_uri_tokens(e1->context); - e2_tokens = worker_count_context_uri_tokens(e2->context); - - if (e1_tokens != e2_tokens) { - return (e2_tokens - e1_tokens); - } - /* given the same number of URI tokens, use character - * length as a tie breaker - */ - if(e2->context_len != e1->context_len) - return ((int)e2->context_len - (int)e1->context_len); - - return ((int)e2->source_type - (int)e1->source_type); -} - -static void worker_qsort(jk_uri_worker_map_t *uw_map) -{ - - /* Sort remaining args using Quicksort algorithm: */ - qsort((void *)IND_NEXT(uw_map->maps), IND_NEXT(uw_map->size), - sizeof(uri_worker_record_t *), worker_compare ); - -} - -/* Dump the map contents - only call if debug log is active. */ -static void uri_worker_map_dump(jk_uri_worker_map_t *uw_map, - const char *reason, jk_logger_t *l) -{ - JK_TRACE_ENTER(l); - if (uw_map) { - int i, off, k; - uri_worker_record_t *uwr = NULL; - char buf[32]; - jk_log(l, JK_LOG_DEBUG, "uri map dump %s: index=%d file='%s' reject_unsafe=%d " - "reload=%d modified=%d checked=%d", - reason, uw_map->index, STRNULL_FOR_NULL(uw_map->fname), uw_map->reject_unsafe, - uw_map->reload, uw_map->modified, uw_map->checked); - for(i=0;i<=1;i++) { - jk_log(l, JK_LOG_DEBUG, "generation %d: size=%d nosize=%d capacity=%d", - i, uw_map->size[i], uw_map->nosize[i], uw_map->capacity[i], uw_map->maps[i]); - } - - off = uw_map->index; - for(i=0;i<=1;i++) { - unsigned int j; - k = (i + off) % 2; - for (j = 0; j < uw_map->size[k]; j++) { - uwr = uw_map->maps[k][j]; - jk_log(l, JK_LOG_DEBUG, "%s (%d) map #%d: uri=%s worker=%s context=%s " - "source=%s type=%s len=%d", - i ? "NEXT" : "THIS", i, j, - STRNULL_FOR_NULL(uwr->uri), STRNULL_FOR_NULL(uwr->worker_name), - STRNULL_FOR_NULL(uwr->context), STRNULL_FOR_NULL(uri_worker_map_get_source(uwr,l)), - STRNULL_FOR_NULL(uri_worker_map_get_match(uwr,buf,l)), uwr->context_len); - } - } - } - JK_TRACE_EXIT(l); -} - - -int uri_worker_map_alloc(jk_uri_worker_map_t **uw_map_p, - jk_map_t *init_data, jk_logger_t *l) -{ - int i; - - JK_TRACE_ENTER(l); - - if (uw_map_p) { - int rc; - jk_uri_worker_map_t *uw_map; - *uw_map_p = (jk_uri_worker_map_t *)calloc(1, sizeof(jk_uri_worker_map_t)); - uw_map = *uw_map_p; - - JK_INIT_CS(&(uw_map->cs), rc); - if (rc == JK_FALSE) { - jk_log(l, JK_LOG_ERROR, - "creating thread lock (errno=%d)", - errno); - JK_TRACE_EXIT(l); - return JK_FALSE; - } - - jk_open_pool(&(uw_map->p), - uw_map->buf, sizeof(jk_pool_atom_t) * BIG_POOL_SIZE); - for(i=0;i<=1;i++) { - jk_open_pool(&(uw_map->p_dyn[i]), - uw_map->buf_dyn[i], sizeof(jk_pool_atom_t) * BIG_POOL_SIZE); - uw_map->size[i] = 0; - uw_map->nosize[i] = 0; - uw_map->capacity[i] = 0; - uw_map->maps[i] = NULL; - } - uw_map->index = 0; - uw_map->fname = NULL; - uw_map->reject_unsafe = 0; - uw_map->reload = JK_URIMAP_DEF_RELOAD; - uw_map->modified = 0; - uw_map->checked = 0; - - if (init_data) - rc = uri_worker_map_open(uw_map, init_data, l); - JK_TRACE_EXIT(l); - return rc; - } - - JK_LOG_NULL_PARAMS(l); - JK_TRACE_EXIT(l); - - return JK_FALSE; -} - -static int uri_worker_map_close(jk_uri_worker_map_t *uw_map, jk_logger_t *l) -{ - JK_TRACE_ENTER(l); - - if (uw_map) { - int i; - JK_DELETE_CS(&(uw_map->cs), i); - jk_close_pool(&uw_map->p_dyn[0]); - jk_close_pool(&uw_map->p_dyn[1]); - jk_close_pool(&uw_map->p); - JK_TRACE_EXIT(l); - return JK_TRUE; - } - - JK_LOG_NULL_PARAMS(l); - JK_TRACE_EXIT(l); - return JK_FALSE; -} - -int uri_worker_map_free(jk_uri_worker_map_t **uw_map, jk_logger_t *l) -{ - JK_TRACE_ENTER(l); - - if (uw_map && *uw_map) { - uri_worker_map_close(*uw_map, l); - free(*uw_map); - *uw_map = NULL; - JK_TRACE_EXIT(l); - return JK_TRUE; - } - else - JK_LOG_NULL_PARAMS(l); - - JK_TRACE_EXIT(l); - return JK_FALSE; -} - -/* - * Ensure there will be memory in context info to store Context Bases - */ - -#define UW_INC_SIZE 4 /* 4 URI->WORKER STEP */ - -static int uri_worker_map_realloc(jk_uri_worker_map_t *uw_map) -{ - if (IND_NEXT(uw_map->size) == IND_NEXT(uw_map->capacity)) { - uri_worker_record_t **uwr; - int capacity = IND_NEXT(uw_map->capacity) + UW_INC_SIZE; - - uwr = - (uri_worker_record_t **) jk_pool_alloc(&IND_NEXT(uw_map->p_dyn), - sizeof(uri_worker_record_t - *) * capacity); - - if (!uwr) - return JK_FALSE; - - if (IND_NEXT(uw_map->capacity) && IND_NEXT(uw_map->maps)) - memcpy(uwr, IND_NEXT(uw_map->maps), - sizeof(uri_worker_record_t *) * IND_NEXT(uw_map->capacity)); - - IND_NEXT(uw_map->maps) = uwr; - IND_NEXT(uw_map->capacity) = capacity; - } - - return JK_TRUE; -} - - -/* - * Delete all entries of a given source type - */ - -static int uri_worker_map_clear(jk_uri_worker_map_t *uw_map, - jk_logger_t *l) -{ - uri_worker_record_t *uwr = NULL; - unsigned int i; - unsigned int new_size = 0; - unsigned int new_nosize = 0; - - JK_TRACE_ENTER(l); - - IND_NEXT(uw_map->maps) = - (uri_worker_record_t **) jk_pool_alloc(&(IND_NEXT(uw_map->p_dyn)), - sizeof(uri_worker_record_t - *) * IND_THIS(uw_map->size)); - IND_NEXT(uw_map->capacity) = IND_THIS(uw_map->size); - IND_NEXT(uw_map->size) = 0; - IND_NEXT(uw_map->nosize) = 0; - for (i = 0; i < IND_THIS(uw_map->size); i++) { - uwr = IND_THIS(uw_map->maps)[i]; - if (uwr->source_type == SOURCE_TYPE_URIMAP) { - if (JK_IS_DEBUG_LEVEL(l)) - jk_log(l, JK_LOG_DEBUG, - "deleting map rule '%s=%s' source '%s'", - uwr->context, uwr->worker_name, uri_worker_map_get_source(uwr, l)); - } - else { - IND_NEXT(uw_map->maps)[new_size] = uwr; - new_size++; - if (uwr->match_type & MATCH_TYPE_NO_MATCH) - new_nosize++; - } - } - IND_NEXT(uw_map->size) = new_size; - IND_NEXT(uw_map->nosize) = new_nosize; - - JK_TRACE_EXIT(l); - return JK_TRUE; -} - -static void extract_activation(jk_uri_worker_map_t *uw_map, - uri_worker_record_t *uwr, - lb_worker_t *lb, - int *activations, - char *workers, - int activation, - jk_logger_t *l) -{ - unsigned int i; - jk_pool_t *p; - char *worker; -#ifdef _MT_CODE_PTHREAD - char *lasts; -#endif - - JK_TRACE_ENTER(l); - - if (uwr->source_type == SOURCE_TYPE_URIMAP) - p = &IND_NEXT(uw_map->p_dyn); - else - p = &uw_map->p; - worker = jk_pool_strdup(p, workers); - -#ifdef _MT_CODE_PTHREAD - for (worker = strtok_r(worker, ", ", &lasts); - worker; worker = strtok_r(NULL, ", ", &lasts)) { -#else - for (worker = strtok(worker, ", "); worker; worker = strtok(NULL, ", ")) { -#endif - for (i=0; i<lb->num_of_workers; i++) { - if (!strcmp(worker, lb->lb_workers[i].name)) { - if (activations[i] != JK_LB_ACTIVATION_UNSET) - jk_log(l, JK_LOG_WARNING, - "inconsistent activation overwrite for member %s " - "of load balancer %s: '%s' replaced by '%s'", - worker, lb->name, - jk_lb_get_activation_direct(activations[i], l), - jk_lb_get_activation_direct(activation, l)); - activations[i] = activation; - break; - } - } - if (i >= lb->num_of_workers) - jk_log(l, JK_LOG_WARNING, - "could not find member %s of load balancer %s", - worker, lb->name); - } - - JK_TRACE_EXIT(l); - -} - -static void extract_fail_on_status(jk_uri_worker_map_t *uw_map, - uri_worker_record_t *uwr, - jk_logger_t *l) -{ - unsigned int i; - int j; - int cnt = 1; - jk_pool_t *p; - char *status; -#ifdef _MT_CODE_PTHREAD - char *lasts; -#endif - - JK_TRACE_ENTER(l); - - for (i=0; i<strlen(uwr->extensions.fail_on_status_str); i++) { - if (uwr->extensions.fail_on_status_str[i] == ',' || - uwr->extensions.fail_on_status_str[i] == ' ') - cnt++; - } - uwr->extensions.fail_on_status_size = cnt; - - if (uwr->source_type == SOURCE_TYPE_URIMAP) - p = &IND_NEXT(uw_map->p_dyn); - else - p = &uw_map->p; - status = jk_pool_strdup(p, uwr->extensions.fail_on_status_str); - uwr->extensions.fail_on_status = (int *)jk_pool_alloc(p, - uwr->extensions.fail_on_status_size * sizeof(int)); - if (!uwr->extensions.fail_on_status) { - jk_log(l, JK_LOG_ERROR, - "can't alloc extensions fail_on_status list"); - JK_TRACE_EXIT(l); - return; - } else if (JK_IS_DEBUG_LEVEL(l)) - jk_log(l, JK_LOG_DEBUG, - "Allocated fail_on_status array of size %d for worker %s", - uwr->extensions.fail_on_status_size, uwr->worker_name); - - - for (j=0; j<uwr->extensions.fail_on_status_size; j++) { - uwr->extensions.fail_on_status[j] = 0; - } - - cnt = 0; -#ifdef _MT_CODE_PTHREAD - for (status = strtok_r(status, ", ", &lasts); - status; status = strtok_r(NULL, ", ", &lasts)) { -#else - for (status = strtok(status, ", "); status; status = strtok(NULL, ", ")) { -#endif - uwr->extensions.fail_on_status[cnt] = atoi(status); - cnt++; - } - - JK_TRACE_EXIT(l); - -} - -void uri_worker_map_switch(jk_uri_worker_map_t *uw_map, jk_logger_t *l) -{ - int new_index; - - JK_TRACE_ENTER(l); - - if (uw_map) { - new_index = IND_SWITCH(uw_map->index); - if (JK_IS_DEBUG_LEVEL(l)) - jk_log(l, JK_LOG_DEBUG, - "Switching uri worker map from index %d to index %d", - uw_map->index, new_index); - uw_map->index = new_index; - jk_reset_pool(&(IND_NEXT(uw_map->p_dyn))); - } - - JK_TRACE_EXIT(l); - -} - -void uri_worker_map_ext(jk_uri_worker_map_t *uw_map, jk_logger_t *l) -{ - unsigned int i; - - JK_TRACE_ENTER(l); - - for (i = 0; i < IND_NEXT(uw_map->size); i++) { - uri_worker_record_t *uwr = IND_NEXT(uw_map->maps)[i]; - jk_worker_t *jw; - if(uwr->match_type & MATCH_TYPE_NO_MATCH) - continue; - jw = wc_get_worker_for_name(uwr->worker_name, l); - if(!jw) { - jk_log(l, JK_LOG_ERROR, - "Could not find worker with name '%s' in uri map post processing.", - uwr->worker_name); - continue; - } - if (JK_IS_DEBUG_LEVEL(l)) - jk_log(l, JK_LOG_DEBUG, - "Checking extension for worker %d: %s of type %s (%d)", - i, uwr->worker_name, wc_get_name_for_type(jw->type,l), jw->type); - - if (jw->type == JK_LB_WORKER_TYPE && - (uwr->extensions.active || uwr->extensions.disabled || uwr->extensions.stopped)) { - int j; - lb_worker_t *lb = (lb_worker_t *)jw->worker_private; - jk_pool_t *p; - if (!uwr->extensions.activation) { - uwr->extensions.activation_size = lb->num_of_workers; - if (uwr->source_type == SOURCE_TYPE_URIMAP) - p = &IND_NEXT(uw_map->p_dyn); - else - p = &uw_map->p; - uwr->extensions.activation = (int *)jk_pool_alloc(p, - uwr->extensions.activation_size * sizeof(int)); - if (!uwr->extensions.activation) { - jk_log(l, JK_LOG_ERROR, - "can't alloc extensions activation list"); - continue; - } else if (JK_IS_DEBUG_LEVEL(l)) - jk_log(l, JK_LOG_DEBUG, - "Allocated activations array of size %d for lb worker %s", - uwr->extensions.activation_size, uwr->worker_name); - for (j=0; j<uwr->extensions.activation_size; j++) { - uwr->extensions.activation[j] = JK_LB_ACTIVATION_UNSET; - } - } - if (uwr->extensions.active) - extract_activation(uw_map, uwr, lb, uwr->extensions.activation, - uwr->extensions.active, JK_LB_ACTIVATION_ACTIVE, l); - if (uwr->extensions.disabled) - extract_activation(uw_map, uwr, lb, uwr->extensions.activation, - uwr->extensions.disabled, JK_LB_ACTIVATION_DISABLED, l); - if (uwr->extensions.stopped) - extract_activation(uw_map, uwr, lb, uwr->extensions.activation, - uwr->extensions.stopped, JK_LB_ACTIVATION_STOPPED, l); - } - else if (uwr->extensions.active) { - jk_log(l, JK_LOG_WARNING, - "Worker %s is not of type lb, activation extension " - JK_UWMAP_EXTENSION_ACTIVE " for %s ignored", - uwr->worker_name, uwr->extensions.active); - } - else if (uwr->extensions.disabled) { - jk_log(l, JK_LOG_WARNING, - "Worker %s is not of type lb, activation extension " - JK_UWMAP_EXTENSION_DISABLED " for %s ignored", - uwr->worker_name, uwr->extensions.disabled); - } - else if (uwr->extensions.stopped) { - jk_log(l, JK_LOG_WARNING, - "Worker %s is not of type lb, activation extension " - JK_UWMAP_EXTENSION_STOPPED " for %s ignored", - uwr->worker_name, uwr->extensions.stopped); - } - if (uwr->extensions.fail_on_status_str) { - extract_fail_on_status(uw_map, uwr, l); - } - } - if (JK_IS_DEBUG_LEVEL(l)) - uri_worker_map_dump(uw_map, "after extension stripping", l); - - JK_TRACE_EXIT(l); - return; - -} - -/* Add new entry to NEXT generation */ -int uri_worker_map_add(jk_uri_worker_map_t *uw_map, - const char *puri, const char *worker, - unsigned int source_type, jk_logger_t *l) -{ - uri_worker_record_t *uwr = NULL; - char *uri; - jk_pool_t *p; - unsigned int match_type = 0; - - JK_TRACE_ENTER(l); - - if (*puri == '-') { - /* Disable urimap. - * This way you can disable already mounted - * context. - */ - match_type = MATCH_TYPE_DISABLED; - puri++; - } - if (*puri == '!') { - match_type |= MATCH_TYPE_NO_MATCH; - puri++; - } - - if (uri_worker_map_realloc(uw_map) == JK_FALSE) { - JK_TRACE_EXIT(l); - return JK_FALSE; - } - if (source_type == SOURCE_TYPE_URIMAP) - p = &IND_NEXT(uw_map->p_dyn); - else - p = &uw_map->p; - - uwr = (uri_worker_record_t *)jk_pool_alloc(p, sizeof(uri_worker_record_t)); - if (!uwr) { - jk_log(l, JK_LOG_ERROR, - "can't alloc map entry"); - JK_TRACE_EXIT(l); - return JK_FALSE; - } - - uri = jk_pool_strdup(p, puri); - if (!uri || !worker) { - jk_log(l, JK_LOG_ERROR, - "can't alloc uri/worker strings"); - JK_TRACE_EXIT(l); - return JK_FALSE; - } - - if (*uri == '/') { - char *w; - char *param; -#ifdef _MT_CODE_PTHREAD - char *lasts = NULL; -#endif - - w = jk_pool_strdup(p, worker); - uwr->extensions.reply_timeout = -1; - uwr->extensions.active = NULL; - uwr->extensions.disabled = NULL; - uwr->extensions.stopped = NULL; - uwr->extensions.activation_size = 0; - uwr->extensions.activation = NULL; - uwr->extensions.fail_on_status_size = 0; - uwr->extensions.fail_on_status = NULL; - uwr->extensions.fail_on_status_str = NULL; - uwr->extensions.use_server_error_pages = 0; - -#ifdef _MT_CODE_PTHREAD - param = strtok_r(w, ";", &lasts); -#else - param = strtok(w, ";"); -#endif - if (param) { -#ifdef _MT_CODE_PTHREAD - for (param = strtok_r(NULL, ";", &lasts); param; param = strtok_r(NULL, ";", &lasts)) { -#else - for (param = strtok(NULL, ";"); param; param = strtok(NULL, ";")) { -#endif - if (!strncmp(param, JK_UWMAP_EXTENSION_REPLY_TIMEOUT, strlen(JK_UWMAP_EXTENSION_REPLY_TIMEOUT))) { - uwr->extensions.reply_timeout = atoi(param + strlen(JK_UWMAP_EXTENSION_REPLY_TIMEOUT)); - } - else if (!strncmp(param, JK_UWMAP_EXTENSION_USE_SRV_ERRORS, strlen(JK_UWMAP_EXTENSION_USE_SRV_ERRORS))) { - uwr->extensions.use_server_error_pages = atoi(param + strlen(JK_UWMAP_EXTENSION_USE_SRV_ERRORS)); - } - else if (!strncmp(param, JK_UWMAP_EXTENSION_ACTIVE, strlen(JK_UWMAP_EXTENSION_ACTIVE))) { - if (uwr->extensions.active) - jk_log(l, JK_LOG_WARNING, - "extension '%s' in uri worker map only allowed once", - JK_UWMAP_EXTENSION_ACTIVE); - else - uwr->extensions.active = param + strlen(JK_UWMAP_EXTENSION_ACTIVE); - } - else if (!strncmp(param, JK_UWMAP_EXTENSION_DISABLED, strlen(JK_UWMAP_EXTENSION_DISABLED))) { - if (uwr->extensions.disabled) - jk_log(l, JK_LOG_WARNING, - "extension '%s' in uri worker map only allowed once", - JK_UWMAP_EXTENSION_DISABLED); - else - uwr->extensions.disabled = param + strlen(JK_UWMAP_EXTENSION_DISABLED); - } - else if (!strncmp(param, JK_UWMAP_EXTENSION_STOPPED, strlen(JK_UWMAP_EXTENSION_STOPPED))) { - if (uwr->extensions.stopped) - jk_log(l, JK_LOG_WARNING, - "extension '%s' in uri worker map only allowed once", - JK_UWMAP_EXTENSION_STOPPED); - else - uwr->extensions.stopped = param + strlen(JK_UWMAP_EXTENSION_STOPPED); - } - else if (!strncmp(param, JK_UWMAP_EXTENSION_FAIL_ON_STATUS, strlen(JK_UWMAP_EXTENSION_FAIL_ON_STATUS))) { - if (uwr->extensions.fail_on_status_str) - jk_log(l, JK_LOG_WARNING, - "extension '%s' in uri worker map only allowed once", - JK_UWMAP_EXTENSION_FAIL_ON_STATUS); - else - uwr->extensions.fail_on_status_str = param + strlen(JK_UWMAP_EXTENSION_FAIL_ON_STATUS); - } - else { - jk_log(l, JK_LOG_WARNING, - "unknown extension '%s' in uri worker map", - param); - } - } - } - - uwr->source_type = source_type; - uwr->worker_name = w; - uwr->uri = uri; - uwr->context = uri; - uwr->context_len = strlen(uwr->context); - if (strchr(uri, '*') || - strchr(uri, '?')) { - /* Something like - * /context/ * /user/ * - * /context/ *.suffix - */ - match_type |= MATCH_TYPE_WILDCHAR_PATH; - if (JK_IS_DEBUG_LEVEL(l)) - jk_log(l, JK_LOG_DEBUG, - "wildchar rule '%s=%s' source '%s' was added", - uwr->context, uwr->worker_name, uri_worker_map_get_source(uwr, l)); - - } - else { - /* Something like: JkMount /login/j_security_check ajp13 */ - match_type |= MATCH_TYPE_EXACT; - if (JK_IS_DEBUG_LEVEL(l)) - jk_log(l, JK_LOG_DEBUG, - "exact rule '%s=%s' source '%s' was added", - uwr->context, uwr->worker_name, uri_worker_map_get_source(uwr, l)); - } - } - else { - /* - * JFC: please check... - * Not sure what to do, but I try to prevent problems. - * I have fixed jk_mount_context() in apaches/mod_jk.c so we should - * not arrive here when using Apache. - */ - jk_log(l, JK_LOG_ERROR, - "invalid context '%s': does not begin with '/'", - uri); - JK_TRACE_EXIT(l); - return JK_FALSE; - } - uwr->match_type = match_type; - IND_NEXT(uw_map->maps)[IND_NEXT(uw_map->size)] = uwr; - IND_NEXT(uw_map->size)++; - if (match_type & MATCH_TYPE_NO_MATCH) { - /* If we split the mappings this one will be calculated */ - IND_NEXT(uw_map->nosize)++; - } - worker_qsort(uw_map); - JK_TRACE_EXIT(l); - return JK_TRUE; -} - -int uri_worker_map_open(jk_uri_worker_map_t *uw_map, - jk_map_t *init_data, jk_logger_t *l) -{ - int rc = JK_TRUE; - - JK_TRACE_ENTER(l); - - if (uw_map) { - int sz = jk_map_size(init_data); - - if (JK_IS_DEBUG_LEVEL(l)) - jk_log(l, JK_LOG_DEBUG, - "rule map size is %d", - sz); - - if (sz > 0) { - int i; - for (i = 0; i < sz; i++) { - const char *u = jk_map_name_at(init_data, i); - const char *w = jk_map_value_at(init_data, i); - /* Multiple mappings like : - * /servlets-examples|/ * - * will create two mappings: - * /servlets-examples - * and: - * /servlets-examples/ * - */ - if (strchr(u, '|')) { - char *s, *r = strdup(u); - s = strchr(r, '|'); - *(s++) = '\0'; - /* Add first mapping */ - if (!uri_worker_map_add(uw_map, r, w, SOURCE_TYPE_JKMOUNT, l)) { - jk_log(l, JK_LOG_ERROR, - "invalid mapping rule %s->%s", r, w); - rc = JK_FALSE; - } - for (; *s; s++) - *(s - 1) = *s; - *(s - 1) = '\0'; - /* add second mapping */ - if (!uri_worker_map_add(uw_map, r, w, SOURCE_TYPE_JKMOUNT, l)) { - jk_log(l, JK_LOG_ERROR, - "invalid mapping rule %s->%s", r, w); - rc = JK_FALSE; - } - free(r); - } - else if (!uri_worker_map_add(uw_map, u, w, SOURCE_TYPE_JKMOUNT, l)) { - jk_log(l, JK_LOG_ERROR, - "invalid mapping rule %s->%s", - u, w); - rc = JK_FALSE; - break; - } - if (rc == JK_FALSE) - break; - } - } - - if (rc == JK_FALSE) { - jk_log(l, JK_LOG_ERROR, - "there was an error, freeing buf"); - jk_close_pool(&uw_map->p_dyn[0]); - jk_close_pool(&uw_map->p_dyn[1]); - jk_close_pool(&uw_map->p); - } - else if (JK_IS_DEBUG_LEVEL(l)) - uri_worker_map_dump(uw_map, "after map open", l); - } - - JK_TRACE_EXIT(l); - return rc; -} - -static int find_match(jk_uri_worker_map_t *uw_map, - const char *url, jk_logger_t *l) -{ - unsigned int i; - - JK_TRACE_ENTER(l); - - for (i = 0; i < IND_THIS(uw_map->size); i++) { - uri_worker_record_t *uwr = IND_THIS(uw_map->maps)[i]; - - /* Check for match types */ - if ((uwr->match_type & MATCH_TYPE_DISABLED) || - (uwr->match_type & MATCH_TYPE_NO_MATCH)) - continue; - - if (JK_IS_DEBUG_LEVEL(l)) - jk_log(l, JK_LOG_DEBUG, "Attempting to map context URI '%s=%s' source '%s'", - uwr->context, uwr->worker_name, uri_worker_map_get_source(uwr, l)); - - if (uwr->match_type & MATCH_TYPE_WILDCHAR_PATH) { - /* Map is already sorted by context_len */ - if (jk_wildchar_match(url, uwr->context, -#ifdef WIN32 - 0 -#else - 0 -#endif - ) == 0) { - if (JK_IS_DEBUG_LEVEL(l)) - jk_log(l, JK_LOG_DEBUG, - "Found a wildchar match '%s=%s'", - uwr->context, uwr->worker_name); - JK_TRACE_EXIT(l); - return i; - } - } - else if (JK_STRNCMP(uwr->context, url, uwr->context_len) == 0) { - if (strlen(url) == uwr->context_len) { - if (JK_IS_DEBUG_LEVEL(l)) - jk_log(l, JK_LOG_DEBUG, - "Found an exact match '%s=%s'", - uwr->context, uwr->worker_name); - JK_TRACE_EXIT(l); - return i; - } - } - } - - JK_TRACE_EXIT(l); - return -1; -} - -static int is_nomatch(jk_uri_worker_map_t *uw_map, - const char *uri, int match, - jk_logger_t *l) -{ - unsigned int i; - const char *worker = IND_THIS(uw_map->maps)[match]->worker_name; - - JK_TRACE_ENTER(l); - - for (i = 0; i < IND_THIS(uw_map->size); i++) { - uri_worker_record_t *uwr = IND_THIS(uw_map->maps)[i]; - - /* Check only nomatch mappings */ - if (!(uwr->match_type & MATCH_TYPE_NO_MATCH) || - (uwr->match_type & MATCH_TYPE_DISABLED)) - continue; - /* Check only matching workers */ - if (strcmp(uwr->worker_name, worker) && - strcmp(uwr->worker_name, "*")) - continue; - if (uwr->match_type & MATCH_TYPE_WILDCHAR_PATH) { - /* Map is already sorted by context_len */ - if (jk_wildchar_match(uri, uwr->context, -#ifdef WIN32 - 0 -#else - 0 -#endif - ) == 0) { - if (JK_IS_DEBUG_LEVEL(l)) - jk_log(l, JK_LOG_DEBUG, - "Found a wildchar no match '%s=%s' source '%s'", - uwr->context, uwr->worker_name, uri_worker_map_get_source(uwr, l)); - JK_TRACE_EXIT(l); - return JK_TRUE; - } - } - else if (JK_STRNCMP(uwr->context, uri, uwr->context_len) == 0) { - if (strlen(uri) == uwr->context_len) { - if (JK_IS_DEBUG_LEVEL(l)) - jk_log(l, JK_LOG_DEBUG, - "Found an exact no match '%s=%s' source '%s'", - uwr->context, uwr->worker_name, uri_worker_map_get_source(uwr, l)); - JK_TRACE_EXIT(l); - return JK_TRUE; - } - } - } - - JK_TRACE_EXIT(l); - return JK_FALSE; -} - -const char *map_uri_to_worker_ext(jk_uri_worker_map_t *uw_map, - const char *uri, const char *vhost, - rule_extension_t **extensions, - int *index, - jk_logger_t *l) -{ - unsigned int i; - unsigned int vhost_len; - int reject_unsafe; - int rv = -1; - char url[JK_MAX_URI_LEN+1]; - - JK_TRACE_ENTER(l); - - if (!uw_map || !uri || !extensions) { - JK_LOG_NULL_PARAMS(l); - JK_TRACE_EXIT(l); - return NULL; - } - *extensions = NULL; - if (index) - *index = -1; - if (*uri != '/') { - jk_log(l, JK_LOG_WARNING, - "Uri %s is invalid. Uri must start with /", uri); - JK_TRACE_EXIT(l); - return NULL; - } - if (uw_map->fname) { - uri_worker_map_update(uw_map, 0, l); - if (!IND_THIS(uw_map->size)) { - jk_log(l, JK_LOG_INFO, - "No worker maps defined for %s.", - uw_map->fname); - JK_TRACE_EXIT(l); - return NULL; - } - } - /* Make the copy of the provided uri and strip - * everything after the first ';' char. - */ - reject_unsafe = uw_map->reject_unsafe; - vhost_len = 0; - /* - * In case we got a vhost, we prepend a slash - * and the vhost to the url in order to enable - * vhost mapping rules especially for IIS. - */ - if (vhost) { - int off = 0; - /* Add leading '/' if necessary */ - if (vhost[0] != '/') { - url[0] = '/'; - off = 1; - } - /* Size including leading slash. */ - vhost_len = strlen(vhost); - if (vhost_len + off >= JK_MAX_URI_LEN) { - vhost_len = 0; - jk_log(l, JK_LOG_WARNING, - "Host prefix %s for URI %s is invalid and will be ignored." - " It must be smaller than %d chars", - vhost, JK_MAX_URI_LEN - off); - } - else { - strncpy(&url[off], vhost, vhost_len + 1); - } - vhost_len += off; - } - for (i = 0; i < strlen(uri); i++) { - if (i == JK_MAX_URI_LEN) { - jk_log(l, JK_LOG_WARNING, - "URI %s is invalid. URI must be smaller than %d chars", - uri, JK_MAX_URI_LEN); - JK_TRACE_EXIT(l); - return NULL; - } - if (uri[i] == ';') - break; - else { - url[i + vhost_len] = uri[i]; - if (reject_unsafe && (uri[i] == '%' || uri[i] == '\\')) { - jk_log(l, JK_LOG_INFO, "Potentially unsafe request url '%s' rejected", uri); - JK_TRACE_EXIT(l); - return NULL; - } - } - } - url[i + vhost_len] = '\0'; - - if (JK_IS_DEBUG_LEVEL(l)) { - char *url_rewrite = strstr(uri, JK_PATH_SESSION_IDENTIFIER); - if (url_rewrite) - jk_log(l, JK_LOG_DEBUG, "Found session identifier '%s' in url '%s'", - url_rewrite, uri); - } - if (JK_IS_DEBUG_LEVEL(l)) - jk_log(l, JK_LOG_DEBUG, "Attempting to map URI '%s' from %d maps", - url, IND_THIS(uw_map->size)); - rv = find_match(uw_map, url, l); - /* If this doesn't find a match, try without the vhost. */ - if (rv < 0 && vhost_len) { - rv = find_match(uw_map, &url[vhost_len], l); - } - - /* In case we found a match, check for the unmounts. */ - if (rv >= 0 && IND_THIS(uw_map->nosize)) { - /* Again first including vhost. */ - int rc = is_nomatch(uw_map, url, rv, l); - /* If no unmount was find, try without vhost. */ - if (!rc && vhost_len) - rc = is_nomatch(uw_map, &url[vhost_len], rv, l); - if (rc) { - if (JK_IS_DEBUG_LEVEL(l)) { - jk_log(l, JK_LOG_DEBUG, - "Denying match for worker %s by nomatch rule", - IND_THIS(uw_map->maps)[rv]->worker_name); - } - rv = -1; - } - } - - if (rv >= 0) { - *extensions = &(IND_THIS(uw_map->maps)[rv]->extensions); - if (index) - *index = rv; - JK_TRACE_EXIT(l); - return IND_THIS(uw_map->maps)[rv]->worker_name; - } - JK_TRACE_EXIT(l); - return NULL; -} - -rule_extension_t *get_uri_to_worker_ext(jk_uri_worker_map_t *uw_map, - int index) -{ - if (index >= 0) { - return &(IND_THIS(uw_map->maps)[index]->extensions); - } - else { - return NULL; - } -} - -const char *map_uri_to_worker(jk_uri_worker_map_t *uw_map, - const char *uri, const char *vhost, - jk_logger_t *l) -{ - rule_extension_t *ext; - return map_uri_to_worker_ext(uw_map, uri, vhost, &ext, NULL, l); -} - -int uri_worker_map_load(jk_uri_worker_map_t *uw_map, - jk_logger_t *l) -{ - int rc = JK_FALSE; - jk_map_t *map; - - jk_map_alloc(&map); - if (jk_map_read_properties(map, NULL, uw_map->fname, &uw_map->modified, - JK_MAP_HANDLE_NORMAL, l)) { - int i; - if (JK_IS_DEBUG_LEVEL(l)) - jk_log(l, JK_LOG_DEBUG, - "Loading urimaps from %s with reload check interval %d seconds", - uw_map->fname, uw_map->reload); - uri_worker_map_clear(uw_map, l); - for (i = 0; i < jk_map_size(map); i++) { - const char *u = jk_map_name_at(map, i); - const char *w = jk_map_value_at(map, i); - /* Multiple mappings like : - * /servlets-examples|/ * - * will create two mappings: - * /servlets-examples - * and: - * /servlets-examples/ * - */ - if (strchr(u, '|')) { - char *s, *r = strdup(u); - s = strchr(r, '|'); - *(s++) = '\0'; - /* Add first mapping */ - if (!uri_worker_map_add(uw_map, r, w, SOURCE_TYPE_URIMAP, l)) { - jk_log(l, JK_LOG_ERROR, - "invalid mapping rule %s->%s", r, w); - } - for (; *s; s++) - *(s - 1) = *s; - *(s - 1) = '\0'; - /* add second mapping */ - if (!uri_worker_map_add(uw_map, r, w, SOURCE_TYPE_URIMAP, l)) { - jk_log(l, JK_LOG_ERROR, - "invalid mapping rule %s->%s", r, w); - } - free(r); - } - else if (!uri_worker_map_add(uw_map, u, w, SOURCE_TYPE_URIMAP, l)) { - jk_log(l, JK_LOG_ERROR, - "invalid mapping rule %s->%s", - u, w); - } - } - uw_map->checked = time(NULL); - if (JK_IS_DEBUG_LEVEL(l)) - uri_worker_map_dump(uw_map, "after file load", l); - rc = JK_TRUE; - } - jk_map_free(&map); - return rc; -} - -int uri_worker_map_update(jk_uri_worker_map_t *uw_map, - int force, jk_logger_t *l) -{ - int rc = JK_TRUE; - time_t now = time(NULL); - - if (force || (uw_map->reload > 0 && difftime(now, uw_map->checked) > - uw_map->reload)) { - struct stat statbuf; - uw_map->checked = now; - if ((rc = jk_stat(uw_map->fname, &statbuf)) == -1) { - jk_log(l, JK_LOG_ERROR, - "Unable to stat the %s (errno=%d)", - uw_map->fname, errno); - return JK_FALSE; - } - if (statbuf.st_mtime == uw_map->modified) { - if (JK_IS_DEBUG_LEVEL(l)) - jk_log(l, JK_LOG_DEBUG, - "File %s is not modified", - uw_map->fname); - return JK_TRUE; - } - JK_ENTER_CS(&(uw_map->cs), rc); - /* Check if some other thread updated status */ - if (statbuf.st_mtime == uw_map->modified) { - JK_LEAVE_CS(&(uw_map->cs), rc); - if (JK_IS_DEBUG_LEVEL(l)) - jk_log(l, JK_LOG_DEBUG, - "File %s is not modified", - uw_map->fname); - return JK_TRUE; - } - rc = uri_worker_map_load(uw_map, l); - uri_worker_map_ext(uw_map, l); - uri_worker_map_switch(uw_map, l); - JK_LEAVE_CS(&(uw_map->cs), rc); - jk_log(l, JK_LOG_INFO, - "Reloaded urimaps from %s", uw_map->fname); - } - return JK_TRUE; -} |