From: Eric Covener
Date: Sat, 24 Oct 2015 19:13:16 +0000 (+0000)
Subject: Make the fix for fully qualifying REDIRECT_URL from PR#57785 opt-in.
X-Git-Tag: 2.5.0-alpha~2697
X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=28d2d122419e5e03577f3aabf3b9cc83af8273c3;p=thirdparty%2Fapache%2Fhttpd.git
Make the fix for fully qualifying REDIRECT_URL from PR#57785 opt-in.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1710380 13f79535-47bb-0310-9956-ffa450edef68
---
diff --git a/docs/manual/mod/core.xml b/docs/manual/mod/core.xml
index 0cf0f74546d..ba96885c32b 100644
--- a/docs/manual/mod/core.xml
+++ b/docs/manual/mod/core.xml
@@ -4803,5 +4803,32 @@ for external processing, e.g. to a CGI script.
+
+QualifyRedirectURL
+Controls whether the REDIRECT_URL environent variable is
+ fully qualified
+QualifyRedirectURL ON|OFF
+QualifyRedirectURL OFF
+server configvirtual host
+directory
+
+FileInfo
+Directive supported in 2.4.18 and later. 2.4.17 acted
+as if 'QualifyRedirectURL ON' was configured.
+
+
+ This directive controls whether the server will ensure that the
+ REDIRECT_URL environment variable is fully qualified. By default,
+ the variable contains the verbatim URL requested by the client,
+ such as "/index.html". With QualifyRedirectURL ON, the same request would result in a
+ value such as "http://www.example.com/index.html".
+ Even without this directive set, when a request is issued against a
+ fully qualified URL, REDIRECT_URL will remain fully qualified.
+
+
+
+
+
diff --git a/include/http_core.h b/include/http_core.h
index cbd4b81d103..92bf161ce2b 100644
--- a/include/http_core.h
+++ b/include/http_core.h
@@ -465,6 +465,17 @@ typedef unsigned long etag_components_t;
/* This is the default value used */
#define ETAG_BACKWARD (ETAG_MTIME | ETAG_SIZE)
+/* Generic ON/OFF/UNSET for unsigned int foo :2 */
+#define AP_CORE_CONFIG_OFF (0)
+#define AP_CORE_CONFIG_ON (1)
+#define AP_CORE_CONFIG_UNSET (2)
+
+/* Generic merge of flag */
+#define AP_CORE_MERGE_FLAG(field, to, base, over) to->field = \
+ over->field != AP_CORE_CONFIG_UNSET \
+ ? over->field \
+ : base->field
+
/**
* @brief Server Signature Enumeration
*/
@@ -634,6 +645,8 @@ typedef struct {
*/
apr_hash_t *response_code_exprs;
+ unsigned int qualify_redirect_url :2;
+
} core_dir_config;
/* macro to implement off by default behaviour */
diff --git a/server/core.c b/server/core.c
index 5b8f230a99c..e1bef97bafa 100644
--- a/server/core.c
+++ b/server/core.c
@@ -198,6 +198,7 @@ static void *create_core_dir_config(apr_pool_t *a, char *dir)
conf->max_reversals = AP_MAXRANGES_UNSET;
conf->cgi_pass_auth = AP_CGI_PASS_AUTH_UNSET;
+ conf->qualify_redirect_url = AP_CORE_CONFIG_UNSET;
return (void *)conf;
}
@@ -416,6 +417,8 @@ static void *merge_core_dir_configs(apr_pool_t *a, void *basev, void *newv)
conf->cgi_pass_auth = new->cgi_pass_auth != AP_CGI_PASS_AUTH_UNSET ? new->cgi_pass_auth : base->cgi_pass_auth;
+ AP_CORE_MERGE_FLAG(qualify_redirect_url, conf, base, new);
+
return (void*)conf;
}
@@ -1776,6 +1779,15 @@ static const char *set_cgi_pass_auth(cmd_parms *cmd, void *d_, int flag)
return NULL;
}
+static const char *set_qualify_redirect_url(cmd_parms *cmd, void *d_, int flag)
+{
+ core_dir_config *d = d_;
+
+ d->qualify_redirect_url = flag ? AP_CORE_CONFIG_ON : AP_CORE_CONFIG_OFF;
+
+ return NULL;
+}
+
static const char *set_override_list(cmd_parms *cmd, void *d_, int argc, char *const argv[])
{
core_dir_config *d = d_;
@@ -4471,6 +4483,10 @@ AP_INIT_TAKE12("LimitInternalRecursion", set_recursion_limit, NULL, RSRC_CONF,
AP_INIT_FLAG("CGIPassAuth", set_cgi_pass_auth, NULL, OR_AUTHCFG,
"Controls whether HTTP authorization headers, normally hidden, will "
"be passed to scripts"),
+AP_INIT_FLAG("QualifyRedirectURL", set_qualify_redirect_url, NULL, OR_FILEINFO,
+ "Controls whether HTTP authorization headers, normally hidden, will "
+ "be passed to scripts"),
+
AP_INIT_TAKE1("ForceType", ap_set_string_slot_lower,
(void *)APR_OFFSETOF(core_dir_config, mime_type), OR_FILEINFO,
"a mime type that overrides other configured type"),
diff --git a/server/util_script.c b/server/util_script.c
index 4ec4bb58c0b..de9e91dd2b1 100644
--- a/server/util_script.c
+++ b/server/util_script.c
@@ -286,21 +286,26 @@ AP_DECLARE(void) ap_add_common_vars(request_rec *r)
/* Apache custom error responses. If we have redirected set two new vars */
if (r->prev) {
- /* PR#57785: reconstruct full URL here */
- apr_uri_t *uri = &r->prev->parsed_uri;
- if (!uri->scheme) {
- uri->scheme = (char*)ap_http_scheme(r->prev);
- }
- if (!uri->port) {
- uri->port = ap_get_server_port(r->prev);
- uri->port_str = apr_psprintf(r->pool, "%u", uri->port);
- }
- if (!uri->hostname) {
- uri->hostname = (char*)ap_get_server_name_for_url(r->prev);
+ if (conf->fully_qualify_redirect_url != AP_CORE_CONFIG_ON) {
+ add_unless_null(e, "REDIRECT_URL", r->prev->uri);
+ }
+ else {
+ /* PR#57785: reconstruct full URL here */
+ apr_uri_t *uri = &r->prev->parsed_uri;
+ if (!uri->scheme) {
+ uri->scheme = (char*)ap_http_scheme(r->prev);
+ }
+ if (!uri->port) {
+ uri->port = ap_get_server_port(r->prev);
+ uri->port_str = apr_psprintf(r->pool, "%u", uri->port);
+ }
+ if (!uri->hostname) {
+ uri->hostname = (char*)ap_get_server_name_for_url(r->prev);
+ }
+ add_unless_null(e, "REDIRECT_URL",
+ apr_uri_unparse(r->pool, uri, 0));
}
add_unless_null(e, "REDIRECT_QUERY_STRING", r->prev->args);
- add_unless_null(e, "REDIRECT_URL",
- apr_uri_unparse(r->pool, uri, 0));
}
if (e != r->subprocess_env) {