⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mod_rewrite.c

📁 Apache官方在今天放出产品系列2.2的最新版本2.2.11的源码包 最流行的HTTP服务器软件之一
💻 C
📖 第 1 页 / 共 5 页
字号:
    }    return 0;}/* * substitute the prefix path 'match' in 'input' with 'subst' (RewriteBase) */static char *subst_prefix_path(request_rec *r, char *input, char *match,                               const char *subst){    apr_size_t len = strlen(match);    if (len && match[len - 1] == '/') {        --len;    }    if (!strncmp(input, match, len) && input[len++] == '/') {        apr_size_t slen, outlen;        char *output;        rewritelog((r, 5, NULL, "strip matching prefix: %s -> %s", input,                    input+len));        slen = strlen(subst);        if (slen && subst[slen - 1] != '/') {            ++slen;        }        outlen = strlen(input) + slen - len;        output = apr_palloc(r->pool, outlen + 1); /* don't forget the \0 */        memcpy(output, subst, slen);        if (slen && !output[slen-1]) {            output[slen-1] = '/';        }        memcpy(output+slen, input+len, outlen - slen);        output[outlen] = '\0';        rewritelog((r, 4, NULL, "add subst prefix: %s -> %s", input+len,                    output));        return output;    }    /* prefix didn't match */    return input;}/* * +-------------------------------------------------------+ * |                                                       | * |                    caching support * |                                                       | * +-------------------------------------------------------+ */static void set_cache_value(const char *name, apr_time_t t, char *key,                            char *val){    cachedmap *map;    if (cachep) {#if APR_HAS_THREADS        apr_thread_mutex_lock(cachep->lock);#endif        map = apr_hash_get(cachep->maps, name, APR_HASH_KEY_STRING);        if (!map) {            apr_pool_t *p;            if (apr_pool_create(&p, cachep->pool) != APR_SUCCESS) {#if APR_HAS_THREADS                apr_thread_mutex_unlock(cachep->lock);#endif                return;            }            map = apr_palloc(cachep->pool, sizeof(cachedmap));            map->pool = p;            map->entries = apr_hash_make(map->pool);            map->mtime = t;            apr_hash_set(cachep->maps, name, APR_HASH_KEY_STRING, map);        }        else if (map->mtime != t) {            apr_pool_clear(map->pool);            map->entries = apr_hash_make(map->pool);            map->mtime = t;        }        /* Now we should have a valid map->entries hash, where we         * can store our value.         *         * We need to copy the key and the value into OUR pool,         * so that we don't leave it during the r->pool cleanup.         */        apr_hash_set(map->entries,                     apr_pstrdup(map->pool, key), APR_HASH_KEY_STRING,                     apr_pstrdup(map->pool, val));#if APR_HAS_THREADS        apr_thread_mutex_unlock(cachep->lock);#endif    }    return;}static char *get_cache_value(const char *name, apr_time_t t, char *key,                             apr_pool_t *p){    cachedmap *map;    char *val = NULL;    if (cachep) {#if APR_HAS_THREADS        apr_thread_mutex_lock(cachep->lock);#endif        map = apr_hash_get(cachep->maps, name, APR_HASH_KEY_STRING);        if (map) {            /* if this map is outdated, forget it. */            if (map->mtime != t) {                apr_pool_clear(map->pool);                map->entries = apr_hash_make(map->pool);                map->mtime = t;            }            else {                val = apr_hash_get(map->entries, key, APR_HASH_KEY_STRING);                if (val) {                    /* copy the cached value into the supplied pool,                     * where it belongs (r->pool usually)                     */                    val = apr_pstrdup(p, val);                }            }        }#if APR_HAS_THREADS        apr_thread_mutex_unlock(cachep->lock);#endif    }    return val;}static int init_cache(apr_pool_t *p){    cachep = apr_palloc(p, sizeof(cache));    if (apr_pool_create(&cachep->pool, p) != APR_SUCCESS) {        cachep = NULL; /* turns off cache */        return 0;    }    cachep->maps = apr_hash_make(cachep->pool);#if APR_HAS_THREADS    (void)apr_thread_mutex_create(&(cachep->lock), APR_THREAD_MUTEX_DEFAULT, p);#endif    return 1;}/* * +-------------------------------------------------------+ * |                                                       | * |                    Map Functions * |                                                       | * +-------------------------------------------------------+ *//* * General Note: key is already a fresh string, created (expanded) just * for the purpose to be passed in here. So one can modify key itself. */static char *rewrite_mapfunc_toupper(request_rec *r, char *key){    char *p;    for (p = key; *p; ++p) {        *p = apr_toupper(*p);    }    return key;}static char *rewrite_mapfunc_tolower(request_rec *r, char *key){    ap_str_tolower(key);    return key;}static char *rewrite_mapfunc_escape(request_rec *r, char *key){    return ap_escape_uri(r->pool, key);}static char *rewrite_mapfunc_unescape(request_rec *r, char *key){    ap_unescape_url(key);    return key;}static char *select_random_value_part(request_rec *r, char *value){    char *p = value;    unsigned n = 1;    /* count number of distinct values */    while ((p = ap_strchr(p, '|')) != NULL) {        ++n;        ++p;    }    if (n > 1) {        /* initialize random generator         *         * XXX: Probably this should be wrapped into a thread mutex,         * shouldn't it? Is it worth the effort?         */        if (!rewrite_rand_init_done) {            srand((unsigned)(getpid()));            rewrite_rand_init_done = 1;        }        /* select a random subvalue */        n = (int)(((double)(rand() % RAND_MAX) / RAND_MAX) * n + 1);        /* extract it from the whole string */        while (--n && (value = ap_strchr(value, '|')) != NULL) {            ++value;        }        if (value) { /* should not be NULL, but ... */            p = ap_strchr(value, '|');            if (p) {                *p = '\0';            }        }    }    return value;}/* child process code */static void rewrite_child_errfn(apr_pool_t *p, apr_status_t err,                                const char *desc){    ap_log_error(APLOG_MARK, APLOG_ERR, err, NULL, "%s", desc);}static apr_status_t rewritemap_program_child(apr_pool_t *p,                                             const char *progname, char **argv,                                             apr_file_t **fpout,                                             apr_file_t **fpin){    apr_status_t rc;    apr_procattr_t *procattr;    apr_proc_t *procnew;    if (   APR_SUCCESS == (rc=apr_procattr_create(&procattr, p))        && APR_SUCCESS == (rc=apr_procattr_io_set(procattr, APR_FULL_BLOCK,                                                  APR_FULL_BLOCK, APR_NO_PIPE))        && APR_SUCCESS == (rc=apr_procattr_dir_set(procattr,                                             ap_make_dirstr_parent(p, argv[0])))        && APR_SUCCESS == (rc=apr_procattr_cmdtype_set(procattr, APR_PROGRAM))        && APR_SUCCESS == (rc=apr_procattr_child_errfn_set(procattr,                                                           rewrite_child_errfn))        && APR_SUCCESS == (rc=apr_procattr_error_check_set(procattr, 1))) {        procnew = apr_pcalloc(p, sizeof(*procnew));        rc = apr_proc_create(procnew, argv[0], (const char **)argv, NULL,                             procattr, p);        if (rc == APR_SUCCESS) {            apr_pool_note_subprocess(p, procnew, APR_KILL_AFTER_TIMEOUT);            if (fpin) {                (*fpin) = procnew->in;            }            if (fpout) {                (*fpout) = procnew->out;            }        }    }    return (rc);}static apr_status_t run_rewritemap_programs(server_rec *s, apr_pool_t *p){    rewrite_server_conf *conf;    apr_hash_index_t *hi;    apr_status_t rc;    int lock_warning_issued = 0;    conf = ap_get_module_config(s->module_config, &rewrite_module);    /*  If the engine isn't turned on,     *  don't even try to do anything.     */    if (conf->state == ENGINE_DISABLED) {        return APR_SUCCESS;    }    for (hi = apr_hash_first(p, conf->rewritemaps); hi; hi = apr_hash_next(hi)){        apr_file_t *fpin = NULL;        apr_file_t *fpout = NULL;        rewritemap_entry *map;        void *val;        apr_hash_this(hi, NULL, NULL, &val);        map = val;        if (map->type != MAPTYPE_PRG) {            continue;        }        if (!(map->argv[0]) || !*(map->argv[0]) || map->fpin || map->fpout) {            continue;        }        if (!lock_warning_issued && (!lockname || !*lockname)) {            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,                         "mod_rewrite: Running external rewrite maps "                         "without defining a RewriteLock is DANGEROUS!");            ++lock_warning_issued;        }        rc = rewritemap_program_child(p, map->argv[0], map->argv,                                      &fpout, &fpin);        if (rc != APR_SUCCESS || fpin == NULL || fpout == NULL) {            ap_log_error(APLOG_MARK, APLOG_ERR, rc, s,                         "mod_rewrite: could not start RewriteMap "                         "program %s", map->checkfile);            return rc;        }        map->fpin  = fpin;        map->fpout = fpout;    }    return APR_SUCCESS;}/* * +-------------------------------------------------------+ * |                                                       | * |                  Lookup functions * |                                                       | * +-------------------------------------------------------+ */static char *lookup_map_txtfile(request_rec *r, const char *file, char *key){    apr_file_t *fp = NULL;    char line[REWRITE_MAX_TXT_MAP_LINE + 1]; /* +1 for \0 */    char *value, *keylast;    if (apr_file_open(&fp, file, APR_READ|APR_BUFFERED, APR_OS_DEFAULT,                      r->pool) != APR_SUCCESS) {        return NULL;    }    keylast = key + strlen(key);    value = NULL;    while (apr_file_gets(line, sizeof(line), fp) == APR_SUCCESS) {        char *p, *c;        /* ignore comments and lines starting with whitespaces */        if (*line == '#' || apr_isspace(*line)) {            continue;        }        p = line;        c = key;        while (c < keylast && *p == *c && !apr_isspace(*p)) {            ++p;            ++c;        }        /* key doesn't match - ignore. */        if (c != keylast || !apr_isspace(*p)) {            continue;        }        /* jump to the value */        while (*p && apr_isspace(*p)) {            ++p;        }        /* no value? ignore */        if (!*p) {            continue;        }        /* extract the value and return. */        c = p;        while (*p && !apr_isspace(*p)) {            ++p;        }        value = apr_pstrmemdup(r->pool, c, p - c);        break;    }    apr_file_close(fp);    return value;}static char *lookup_map_dbmfile(request_rec *r, const char *file,                                const char *dbmtype, char *key){    apr_dbm_t *dbmfp = NULL;    apr_datum_t dbmkey;    apr_datum_t dbmval;    char *value;    if (apr_dbm_open_ex(&dbmfp, dbmtype, file, APR_DBM_READONLY, APR_OS_DEFAULT,                        r->pool) != APR_SUCCESS) {        return NULL;    }    dbmkey.dptr  = key;    dbmkey.dsize = strlen(key);    if (apr_dbm_fetch(dbmfp, dbmkey, &dbmval) == APR_SUCCESS && dbmval.dptr) {        value = apr_pstrmemdup(r->pool, dbmval.dptr, dbmval.dsize);    }    else {        value = NULL;    }    apr_dbm_close(dbmfp);

⌨️ 快捷键说明

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