jk_uri_worker_map.c
来自「精通tomcat书籍原代码,希望大家共同学习」· C语言 代码 · 共 628 行 · 第 1/2 页
C
628 行
/*
* Copyright 1999-2004 The Apache Software Foundation
*
* Licensed 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: 386282 $ *
***************************************************************************/
#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
#endif
/*
* 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
*/
return ((int)e2->context_len - (int)e1->context_len);
}
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;
}
int uri_worker_map_add(jk_uri_worker_map_t *uw_map,
const char *puri, const char *worker, jk_logger_t *l)
{
uri_worker_record_t *uwr = NULL;
char *uri;
unsigned int match_type = 0;
unsigned int i;
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++;
}
/* Find if duplicate entry */
for (i = 0; i < uw_map->size; i++) {
uwr = uw_map->maps[i];
if (strcmp(uwr->uri, puri) == 0) {
/* Update disabled flag */
if (match_type & MATCH_TYPE_DISABLED)
uwr->match_type |= MATCH_TYPE_DISABLED;
else
uwr->match_type &= ~MATCH_TYPE_DISABLED;
if (strcmp(uwr->worker_name, worker) == 0) {
jk_log(l, JK_LOG_DEBUG,
"map rule %s=%s already exists",
puri, worker);
JK_TRACE_EXIT(l);
return JK_TRUE;
}
else {
jk_log(l, JK_LOG_DEBUG,
"changing map rule %s=%s ",
puri, worker);
uwr->worker_name = jk_pool_strdup(&uw_map->p, worker);
JK_TRACE_EXIT(l);
return JK_TRUE;
}
}
}
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 == '/') {
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 was added",
uri, worker);
}
else {
/* Something like: JkMount /login/j_security_check ajp13 */
match_type |= MATCH_TYPE_EXACT;
jk_log(l, JK_LOG_DEBUG,
"exact rule %s=%s was added",
uri, worker);
}
uwr->uri = uri;
uwr->context = uri;
uwr->worker_name = jk_pool_strdup(&uw_map->p, worker);
uwr->context_len = strlen(uwr->context);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?