📄 mod_rewrite.c
字号:
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 + -