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 + -
显示快捷键?