diff options
author | Graham Leggett <minfrin@apache.org> | 2013-12-30 20:50:52 +0100 |
---|---|---|
committer | Graham Leggett <minfrin@apache.org> | 2013-12-30 20:50:52 +0100 |
commit | 43e022f007cf8cde3b1cbe577de74464e10f2f55 (patch) | |
tree | a03d807274e739557b4d8f4480745d11272c6e4a /server/request.c | |
parent | xforms (diff) | |
download | apache2-43e022f007cf8cde3b1cbe577de74464e10f2f55.tar.xz apache2-43e022f007cf8cde3b1cbe577de74464e10f2f55.zip |
core: Support named groups and backreferences within the LocationMatch,
DirectoryMatch, FilesMatch and ProxyMatch directives.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1554300 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'server/request.c')
-rw-r--r-- | server/request.c | 122 |
1 files changed, 111 insertions, 11 deletions
diff --git a/server/request.c b/server/request.c index 12dd58c315..736c4c444e 100644 --- a/server/request.c +++ b/server/request.c @@ -741,6 +741,7 @@ AP_DECLARE(int) ap_directory_walk(request_rec *r) apr_size_t buflen; char *buf; unsigned int seg, startseg; + apr_pool_t *rxpool = NULL; /* Invariant: from the first time filename_len is set until * it goes out of scope, filename_len==strlen(r->filename) @@ -1196,6 +1197,10 @@ AP_DECLARE(int) ap_directory_walk(request_rec *r) */ for (; sec_idx < num_sec; ++sec_idx) { + int nmatch = 0; + int i; + ap_regmatch_t *pmatch = NULL; + core_dir_config *entry_core; entry_core = ap_get_core_module_config(sec_ent[sec_idx]); @@ -1203,10 +1208,29 @@ AP_DECLARE(int) ap_directory_walk(request_rec *r) continue; } - if (ap_regexec(entry_core->r, r->filename, 0, NULL, 0)) { + if (entry_core->refs && entry_core->refs->nelts) { + if (!rxpool) { + apr_pool_create(&rxpool, r->pool); + } + nmatch = entry_core->refs->nelts; + pmatch = apr_palloc(rxpool, nmatch*sizeof(ap_regmatch_t)); + } + + if (ap_regexec(entry_core->r, r->filename, nmatch, pmatch, 0)) { continue; } + for (i = 0; i < nmatch; i++) { + if (pmatch[i].rm_so >= 0 && pmatch[i].rm_eo >= 0 && + ((const char **)entry_core->refs->elts)[i]) { + apr_table_setn(r->subprocess_env, + ((const char **)entry_core->refs->elts)[i], + apr_pstrndup(r->pool, + r->filename + pmatch[i].rm_so, + pmatch[i].rm_eo - pmatch[i].rm_so)); + } + } + /* If we haven't already continue'd above, we have a match. * * Calculate our full-context core opts & override. @@ -1245,6 +1269,10 @@ AP_DECLARE(int) ap_directory_walk(request_rec *r) last_walk->merged = now_merged; } + if (rxpool) { + apr_pool_destroy(rxpool); + } + /* Whoops - everything matched in sequence, but either the original * walk found some additional matches (which we need to truncate), or * this walk found some additional matches. @@ -1382,6 +1410,7 @@ AP_DECLARE(int) ap_location_walk(request_rec *r) int matches = cache->walked->nelts; int cached_matches = matches; walk_walked_t *last_walk = (walk_walked_t*)cache->walked->elts; + apr_pool_t *rxpool = NULL; cached &= auth_internal_per_conf; cache->cached = entry_uri; @@ -1403,16 +1432,48 @@ AP_DECLARE(int) ap_location_walk(request_rec *r) * not slash terminated, then this uri must be slash * terminated (or at the end of the string) to match. */ - if (entry_core->r - ? ap_regexec(entry_core->r, r->uri, 0, NULL, 0) - : (entry_core->d_is_fnmatch + if (entry_core->r) { + + int nmatch = 0; + int i; + ap_regmatch_t *pmatch = NULL; + + if (entry_core->refs && entry_core->refs->nelts) { + if (!rxpool) { + apr_pool_create(&rxpool, r->pool); + } + nmatch = entry_core->refs->nelts; + pmatch = apr_palloc(rxpool, nmatch*sizeof(ap_regmatch_t)); + } + + if (ap_regexec(entry_core->r, r->uri, nmatch, pmatch, 0)) { + continue; + } + + for (i = 0; i < nmatch; i++) { + if (pmatch[i].rm_so >= 0 && pmatch[i].rm_eo >= 0 && + ((const char **)entry_core->refs->elts)[i]) { + apr_table_setn(r->subprocess_env, + ((const char **)entry_core->refs->elts)[i], + apr_pstrndup(r->pool, + r->uri + pmatch[i].rm_so, + pmatch[i].rm_eo - pmatch[i].rm_so)); + } + } + + } + else { + + if ((entry_core->d_is_fnmatch ? apr_fnmatch(entry_core->d, cache->cached, APR_FNM_PATHNAME) : (strncmp(entry_core->d, cache->cached, len) || (len > 0 && entry_core->d[len - 1] != '/' && cache->cached[len] != '/' && cache->cached[len] != '\0')))) { - continue; + continue; + } + } /* If we merged this same section last time, reuse it @@ -1447,6 +1508,10 @@ AP_DECLARE(int) ap_location_walk(request_rec *r) last_walk->merged = now_merged; } + if (rxpool) { + apr_pool_destroy(rxpool); + } + /* Whoops - everything matched in sequence, but either the original * walk found some additional matches (which we need to truncate), or * this walk found some additional matches. @@ -1556,6 +1621,7 @@ AP_DECLARE(int) ap_file_walk(request_rec *r) int matches = cache->walked->nelts; int cached_matches = matches; walk_walked_t *last_walk = (walk_walked_t*)cache->walked->elts; + apr_pool_t *rxpool = NULL; cached &= auth_internal_per_conf; cache->cached = test_file; @@ -1568,12 +1634,42 @@ AP_DECLARE(int) ap_file_walk(request_rec *r) core_dir_config *entry_core; entry_core = ap_get_core_module_config(sec_ent[sec_idx]); - if (entry_core->r - ? ap_regexec(entry_core->r, cache->cached , 0, NULL, 0) - : (entry_core->d_is_fnmatch - ? apr_fnmatch(entry_core->d, cache->cached, APR_FNM_PATHNAME) - : strcmp(entry_core->d, cache->cached))) { - continue; + if (entry_core->r) { + + int nmatch = 0; + int i; + ap_regmatch_t *pmatch = NULL; + + if (entry_core->refs && entry_core->refs->nelts) { + if (!rxpool) { + apr_pool_create(&rxpool, r->pool); + } + nmatch = entry_core->refs->nelts; + pmatch = apr_palloc(rxpool, nmatch*sizeof(ap_regmatch_t)); + } + + if (ap_regexec(entry_core->r, cache->cached, nmatch, pmatch, 0)) { + continue; + } + + for (i = 0; i < nmatch; i++) { + if (pmatch[i].rm_so >= 0 && pmatch[i].rm_eo >= 0 && + ((const char **)entry_core->refs->elts)[i]) { + apr_table_setn(r->subprocess_env, + ((const char **)entry_core->refs->elts)[i], + apr_pstrndup(r->pool, + cache->cached + pmatch[i].rm_so, + pmatch[i].rm_eo - pmatch[i].rm_so)); + } + } + + } + else { + if ((entry_core->d_is_fnmatch + ? apr_fnmatch(entry_core->d, cache->cached, APR_FNM_PATHNAME) + : strcmp(entry_core->d, cache->cached))) { + continue; + } } /* If we merged this same section last time, reuse it @@ -1608,6 +1704,10 @@ AP_DECLARE(int) ap_file_walk(request_rec *r) last_walk->merged = now_merged; } + if (rxpool) { + apr_pool_destroy(rxpool); + } + /* Whoops - everything matched in sequence, but either the original * walk found some additional matches (which we need to truncate), or * this walk found some additional matches. |