1

I have a bit of a unique situation: I need to take a subdomain and make it redirect to a random selection of alternate domains, each of which is on a separate server. Think load balancing, except it's technically different from that.

Upon investigating my options, Apache's RewriteMap seemed like the ideal solution, except I can't seem to get it to do anything at all. Here's what I've got so far:

In my configuration file, I've added:

RewriteMap map "rnd:/home/mydomain/public_html/servers.txt"

This is in the server context, not VirtualHost or Directory. However, I do have "AllowOverride All" set for the public_html directory. And yes, I did remember to restart Apache after saving changes to my config.

Next, the servers.txt file itself:

servers domain1.com|domain2.com|domain3.com

(It doesn't really matter if these domains are exposed to the user, hence I'm just putting this in public_html for now, but I may move it elsewhere if I can get it working.)

Finally, I have an .htaccess file in public_html which already has several working Rewrite conditions and rules. RewriteEngine is on and all that. But when I add...

RewriteCond %{HTTP_HOST} ^subdomain.domain.com$
RewriteRule ^(.*)$ "https://${map:servers}/$1" [P,L]

... visiting my subdomain just shows the subdomain itself. I've tried a variety of different flags, but to no avail. At best, if I replace the [P] flag with [R=301] I can get a ERR_INVALID_REDIRECT response from the browser, which tells me the rule is at least being processed. Other than that, I don't even get any errors in Apache's error_log file. I've also made sure no other rules have the [L] flag, which might cause the new rule to be skipped.

As far as I can tell, according to the Apache documentation this is exactly the way RewriteMap is supposed to be used, so I'm a little perplexed to say the least. Can anyone tell me what I'm missing here?

LukeLC
  • 11
  • 2

1 Answers1

0

I've also made sure no other rules have the [L] flag

That raises alarm bells. It perhaps implies you've put these directives in the wrong place in your .htaccess file. Your "redirect" should go near the top of your .htaccess file. (I would expect most RewriteRule directives to require the L flag and at the very least for optimisation.)

mod_rewrite directives naturally chain together - in that the output of the previous is the input of the next and so on. If you've removed the L flags from preceding directives and placed your redirect later in the file then your $1 backreference is not capturing the requested URL, but the rewritten URL from any preceding directives.

You should be able to see the URL that triggers the ERR_INVALID_REDIRECT in the browser by monitoring the network traffic (in the browser tools).

if I replace the [P] flag with [R=301]

The P flag sends the request through mod_proxy (as a reverse proxy - which requires additional config). If you want to externally redirect the request then you should use the R flag.

MrWhite
  • 11,643
  • 4
  • 25
  • 40
  • Your explanation of the [L] flag makes sense--apparently I was slightly misunderstanding its function based on the Apache documentation. However, even adding other [L] flags to end rules and moving the RewriteMap rule to the top of `.htaccess` produces the same results. Also, the [R] flag seems like the right way to go here since the alt domains are external, but it silently errors no matter what I do. Nothing comes up in network tools at all. – LukeLC Jan 08 '19 at 21:51
  • If you are seeing a ERR_INVALID_REDIRECT _browser_ error then you should be able to examine the initial HTTP (redirect) response from your server containing the `Location:` header. – MrWhite Jan 08 '19 at 23:18
  • I'm not able to find one either in my browser tools or server logs, but I believe I discovered what's going on, regardless: the domain is just being skipped, leading the browser to attempt to access the subdirectory as the domain. So instead of https://example.com/sub/file.txt it ends up as https://sub/file.txt which obviously isn't going anywhere. So, the RewriteMap is returning an empty string. *Why* remains a mystery without any errors to examine... – LukeLC Jan 08 '19 at 23:39