You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Thomas Eckert <th...@gmail.com> on 2014/01/22 16:36:34 UTC

mod_alias' Redirect with dynamic host

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

Re: mod_alias' Redirect with dynamic host

Posted by Marian Marinov <mm...@yuhu.biz>.
On 01/22/2014 05:42 PM, Graham Leggett wrote:
> On 22 Jan 2014, at 5:36 PM, Thomas Eckert <thomas.r.w.eckert@gmail.com <ma...@gmail.com>> wrote:
>
>> 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
>
> This looks like a job for the expression parser, ie this:
>
> Redirect permanent / https://%{HOST}/
>
> (Syntax off top of head, probably wrong).
>
> Having done expression parser for the require directive, my next one on the wishlist was DocumentRoot (to replace the
> mass virtual hosting module) followed by mod_alias.

I would really like solution like that in mod_alias.

Graham, would you share with us where(in which files/lines) is the expression parser for the require directive so we can 
adjust the code which Thomas sent and have that contributed to the core :)

> Regards,
> Graham
> --
>


Re: mod_alias' Redirect with dynamic host

Posted by Thomas Eckert <th...@gmail.com>.
I remember a discussion about general support for this kind of expression
parsing after I asked for it via IRC/list but cannot remember what became
of it. It would definitely be neat to have that kind of thing in there -
much less copy-n-paste like config sections ! Glad to hear there's progress
on this front. Thanks !


On Wed, Jan 22, 2014 at 4:42 PM, Graham Leggett <mi...@sharp.fm> wrote:

> On 22 Jan 2014, at 5:36 PM, Thomas Eckert <th...@gmail.com>
> wrote:
>
> 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
>
>
> This looks like a job for the expression parser, ie this:
>
> Redirect permanent / https://%{HOST}/
>
> (Syntax off top of head, probably wrong).
>
> Having done expression parser for the require directive, my next one on
> the wishlist was DocumentRoot (to replace the mass virtual hosting module)
> followed by mod_alias.
>
> Regards,
> Graham
> --
>
>

Re: mod_alias' Redirect with dynamic host

Posted by Graham Leggett <mi...@sharp.fm>.
On 22 Jan 2014, at 5:36 PM, Thomas Eckert <th...@gmail.com> wrote:

> 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

This looks like a job for the expression parser, ie this:

Redirect permanent / https://%{HOST}/

(Syntax off top of head, probably wrong).

Having done expression parser for the require directive, my next one on the wishlist was DocumentRoot (to replace the mass virtual hosting module) followed by mod_alias.

Regards,
Graham
--