From: Yann Ylavic Date: Tue, 1 Mar 2022 13:26:03 +0000 (+0000) Subject: mod_rewrite: URI-to-filename rewrites to transparently handle proxy mappings. X-Git-Tag: 2.5.0-alpha2-ci-test-only~465 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=815cf05bb2d506f44a35b65e93de393d5410c779;p=thirdparty%2Fapache%2Fhttpd.git mod_rewrite: URI-to-filename rewrites to transparently handle proxy mappings. Since mod_rewrite works on r->filename and mod_proxy's mapping=servlet|decoded sets its "proxy:" URL there at pre_translate_name stage (i.e. before mod_rewrite's translate_name hook), users have to match the full proxy URL in their RewriteRules to handle proxy mappings, which is not very friendly nor consistent with how proxy non-mapping requests have to be matched. Let's use r->filename = r->uri in hook_uri2file() for pre_trans'ed reverse proxy requests, and restore r->filename to its original value if the request was finally DECLINED (like in hook_fixup). But if a proxy mapping gets rewritten to a non-proxy request, clear any proxy specific r->proxyreq or r->handler so that processing continues accordingly. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1898509 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/changes-entries/rewrite_vs_proxy_mapping.txt b/changes-entries/rewrite_vs_proxy_mapping.txt new file mode 100644 index 00000000000..b8e2ec48268 --- /dev/null +++ b/changes-entries/rewrite_vs_proxy_mapping.txt @@ -0,0 +1,2 @@ + *) mod_rewrite: Make URI-to-filename rewrites work transparently with + proxy early mappings (mapping=servlet/decoded). [Yann Ylavic] \ No newline at end of file diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c index 343b700c75c..94aefc9c20c 100644 --- a/modules/mappers/mod_rewrite.c +++ b/modules/mappers/mod_rewrite.c @@ -4660,6 +4660,7 @@ static int hook_uri2file(request_rec *r) unsigned int port; int rulestatus; void *skipdata; + char *ofilename; const char *oargs; /* @@ -4713,7 +4714,10 @@ static int hook_uri2file(request_rec *r) /* * remember the original query string for later check, since we don't * want to apply URL-escaping when no substitution has changed it. + * also, we'll restore original r->filename if we decline this + * request. */ + ofilename = r->filename; oargs = r->args; /* @@ -4756,13 +4760,15 @@ static int hook_uri2file(request_rec *r) apr_table_setn(r->subprocess_env, ENVVAR_SCRIPT_URI, var); if (!(saved_rulestatus = apr_table_get(r->notes,"mod_rewrite_rewritten"))) { - /* if filename was not initially set, - * we start with the requested URI + /* If r->filename was not initially set or if it's a pre_trans reverse + * "proxy:" scheme, we start with the requested URI. */ - if (r->filename == NULL) { + if (r->filename == NULL || (r->proxyreq == PROXYREQ_REVERSE && + strncmp(r->filename, "proxy:", 6) == 0)) { r->filename = apr_pstrdup(r->pool, r->uri); - rewritelog(r, 2, NULL, "init rewrite engine with requested uri %s", - r->filename); + rewritelog(r, 2, NULL, "init rewrite engine with requested uri " + "%s. Original filename = %s", r->filename, + (ofilename) ? ofilename : "n/a"); } else { rewritelog(r, 2, NULL, "init rewrite engine with passed filename " @@ -4786,6 +4792,7 @@ static int hook_uri2file(request_rec *r) if (rulestatus) { unsigned skip; apr_size_t flen; + int to_proxyreq; if (ACTION_STATUS == rulestatus) { int n = r->status; @@ -4795,7 +4802,19 @@ static int hook_uri2file(request_rec *r) } flen = r->filename ? strlen(r->filename) : 0; - if (flen > 6 && strncmp(r->filename, "proxy:", 6) == 0) { + to_proxyreq = (flen > 6 && strncmp(r->filename, "proxy:", 6) == 0); + + /* If a pre_trans reverse "proxy:" filename gets rewritten to + * a non-proxy one this is not a proxy request anymore. + */ + if (r->proxyreq == PROXYREQ_REVERSE && !to_proxyreq) { + if (r->handler && strcmp(r->handler, "proxy-server") == 0) { + r->handler = NULL; + } + r->proxyreq = PROXYREQ_NONE; + } + + if (to_proxyreq) { /* it should be go on as an internal proxy request */ /* check if the proxy module is enabled, so @@ -4962,7 +4981,9 @@ static int hook_uri2file(request_rec *r) } } else { - rewritelog(r, 1, NULL, "pass through %s", r->filename); + rewritelog(r, 1, NULL, "pass through %s, filename %s", + r->filename, (ofilename) ? ofilename : "n/a"); + r->filename = ofilename; return DECLINED; } } @@ -5309,7 +5330,8 @@ static int hook_fixup(request_rec *r) } } else { - rewritelog(r, 1, dconf->directory, "pass through %s", r->filename); + rewritelog(r, 1, dconf->directory, "pass through %s, filename %s", + r->filename, (ofilename) ? ofilename : "n/a"); r->filename = ofilename; return DECLINED; }