jk_uri_worker_map.c

来自「精通tomcat书籍原代码,希望大家共同学习」· C语言 代码 · 共 628 行 · 第 1/2 页

C
628
字号
    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",
               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++) {
                if (uri_worker_map_add
                    (uw_map, jk_map_name_at(init_data, i),
                     jk_map_value_at(init_data, i), l) == JK_FALSE) {
                    rc = JK_FALSE;
                    break;
                }
            }

            if (i == sz) {
                if (JK_IS_DEBUG_LEVEL(l))
                    jk_log(l, JK_LOG_DEBUG,
                           "there are %d rules",
                           uw_map->size);
            }
            else {
                jk_log(l, JK_LOG_ERROR,
                       "Parsing error");
                rc = JK_FALSE;
            }
        }

        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 mathing 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
                               1
#else
                               0
#endif
                               ) == 0) {
                    jk_log(l, JK_LOG_DEBUG,
                           "Found a no match %s -> %s",
                           uwr->worker_name, uwr->context);
                    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",
                            uwr->worker_name, uwr->context);
                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;
    char *url_rewrite;
    const char *rv = NULL;
    const char *url = uri;
    char  buf[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;
    }
    url_rewrite = strstr(uri, JK_PATH_SESSION_IDENTIFIER);
    if (url_rewrite) {
        size_t len = url_rewrite - uri;
        if (len > JK_MAX_URI_LEN)
            len = JK_MAX_URI_LEN;
        strncpy(buf, uri, len);
        buf[len] = '\0';
        url = &buf[0];
        if (JK_IS_DEBUG_LEVEL(l))
            jk_log(l, JK_LOG_DEBUG, "Removing Session path '%s' URI '%s'",
                   url_rewrite, url);
    }
    if (uw_map->fname)
        uri_worker_map_update(uw_map, l);
    if (JK_IS_DEBUG_LEVEL(l))
        jk_log(l, JK_LOG_DEBUG, "Attempting to map URI '%s' from %d maps",
               uri, 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'", uwr->uri);

        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
                               1
#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->worker_name, uwr->context);
                    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->worker_name, uwr->context);
                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)) {
        int i;
        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, 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, 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, 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 ((now - uw_map->checked) > JK_URIMAP_RELOAD) {
        struct stat statbuf;
        uw_map->checked = now;
        if ((rc = stat(uw_map->fname, &statbuf)) == -1)
            return JK_FALSE;
        if (statbuf.st_mtime == uw_map->modified)
            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);
            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 rc;
}

⌨️ 快捷键说明

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