jk_uri_worker_map.c

来自「以便Apache与其他服务进行整合 Mod_JK安装」· C语言 代码 · 共 756 行 · 第 1/2 页

C
756
字号
         * 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;    uw_map->maps[uw_map->size] = uwr;    uw_map->size++;    if (match_type & MATCH_TYPE_NO_MATCH) {        /* If we split the mappings this one will be calculated */        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);    uw_map->size = 0;    uw_map->capacity = 0;    if (uw_map) {        int sz;        rc = JK_TRUE;        jk_open_pool(&uw_map->p,                     uw_map->buf, sizeof(jk_pool_atom_t) * SMALL_POOL_SIZE);        uw_map->size = 0;        uw_map->maps = NULL;        sz = jk_map_size(init_data);        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, freing buf");            jk_close_pool(&uw_map->p);        }    }    JK_TRACE_EXIT(l);    return rc;}static int is_nomap_match(jk_uri_worker_map_t *uw_map,                          const char *uri, const char* worker,                          jk_logger_t *l){    unsigned int i;    JK_TRACE_ENTER(l);    for (i = 0; i < uw_map->size; i++) {        uri_worker_record_t *uwr = 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))            continue;        if (uwr->match_type & MATCH_TYPE_WILDCHAR_PATH) {            /* Map is already sorted by context_len */            if (wildchar_match(uri, uwr->context,#ifdef WIN32                               0#else                               0#endif                               ) == 0) {                    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(jk_uri_worker_map_t *uw_map,                              const char *uri, jk_logger_t *l){    unsigned int i;    int reject_unsafe;    const char *rv = NULL;    char  url[JK_MAX_URI_LEN+1];    JK_TRACE_ENTER(l);    if (!uw_map || !uri) {        JK_LOG_NULL_PARAMS(l);        JK_TRACE_EXIT(l);        return NULL;    }    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, l);        if (!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;    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 then %d chars",                   uri, JK_MAX_URI_LEN);            JK_TRACE_EXIT(l);            return NULL;        }        if (uri[i] == ';')            break;        else {            url[i] = uri[i];            if (reject_unsafe && (url[i] == '%' || url[i] == '\\')) {                jk_log(l, JK_LOG_INFO, "Potentially unsafe request url '%s' rejected", uri);                JK_TRACE_EXIT(l);                return NULL;            }        }    }    url[i] = '\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, uw_map->size);    for (i = 0; i < uw_map->size; i++) {        uri_worker_record_t *uwr = 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) {            const char *wname;            /* Map is already sorted by context_len */            if (wildchar_match(url, uwr->context,#ifdef WIN32                               0#else                               0#endif                               ) == 0) {                    wname = uwr->worker_name;                    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);                    rv = wname;                    goto cleanup;             }        }        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);                rv = uwr->worker_name;                goto cleanup;            }        }    }    /* No matches found */    JK_TRACE_EXIT(l);cleanup:    if (rv && uw_map->nosize) {        if (is_nomap_match(uw_map, url, rv, l)) {            if (JK_IS_DEBUG_LEVEL(l))                jk_log(l, JK_LOG_DEBUG,                       "Denying matching for worker %s by nomatch rule",                       rv);            rv = NULL;        }    }    return rv;}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, 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, SOURCE_TYPE_URIMAP, 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);        rc = JK_TRUE;    }    jk_map_free(&map);    return rc;}int uri_worker_map_update(jk_uri_worker_map_t *uw_map,                          jk_logger_t *l){    int rc = JK_TRUE;    time_t now = time(NULL);    if (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);        JK_LEAVE_CS(&(uw_map->cs), rc);        jk_log(l, JK_LOG_INFO,               "Reloaded urimaps from %s", uw_map->fname);    }    return JK_TRUE;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?