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

📄 mod_rewrite.c

📁 Apache官方在今天放出产品系列2.2的最新版本2.2.11的源码包 最流行的HTTP服务器软件之一
💻 C
📖 第 1 页 / 共 5 页
字号:
    return value;}static char *lookup_map_program(request_rec *r, apr_file_t *fpin,                                apr_file_t *fpout, char *key){    char *buf;    char c;    apr_size_t i, nbytes, combined_len = 0;    apr_status_t rv;    const char *eol = APR_EOL_STR;    apr_size_t eolc = 0;    int found_nl = 0;    result_list *buflist = NULL, *curbuf = NULL;#ifndef NO_WRITEV    struct iovec iova[2];    apr_size_t niov;#endif    /* when `RewriteEngine off' was used in the per-server     * context then the rewritemap-programs were not spawned.     * In this case using such a map (usually in per-dir context)     * is useless because it is not available.     *     * newlines in the key leave bytes in the pipe and cause     * bad things to happen (next map lookup will use the chars     * after the \n instead of the new key etc etc - in other words,     * the Rewritemap falls out of sync with the requests).     */    if (fpin == NULL || fpout == NULL || ap_strchr(key, '\n')) {        return NULL;    }    /* take the lock */    if (rewrite_mapr_lock_acquire) {        rv = apr_global_mutex_lock(rewrite_mapr_lock_acquire);        if (rv != APR_SUCCESS) {            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,                          "apr_global_mutex_lock(rewrite_mapr_lock_acquire) "                          "failed");            return NULL; /* Maybe this should be fatal? */        }    }    /* write out the request key */#ifdef NO_WRITEV    nbytes = strlen(key);    apr_file_write(fpin, key, &nbytes);    nbytes = 1;    apr_file_write(fpin, "\n", &nbytes);#else    iova[0].iov_base = key;    iova[0].iov_len = strlen(key);    iova[1].iov_base = "\n";    iova[1].iov_len = 1;    niov = 2;    apr_file_writev(fpin, iova, niov, &nbytes);#endif    buf = apr_palloc(r->pool, REWRITE_PRG_MAP_BUF + 1);    /* read in the response value */    nbytes = 1;    apr_file_read(fpout, &c, &nbytes);    do {        i = 0;        while (nbytes == 1 && (i < REWRITE_PRG_MAP_BUF)) {            if (c == eol[eolc]) {                if (!eol[++eolc]) {                    /* remove eol from the buffer */                    --eolc;                    if (i < eolc) {                        curbuf->len -= eolc-i;                        i = 0;                    }                    else {                        i -= eolc;                    }                    ++found_nl;                    break;                }            }            /* only partial (invalid) eol sequence -> reset the counter */            else if (eolc) {                eolc = 0;            }            /* catch binary mode, e.g. on Win32 */            else if (c == '\n') {                ++found_nl;                break;            }            buf[i++] = c;            apr_file_read(fpout, &c, &nbytes);        }        /* well, if there wasn't a newline yet, we need to read further */        if (buflist || (nbytes == 1 && !found_nl)) {            if (!buflist) {                curbuf = buflist = apr_palloc(r->pool, sizeof(*buflist));            }            else if (i) {                curbuf->next = apr_palloc(r->pool, sizeof(*buflist));                curbuf = curbuf->next;            }            curbuf->next = NULL;            if (i) {                curbuf->string = buf;                curbuf->len = i;                combined_len += i;                buf = apr_palloc(r->pool, REWRITE_PRG_MAP_BUF);            }            if (nbytes == 1 && !found_nl) {                i = 0;                continue;            }        }        break;    } while (1);    /* concat the stuff */    if (buflist) {        char *p;        p = buf = apr_palloc(r->pool, combined_len + 1); /* \0 */        while (buflist) {            if (buflist->len) {                memcpy(p, buflist->string, buflist->len);                p += buflist->len;            }            buflist = buflist->next;        }        *p = '\0';        i = combined_len;    }    else {        buf[i] = '\0';    }    /* give the lock back */    if (rewrite_mapr_lock_acquire) {        rv = apr_global_mutex_unlock(rewrite_mapr_lock_acquire);        if (rv != APR_SUCCESS) {            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,                          "apr_global_mutex_unlock(rewrite_mapr_lock_acquire) "                          "failed");            return NULL; /* Maybe this should be fatal? */        }    }    /* catch the "failed" case */    if (i == 4 && !strcasecmp(buf, "NULL")) {        return NULL;    }    return buf;}/* * generic map lookup */static char *lookup_map(request_rec *r, char *name, char *key){    rewrite_server_conf *conf;    rewritemap_entry *s;    char *value;    apr_finfo_t st;    apr_status_t rv;    /* get map configuration */    conf = ap_get_module_config(r->server->module_config, &rewrite_module);    s = apr_hash_get(conf->rewritemaps, name, APR_HASH_KEY_STRING);    /* map doesn't exist */    if (!s) {        return NULL;    }    switch (s->type) {    /*     * Text file map (perhaps random)     */    case MAPTYPE_RND:    case MAPTYPE_TXT:        rv = apr_stat(&st, s->checkfile, APR_FINFO_MIN, r->pool);        if (rv != APR_SUCCESS) {            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,                          "mod_rewrite: can't access text RewriteMap file %s",                          s->checkfile);            rewritelog((r, 1, NULL,                        "can't open RewriteMap file, see error log"));            return NULL;        }        value = get_cache_value(s->cachename, st.mtime, key, r->pool);        if (!value) {            rewritelog((r, 6, NULL,                        "cache lookup FAILED, forcing new map lookup"));            value = lookup_map_txtfile(r, s->datafile, key);            if (!value) {                rewritelog((r, 5, NULL, "map lookup FAILED: map=%s[txt] key=%s",                            name, key));                set_cache_value(s->cachename, st.mtime, key, "");                return NULL;            }            rewritelog((r, 5, NULL,"map lookup OK: map=%s[txt] key=%s -> val=%s",                        name, key, value));            set_cache_value(s->cachename, st.mtime, key, value);        }        else {            rewritelog((r,5,NULL,"cache lookup OK: map=%s[txt] key=%s -> val=%s",                        name, key, value));        }        if (s->type == MAPTYPE_RND && *value) {            value = select_random_value_part(r, value);            rewritelog((r, 5, NULL, "randomly chosen the subvalue `%s'",value));        }        return *value ? value : NULL;    /*     * DBM file map     */    case MAPTYPE_DBM:        rv = apr_stat(&st, s->checkfile, APR_FINFO_MIN, r->pool);        if (rv != APR_SUCCESS) {            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,                          "mod_rewrite: can't access DBM RewriteMap file %s",                          s->checkfile);        }        else if(s->checkfile2 != NULL) {            apr_finfo_t st2;            rv = apr_stat(&st2, s->checkfile2, APR_FINFO_MIN, r->pool);            if (rv != APR_SUCCESS) {                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,                              "mod_rewrite: can't access DBM RewriteMap "                              "file %s", s->checkfile2);            }            else if(st2.mtime > st.mtime) {                st.mtime = st2.mtime;            }        }        if(rv != APR_SUCCESS) {            rewritelog((r, 1, NULL,                        "can't open DBM RewriteMap file, see error log"));            return NULL;        }        value = get_cache_value(s->cachename, st.mtime, key, r->pool);        if (!value) {            rewritelog((r, 6, NULL,                        "cache lookup FAILED, forcing new map lookup"));            value = lookup_map_dbmfile(r, s->datafile, s->dbmtype, key);            if (!value) {                rewritelog((r, 5, NULL, "map lookup FAILED: map=%s[dbm] key=%s",                            name, key));                set_cache_value(s->cachename, st.mtime, key, "");                return NULL;            }            rewritelog((r, 5, NULL, "map lookup OK: map=%s[dbm] key=%s -> "                        "val=%s", name, key, value));            set_cache_value(s->cachename, st.mtime, key, value);            return value;        }        rewritelog((r, 5, NULL, "cache lookup OK: map=%s[dbm] key=%s -> val=%s",                    name, key, value));        return *value ? value : NULL;    /*     * Program file map     */    case MAPTYPE_PRG:        value = lookup_map_program(r, s->fpin, s->fpout, key);        if (!value) {            rewritelog((r, 5,NULL,"map lookup FAILED: map=%s key=%s", name,                        key));            return NULL;        }        rewritelog((r, 5, NULL, "map lookup OK: map=%s key=%s -> val=%s",                    name, key, value));        return value;    /*     * Internal Map     */    case MAPTYPE_INT:        value = s->func(r, key);        if (!value) {            rewritelog((r, 5,NULL,"map lookup FAILED: map=%s key=%s", name,                        key));            return NULL;        }        rewritelog((r, 5, NULL, "map lookup OK: map=%s key=%s -> val=%s",                    name, key, value));        return value;    }    return NULL;}/* * lookup a HTTP header and set VARY note */static const char *lookup_header(const char *name, rewrite_ctx *ctx){    const char *val = apr_table_get(ctx->r->headers_in, name);    if (val) {        ctx->vary_this = ctx->vary_this                         ? apr_pstrcat(ctx->r->pool, ctx->vary_this, ", ",                                       name, NULL)                         : apr_pstrdup(ctx->r->pool, name);    }    return val;}/* * lookahead helper function * Determine the correct URI path in perdir context */static APR_INLINE const char *la_u(rewrite_ctx *ctx){    rewrite_perdir_conf *conf;    if (*ctx->uri == '/') {        return ctx->uri;    }    conf = ap_get_module_config(ctx->r->per_dir_config, &rewrite_module);    return apr_pstrcat(ctx->r->pool, conf->baseurl                                     ? conf->baseurl : conf->directory,                       ctx->uri, NULL);}/* * generic variable lookup */static char *lookup_variable(char *var, rewrite_ctx *ctx){    const char *result;    request_rec *r = ctx->r;    apr_size_t varlen = strlen(var);    /* fast exit */    if (varlen < 4) {        return apr_pstrdup(r->pool, "");    }    result = NULL;    /* fast tests for variable length variables (sic) first */    if (var[3] == ':') {        if (var[4] && !strncasecmp(var, "ENV", 3)) {            var += 4;            result = apr_table_get(r->notes, var);            if (!result) {                result = apr_table_get(r->subprocess_env, var);            }            if (!result) {                result = getenv(var);            }        }        else if (var[4] && !strncasecmp(var, "SSL", 3) && rewrite_ssl_lookup) {            result = rewrite_ssl_lookup(r->pool, r->server, r->connection, r,                                        var + 4);        }    }    else if (var[4] == ':') {        if (var[5]) {            request_rec *rr;            const char *path;            if (!strncasecmp(var, "HTTP", 4)) {                result = lookup_header(var+5, ctx);            }            else if (!strncasecmp(var, "LA-U", 4)) {                if (ctx->uri && subreq_ok(r)) {                    path = ctx->perdir ? la_u(ctx) : ctx->uri;                    rr = ap_sub_req_lookup_uri(path, r, NULL);                    ctx->r = rr;                    result = apr_pstrdup(r->pool, lookup_variable(var+5, ctx));                    ctx->r = r;                    ap_destroy_sub_req(rr);                    rewritelog((r, 5, ctx->perdir, "lookahead: path=%s var=%s "                                "-> val=%s", path, var+5, result));                    return (char *)result;                }            }            else if (!strncasecmp(var, "LA-F", 4)) {                if (ctx->uri && subreq_ok(r)) {                    path = ctx->uri;                    if (ctx->perdir && *path == '/') {                        /* sigh, the user wants a file based subrequest, but                         * we can't do one, since we don't know what the file                         * path is! In this case behave like LA-U.                         */                        rr = ap_sub_req_lookup_uri(path, r, NULL);                    }                    else {                        if (ctx->perdir) {                            rewrite_perdir_conf *conf;                            conf = ap_get_module_config(r->per_dir_config,                                                        &rewrite_module);                            path = apr_pstrcat(r->pool, conf->directory, path,                                               NULL);                        }                        rr = ap_sub_req_lookup_file(path, r, NULL);                    }                    ctx->r = rr;                    result = apr_pstrdup(r->pool, lookup_variable(var+5, ctx));

⌨️ 快捷键说明

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