Return-Path: X-Original-To: apmail-httpd-dev-archive@www.apache.org Delivered-To: apmail-httpd-dev-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 010BC10E20 for ; Wed, 22 Jan 2014 15:37:08 +0000 (UTC) Received: (qmail 81884 invoked by uid 500); 22 Jan 2014 15:37:05 -0000 Delivered-To: apmail-httpd-dev-archive@httpd.apache.org Received: (qmail 81819 invoked by uid 500); 22 Jan 2014 15:37:03 -0000 Mailing-List: contact dev-help@httpd.apache.org; run by ezmlm Precedence: bulk Reply-To: dev@httpd.apache.org list-help: list-unsubscribe: List-Post: List-Id: Delivered-To: mailing list dev@httpd.apache.org Received: (qmail 81809 invoked by uid 99); 22 Jan 2014 15:37:02 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 22 Jan 2014 15:37:02 +0000 X-ASF-Spam-Status: No, hits=1.5 required=5.0 tests=HTML_MESSAGE,RCVD_IN_DNSWL_LOW,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (nike.apache.org: domain of thomas.r.w.eckert@gmail.com designates 209.85.216.177 as permitted sender) Received: from [209.85.216.177] (HELO mail-qc0-f177.google.com) (209.85.216.177) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 22 Jan 2014 15:36:55 +0000 Received: by mail-qc0-f177.google.com with SMTP id i8so666547qcq.22 for ; Wed, 22 Jan 2014 07:36:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to:content-type; bh=HaYb9vCFkQudn3S5y4ysdTaUZKVmce1uu+uWG22KgOY=; b=s/GVw8CE92lbjFo3L9h8BMa0+8m4XH8U9jb94pLSBlQzINaTWv0Tl9RpEytb+JYof8 XHwe12t5O2y701krUUqsu4J3B8T5YJCLYofW2FjsvOESImGdApov8O2VbXn2CoXtZs2y vBnVLP/YW6y/RH5utuAwtI5Y5WfwgUX5UQeJAXyEcL3Ur8RMCVOE9NtOPr0sETbghXfr 7GDbLRjBT7vWvQvCT2HjCM+YO1oO6SLlrRIHx4bgrrNxxDan5LfeDMFSfVbaHnb16gSr d1Rd3AFsnOhx+HcVbdS3ElIQiT0x3UXSXk/pMpBaiuX+SVhRe6Iae3xvyq2Otvawubns iY/w== MIME-Version: 1.0 X-Received: by 10.224.74.74 with SMTP id t10mr3454704qaj.82.1390404994790; Wed, 22 Jan 2014 07:36:34 -0800 (PST) Received: by 10.96.133.166 with HTTP; Wed, 22 Jan 2014 07:36:34 -0800 (PST) Date: Wed, 22 Jan 2014 16:36:34 +0100 Message-ID: Subject: mod_alias' Redirect with dynamic host From: Thomas Eckert To: dev@httpd.apache.org Content-Type: multipart/alternative; boundary=001a11c3ec6acefa9204f090e37c X-Virus-Checked: Checked by ClamAV on apache.org --001a11c3ec6acefa9204f090e37c Content-Type: text/plain; charset=ISO-8859-1 Some time ago I put up HTTP to HTTPS redirects in place which now needed an update so they would not only work for constant host names but use the 'Host' header information as target host. So a simple Redirect permanent / https://example.org/ wasn't enough. I wanted to avoid using mod_rewrite (not included in my configs so far anyway) and stick with the much simpler mod_alias so I read through mod_alias.c. From what I could see there wasn't any means to do get this working so I came up with diff --git a/modules/mappers/mod_alias.c b/modules/mappers/mod_alias.c index 0740cef..b73d262 100644 --- a/modules/mappers/mod_alias.c +++ b/modules/mappers/mod_alias.c @@ -42,6 +42,7 @@ typedef struct { char *handler; ap_regex_t *regexp; int redir_status; /* 301, 302, 303, 410, etc */ + int ssl_redir; } alias_entry; typedef struct { @@ -169,7 +170,8 @@ static const char *add_alias_regex(cmd_parms *cmd, void *dummy, static const char *add_redirect_internal(cmd_parms *cmd, alias_dir_conf *dirconf, const char *arg1, const char *arg2, - const char *arg3, int use_regex) + const char *arg3, int use_regex, + int ssl_redir) { alias_entry *new; server_rec *s = cmd->server; @@ -222,13 +224,17 @@ static const char *add_redirect_internal(cmd_parms *cmd, } if (ap_is_HTTP_REDIRECT(status)) { - if (!url) - return "URL to redirect to is missing"; - /* PR#35314: we can allow path components here; - * they get correctly resolved to full URLs. - */ - if (!use_regex && !ap_is_url(url) && (url[0] != '/')) - return "Redirect to non-URL"; + if (ssl_redir) { + url = apr_pstrdup(cmd->pool, "debugging place holder"); + } else { + if (!url) + return "URL to redirect to is missing"; + /* PR#35314: we can allow path components here; + * they get correctly resolved to full URLs. + */ + if (!use_regex && !ap_is_url(url) && (url[0] != '/')) + return "Redirect to non-URL"; + } } else { if (url) @@ -244,6 +250,7 @@ static const char *add_redirect_internal(cmd_parms *cmd, new->real = url; new->regexp = regex; new->redir_status = status; + new->ssl_redir = ssl_redir; return NULL; } @@ -251,20 +258,27 @@ static const char *add_redirect(cmd_parms *cmd, void *dirconf, const char *arg1, const char *arg2, const char *arg3) { - return add_redirect_internal(cmd, dirconf, arg1, arg2, arg3, 0); + return add_redirect_internal(cmd, dirconf, arg1, arg2, arg3, 0, 0); +} + +static const char *add_redirect_ssl(cmd_parms *cmd, void *dirconf, + const char *arg1, const char *arg2) +{ + return add_redirect_internal(cmd, dirconf, arg1, arg2, NULL, 0, 1); } + static const char *add_redirect2(cmd_parms *cmd, void *dirconf, const char *arg1, const char *arg2) { - return add_redirect_internal(cmd, dirconf, arg1, arg2, NULL, 0); + return add_redirect_internal(cmd, dirconf, arg1, arg2, NULL, 0, 0); } static const char *add_redirect_regex(cmd_parms *cmd, void *dirconf, const char *arg1, const char *arg2, const char *arg3) { - return add_redirect_internal(cmd, dirconf, arg1, arg2, arg3, 1); + return add_redirect_internal(cmd, dirconf, arg1, arg2, arg3, 1, 0); } static const command_rec alias_cmds[] = @@ -277,6 +291,8 @@ static const command_rec alias_cmds[] = OR_FILEINFO, "an optional status, then document to be redirected and " "destination URL"), + AP_INIT_TAKE2("RedirectSSL", add_redirect_ssl, NULL, OR_FILEINFO, + "Add Host Header based redirect using HTTPS"), AP_INIT_TAKE2("AliasMatch", add_alias_regex, NULL, RSRC_CONF, "a regular expression and a filename"), AP_INIT_TAKE2("ScriptAliasMatch", add_alias_regex, "cgi-script", RSRC_CONF, @@ -403,11 +419,14 @@ static char *try_alias_list(request_rec *r, apr_array_header_t *aliases, if (is_redir) { char *escurl; escurl = ap_os_escape_path(r->pool, r->uri + l, 1); - - found = apr_pstrcat(r->pool, alias->real, escurl, NULL); - } - else + if (alias->ssl_redir) { + found = apr_pstrcat(r->pool, "https://", apr_table_get(r->headers_in, "Host"), alias->fake, escurl, NULL); + } else { + found = apr_pstrcat(r->pool, alias->real, escurl, NULL); + } + } else { found = apr_pstrcat(r->pool, alias->real, r->uri + l, NULL); + } } } which is fairly simple and straight forward. I figured this might be useful for others, seeing how common HTTP to HTTPS redirects are and how easy a setup like RedirectSSL permanent / is. My guess is there are many setups which would benefit from this. Cheers --001a11c3ec6acefa9204f090e37c Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable
Some time ago I put up HTTP to HTTPS redire= cts in place which now needed an update so they would not only work for con= stant host names but use the 'Host' header information as target ho= st.
So a simple
=A0 Redirect permanent / ht= tps://example.org/
wasn't enough. I wanted to avoid using mod_re= write (not included in my configs so far anyway) and stick with the much si= mpler mod_alias so I read through mod_alias.c. From what I could see there = wasn't any means to do get this working so I came up with

diff --git a/modules/mappers/mod_alias.c b/modules/mappers/mod_alias.c<= br>index 0740cef..b73d262 100644
--- a/modules/mappers/mod_alias.c
++= + b/modules/mappers/mod_alias.c
@@ -42,6 +42,7 @@ typedef struct {
=A0=A0=A0=A0 char *handler;
=A0=A0=A0=A0 ap_regex_t *regexp;
=A0=A0= =A0=A0 int redir_status;=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* 30= 1, 302, 303, 410, etc */
+=A0=A0=A0 int ssl_redir;
=A0} alias_entry;<= br>=A0
=A0typedef struct {
@@ -169,7 +170,8 @@ static const char *add= _alias_regex(cmd_parms *cmd, void *dummy,
=A0static const char *add_redirect_internal(cmd_parms *cmd,
=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 alias_dir_conf *dirconf,
=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 const char *arg1, const char *arg2,=
-=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 const char *arg3, int u= se_regex)
+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 const char *arg3, int use_= regex,
+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 int ssl_redir)=A0{
=A0=A0=A0=A0 alias_entry *new;
=A0=A0=A0=A0 server_rec *s =3D c= md->server;
@@ -222,13 +224,17 @@ static const char *add_redirect_int= ernal(cmd_parms *cmd,
=A0=A0=A0=A0 }
=A0
=A0=A0=A0=A0 if (ap_is_HTTP_REDIRECT(status)) {-=A0=A0=A0=A0=A0=A0=A0 if (!url)
-=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 ret= urn "URL to redirect to is missing";
-=A0=A0=A0=A0=A0=A0=A0 /*= PR#35314: we can allow path components here;
-=A0=A0=A0=A0=A0=A0=A0=A0 = * they get correctly resolved to full URLs.
-=A0=A0=A0=A0=A0=A0=A0=A0 */
-=A0=A0=A0=A0=A0=A0=A0 if (!use_regex &= & !ap_is_url(url) && (url[0] !=3D '/'))
-=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0 return "Redirect to non-URL";
+=A0=A0= =A0=A0=A0=A0=A0 if (ssl_redir) {
+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 url = =3D apr_pstrdup(cmd->pool, "debugging place holder");
+=A0=A0=A0=A0=A0=A0=A0 } else {
+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 if (!= url)
+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 return "URL to = redirect to is missing";
+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* PR#3= 5314: we can allow path components here;
+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0 * they get correctly resolved to full URLs.
+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 */
+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0 if (!use_regex && !ap_is_url(url) && (url[0] !=3D '= /'))
+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 return "Red= irect to non-URL";
+=A0=A0=A0=A0=A0=A0=A0 }
=A0=A0=A0=A0 }
= =A0=A0=A0=A0 else {
=A0=A0=A0=A0=A0=A0=A0=A0 if (url)
@@ -244,6 +250,7 @@ static const char *add_redirect_internal(cmd_parms *cmd= ,
=A0=A0=A0=A0 new->real =3D url;
=A0=A0=A0=A0 new->regexp =3D = regex;
=A0=A0=A0=A0 new->redir_status =3D status;
+=A0=A0=A0 new-&= gt;ssl_redir =3D ssl_redir;
=A0=A0=A0=A0 return NULL;
=A0}
=A0
@@ -251,20 +258,27 @@ static const char *add_redirect(cmd_pa= rms *cmd, void *dirconf,
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 const char *arg1, const= char *arg2,
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 const char *arg3)
=A0{
-=A0=A0=A0 return add_redirect_internal(cmd, dirconf, arg1, arg2, a= rg3, 0);
+=A0=A0=A0 return add_redirect_internal(cmd, dirconf, arg1, arg= 2, arg3, 0, 0);
+}
+
+static const char *add_redirect_ssl(cmd_parm= s *cmd, void *dirconf,
+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 const char *arg1, const char *arg2)
+{=
+=A0=A0=A0 return add_redirect_internal(cmd, dirconf, arg1, arg2, NULL,= 0, 1);
=A0}
=A0
+
=A0static const char *add_redirect2(cmd_parm= s *cmd, void *dirconf,
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0 const char *arg1, const char *arg2)
=A0{
-= =A0=A0=A0 return add_redirect_internal(cmd, dirconf, arg1, arg2, NULL, 0);<= br>+=A0=A0=A0 return add_redirect_internal(cmd, dirconf, arg1, arg2, NULL, = 0, 0);
=A0}
=A0
=A0static const char *add_redirect_regex(cmd_parms *cmd, voi= d *dirconf,
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 const char *arg1, co= nst char *arg2,
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 const char *ar= g3)
=A0{
-=A0=A0=A0 return add_redirect_internal(cmd, dirconf, arg1, arg2, a= rg3, 1);
+=A0=A0=A0 return add_redirect_internal(cmd, dirconf, arg1, arg= 2, arg3, 1, 0);
=A0}
=A0
=A0static const command_rec alias_cmds[] = =3D
@@ -277,6 +291,8 @@ static const command_rec alias_cmds[] =3D
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 OR_FILEINFO,
= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 "an optional= status, then document to be redirected and "
=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 "destination URL"),
+=A0= =A0=A0 AP_INIT_TAKE2("RedirectSSL", add_redirect_ssl, NULL, OR_FI= LEINFO,
+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 "Add Host Header = based redirect using HTTPS"),
=A0=A0=A0=A0 AP_INIT_TAKE2("Alia= sMatch", add_alias_regex, NULL, RSRC_CONF,
=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 "a regular expression and a filename&qu= ot;),
=A0=A0=A0=A0 AP_INIT_TAKE2("ScriptAliasMatch", add_alias_regex, &= quot;cgi-script", RSRC_CONF,
@@ -403,11 +419,14 @@ static char *try= _alias_list(request_rec *r, apr_array_header_t *aliases,
=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 if (is_redir) {
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 char *escurl;<= br>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 escurl =3D = ap_os_escape_path(r->pool, r->uri + l, 1);
-
-=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 found =3D apr_pstrcat(r->pool= , alias->real, escurl, NULL);
-=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0 }
-=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 else
+=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 if (alias->ssl_redir) {
+=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 found = =3D apr_pstrcat(r->pool, "https://", apr_table_get(r->heade= rs_in, "Host"), alias->fake, escurl, NULL);
+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 } else {
+=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 found = =3D apr_pstrcat(r->pool, alias->real, escurl, NULL);
+=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 }
+=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0 } else {
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0 found =3D apr_pstrcat(r->pool, alias->real, = r->uri + l, NULL);
+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 }
=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0 }
=A0=A0=A0=A0=A0=A0=A0=A0 }
=A0

wh= ich is fairly simple and straight forward. I figured this might be useful f= or others, seeing how common HTTP to HTTPS redirects are and how easy a set= up like
=A0 RedirectSSL permanent /
is. My guess is there = are many setups which would benefit from this.

Cheers
=
--001a11c3ec6acefa9204f090e37c--