summaryrefslogtreecommitdiff
path: root/modules/proxy/proxy_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/proxy/proxy_util.c')
-rw-r--r--modules/proxy/proxy_util.c39
1 files changed, 34 insertions, 5 deletions
diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c
index 992dba8fae..caafde0b76 100644
--- a/modules/proxy/proxy_util.c
+++ b/modules/proxy/proxy_util.c
@@ -200,14 +200,16 @@ PROXY_DECLARE(void) ap_proxy_c2hex(int ch, char *x)
* and encodes those which must be encoded, and does not touch
* those which must not be touched.
*/
-PROXY_DECLARE(char *)ap_proxy_canonenc(apr_pool_t *p, const char *x, int len,
- enum enctype t, int forcedec,
- int proxyreq)
+PROXY_DECLARE(char *)ap_proxy_canonenc_ex(apr_pool_t *p, const char *x, int len,
+ enum enctype t, int flags,
+ int proxyreq)
{
int i, j, ch;
char *y;
char *allowed; /* characters which should not be encoded */
char *reserved; /* characters which much not be en/de-coded */
+ int forcedec = flags & PROXY_CANONENC_FORCEDEC;
+ int noencslashesenc = flags & PROXY_CANONENC_NOENCODEDSLASHENCODING;
/*
* N.B. in addition to :@&=, this allows ';' in an http path
@@ -256,7 +258,8 @@ PROXY_DECLARE(char *)ap_proxy_canonenc(apr_pool_t *p, const char *x, int len,
* decode it if not already done. do not decode reverse proxied URLs
* unless specifically forced
*/
- if ((forcedec || (proxyreq && proxyreq != PROXYREQ_REVERSE)) && ch == '%') {
+ if ((forcedec || noencslashesenc
+ || (proxyreq && proxyreq != PROXYREQ_REVERSE)) && ch == '%') {
if (!apr_isxdigit(x[i + 1]) || !apr_isxdigit(x[i + 2])) {
return NULL;
}
@@ -267,7 +270,17 @@ PROXY_DECLARE(char *)ap_proxy_canonenc(apr_pool_t *p, const char *x, int len,
y[j] = x[i];
continue;
}
- i += 2;
+ if (noencslashesenc && !forcedec && (proxyreq == PROXYREQ_REVERSE)) {
+ /*
+ * In the reverse proxy case when we only want to keep encoded
+ * slashes untouched revert back to '%' which will cause
+ * '%' to be encoded in the following.
+ */
+ ch = '%';
+ }
+ else {
+ i += 2;
+ }
}
/* recode it, if necessary */
if (!apr_isalnum(ch) && !strchr(allowed, ch)) {
@@ -283,6 +296,22 @@ PROXY_DECLARE(char *)ap_proxy_canonenc(apr_pool_t *p, const char *x, int len,
}
/*
+ * Convert a URL-encoded string to canonical form.
+ * It decodes characters which need not be encoded,
+ * and encodes those which must be encoded, and does not touch
+ * those which must not be touched.
+ */
+PROXY_DECLARE(char *)ap_proxy_canonenc(apr_pool_t *p, const char *x, int len,
+ enum enctype t, int forcedec,
+ int proxyreq)
+{
+ int flags;
+
+ flags = forcedec ? PROXY_CANONENC_FORCEDEC : 0;
+ return ap_proxy_canonenc_ex(p, x, len, t, flags, proxyreq);
+}
+
+/*
* Parses network-location.
* urlp on input the URL; on output the path, after the leading /
* user NULL if no user/password permitted