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

Reply via email to