summaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
authorYann Ylavic <ylavic@apache.org>2020-06-26 14:51:08 +0200
committerYann Ylavic <ylavic@apache.org>2020-06-26 14:51:08 +0200
commiteb4ba427a437b4e0c775a5dca9ddadce2a955a35 (patch)
treed126840cdd935065af3bda03be98afa755acf947 /modules
parentAdd a plain mod_cgid build, explicitly without mod_cgi. (diff)
downloadapache2-eb4ba427a437b4e0c775a5dca9ddadce2a955a35.tar.xz
apache2-eb4ba427a437b4e0c775a5dca9ddadce2a955a35.zip
Follow up to r1879080 and r1879137: servlet-normalize r->uri if matched.
If a ProxyPass mapping=servlet matches (in pre_trans hook), update r->uri with the servlet normalization so that later <Location> or any dir context match does not have to handle potential path parameters. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1879235 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'modules')
-rw-r--r--modules/proxy/mod_proxy.c34
-rw-r--r--modules/proxy/mod_proxy.h6
2 files changed, 32 insertions, 8 deletions
diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c
index 4fddfeeb39..62dca77635 100644
--- a/modules/proxy/mod_proxy.c
+++ b/modules/proxy/mod_proxy.c
@@ -17,6 +17,7 @@
#include "mod_proxy.h"
#include "mod_core.h"
#include "apr_optional.h"
+#include "apr_strings.h"
#include "scoreboard.h"
#include "mod_status.h"
#include "proxy_util.h"
@@ -574,10 +575,11 @@ static int alias_match(const char *uri, const char *alias_fakename)
* Inspired by mod_jk's jk_servlet_normalize().
*/
static int alias_match_servlet(apr_pool_t *p,
- const char *uri,
+ const char **urip,
const char *alias)
{
char *map;
+ const char *uri = *urip;
apr_array_header_t *stack;
int map_pos, uri_pos, alias_pos, first_pos;
int alias_depth = 0, depth;
@@ -759,6 +761,8 @@ static int alias_match_servlet(apr_pool_t *p,
if (alias[alias_pos - 1] != '/' && uri[uri_pos - 1] == '/') {
uri_pos--;
}
+
+ *urip = map;
return uri_pos;
}
@@ -872,6 +876,7 @@ PROXY_DECLARE(int) ap_proxy_trans_match(request_rec *r, struct proxy_alias *ent,
int mismatch = 0;
unsigned int nocanon = ent->flags & PROXYPASS_NOCANON;
const char *use_uri = nocanon ? r->unparsed_uri : r->uri;
+ const char *servlet_uri = NULL;
if (dconf && (dconf->interpolate_env == 1) && (ent->flags & PROXYPASS_INTERPOLATE)) {
fake = proxy_interpolate(r, ent->fake);
@@ -933,8 +938,9 @@ PROXY_DECLARE(int) ap_proxy_trans_match(request_rec *r, struct proxy_alias *ent,
}
else {
if ((ent->flags & PROXYPASS_MAP_SERVLET) == PROXYPASS_MAP_SERVLET) {
+ servlet_uri = r->uri;
+ len = alias_match_servlet(r->pool, &servlet_uri, fake);
nocanon = 0; /* ignored since servlet's normalization applies */
- len = alias_match_servlet(r->pool, r->uri, fake);
}
else {
len = alias_match(r->uri, fake);
@@ -969,7 +975,7 @@ PROXY_DECLARE(int) ap_proxy_trans_match(request_rec *r, struct proxy_alias *ent,
*/
int rc = proxy_run_check_trans(r, found + 6);
if (rc != OK && rc != DECLINED) {
- return DONE;
+ return HTTP_CONTINUE;
}
r->filename = found;
@@ -983,14 +989,28 @@ PROXY_DECLARE(int) ap_proxy_trans_match(request_rec *r, struct proxy_alias *ent,
apr_table_setn(r->notes, "proxy-noquery", "1");
}
+ if (servlet_uri) {
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO()
+ "Servlet path '%s' (%s) matches proxy handler '%s'",
+ r->uri, servlet_uri, found);
+ /* Apply servlet normalization to r->uri so that <Location> or any
+ * directory context match does not have to handle path parameters.
+ * We change r->uri in-place so that r->parsed_uri.path is updated
+ * too. Since normalized servlet_uri is necessarily shorter than
+ * the original r->uri, strcpy() is fine.
+ */
+ AP_DEBUG_ASSERT(strlen(r->uri) >= strlen(servlet_uri));
+ strcpy(r->uri, servlet_uri);
+ return DONE;
+ }
+
ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(03464)
"URI path '%s' matches proxy handler '%s'", r->uri,
found);
-
return OK;
}
- return DONE;
+ return HTTP_CONTINUE;
}
static int proxy_trans(request_rec *r, int pre_trans)
@@ -1042,7 +1062,7 @@ static int proxy_trans(request_rec *r, int pre_trans)
enc = (dconf->alias->flags & PROXYPASS_MAP_ENCODED) != 0;
if (!(pre_trans ^ enc)) {
int rv = ap_proxy_trans_match(r, dconf->alias, dconf);
- if (DONE != rv) {
+ if (rv != HTTP_CONTINUE) {
return rv;
}
}
@@ -1054,7 +1074,7 @@ static int proxy_trans(request_rec *r, int pre_trans)
enc = (ent->flags & PROXYPASS_MAP_ENCODED) != 0;
if (!(pre_trans ^ enc)) {
int rv = ap_proxy_trans_match(r, ent, dconf);
- if (DONE != rv) {
+ if (rv != HTTP_CONTINUE) {
return rv;
}
}
diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h
index e774fe3a02..58d6cc54d7 100644
--- a/modules/proxy/mod_proxy.h
+++ b/modules/proxy/mod_proxy.h
@@ -1185,7 +1185,11 @@ PROXY_DECLARE(apr_status_t) ap_proxy_sync_balancer(proxy_balancer *b,
* @param r request
* @param ent proxy_alias record
* @param dconf per-dir config or NULL
- * @return DECLINED, DONE or OK if matched
+ * @return OK if the alias matched,
+ * DONE if the alias matched and r->uri was normalized so
+ * no further transformation should happen on it,
+ * DECLINED if proxying is disabled for this alias,
+ * HTTP_CONTINUE if the alias did not match
*/
PROXY_DECLARE(int) ap_proxy_trans_match(request_rec *r,
struct proxy_alias *ent,