1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
From 815cf05bb2d506f44a35b65e93de393d5410c779 Mon Sep 17 00:00:00 2001
From: Yann Ylavic <ylavic@apache.org>
Date: Tue, 1 Mar 2022 13:26:03 +0000
Subject: [PATCH] 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
---
changes-entries/rewrite_vs_proxy_mapping.txt | 2 ++
modules/mappers/mod_rewrite.c | 38 +++++++++++++++-----
2 files changed, 32 insertions(+), 8 deletions(-)
create mode 100644 changes-entries/rewrite_vs_proxy_mapping.txt
Index: apache2/changes-entries/rewrite_vs_proxy_mapping.txt
===================================================================
--- /dev/null
+++ apache2/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
Index: apache2/modules/mappers/mod_rewrite.c
===================================================================
--- apache2.orig/modules/mappers/mod_rewrite.c
+++ apache2/modules/mappers/mod_rewrite.c
@@ -4575,6 +4575,7 @@ static int hook_uri2file(request_rec *r)
unsigned int port;
int rulestatus;
void *skipdata;
+ char *ofilename;
const char *oargs;
/*
@@ -4628,7 +4629,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;
/*
@@ -4671,13 +4675,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 "
@@ -4701,6 +4707,7 @@ static int hook_uri2file(request_rec *r)
if (rulestatus) {
unsigned skip;
apr_size_t flen;
+ int to_proxyreq;
if (r->args && *(ap_scan_vchar_obstext(r->args))) {
/*
@@ -4721,7 +4728,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
@@ -4888,7 +4907,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;
}
}
@@ -5234,7 +5255,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;
}
|