jk_uri_worker_map.c
来自「以便Apache与其他服务进行整合 Mod_JK安装」· C语言 代码 · 共 756 行 · 第 1/2 页
C
756 行
/* * 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: 562174 $ * ***************************************************************************/#include "jk_pool.h"#include "jk_util.h"#include "jk_map.h"#include "jk_mt.h"#include "jk_uri_worker_map.h"#ifdef WIN32#define JK_STRCMP strcasecmp#define JK_STRNCMP strnicmp#else#define JK_STRCMP strcmp#define JK_STRNCMP strncmp#endifstatic 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 *)uw_map->maps, uw_map->size, sizeof(uri_worker_record_t *), worker_compare );}/* Match = 0, NoMatch = 1, Abort = -1 * Based loosely on sections of wildmat.c by Rich Salz */static int wildchar_match(const char *str, const char *exp, int icase){ int x, y; for (x = 0, y = 0; exp[y]; ++y, ++x) { if (!str[x] && exp[y] != '*') return -1; if (exp[y] == '*') { while (exp[++y] == '*'); if (!exp[y]) return 0; while (str[x]) { int ret; if ((ret = wildchar_match(&str[x++], &exp[y], icase)) != 1) return ret; } return -1; } else if (exp[y] != '?') { if (icase && (tolower(str[x]) != tolower(exp[y]))) return 1; else if (!icase && str[x] != exp[y]) return 1; } } return (str[x] != '\0');}int uri_worker_map_alloc(jk_uri_worker_map_t **uw_map, jk_map_t *init_data, jk_logger_t *l){ JK_TRACE_ENTER(l); if (uw_map) { int rc; *uw_map = (jk_uri_worker_map_t *)calloc(1, sizeof(jk_uri_worker_map_t)); 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; } 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); 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 (uw_map->size == uw_map->capacity) { uri_worker_record_t **uwr; int capacity = uw_map->capacity + UW_INC_SIZE; uwr = (uri_worker_record_t **) jk_pool_alloc(&uw_map->p, sizeof(uri_worker_record_t *) * capacity); if (!uwr) return JK_FALSE; if (uw_map->capacity && uw_map->maps) memcpy(uwr, uw_map->maps, sizeof(uri_worker_record_t *) * uw_map->capacity); uw_map->maps = uwr; 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, unsigned int source_type, jk_logger_t *l){ uri_worker_record_t *uwr = NULL; unsigned int i; unsigned int j; JK_TRACE_ENTER(l); for (i = 0; i < uw_map->size; i++) { uwr = uw_map->maps[i]; if (uwr->source_type == source_type) { 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)); for (j = i; j < uw_map->size-1; j++) uw_map->maps[j] = uw_map->maps[j+1]; uw_map->size--; i--; } } JK_TRACE_EXIT(l); return JK_TRUE;}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; 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; } uwr = (uri_worker_record_t *)jk_pool_alloc(&uw_map->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(&uw_map->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 == '/') { uwr->uri = uri; uwr->context = uri; uwr->worker_name = jk_pool_strdup(&uw_map->p, worker); uwr->context_len = strlen(uwr->context); uwr->source_type = source_type; if (strchr(uri, '*') || strchr(uri, '?')) { /* Something like * /context/ * /user/ * * /context/ *.suffix */ match_type |= MATCH_TYPE_WILDCHAR_PATH; 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; 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 { /*
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?