Forum Moderators: phranque

Message Too Old, No Replies

Multiple Redirects from Subdomain and Variable

Multiple Redirects from Subdomain and Variable

         

GordonB

1:50 am on Apr 21, 2009 (gmt 0)

10+ Year Member



I am trying to create a redirect based on two parameters, the subdomain name and a variable, I have gone through the site, and have not been able to work out the answer!

The base form is

subdomain.example.com/variable

either subdomain or variable may or may not be present

I am trying to get the following syntax

http://example.com/index.php?&s=subdomain&v=variable

(or it could be
http://example.com/index.php?&v=variable&s=subdomain )

both
http://example.com/index.php?&s=subdomain&v=
and
http://example.com/index.php?&s=&v=variable
would be valid answers.

The default for my domain is

example.com, and www.example.com maps to example.com

I also have a number of active subdirectories

I can get one or the other to work, I am struggling with the syntax to get both working:

Subdomain:

Options +FollowSymLinks
rewriteEngine on
rewriteCond %{HTTP_HOST} !^www\.
rewriteCond %{HTTP_HOST} ^([^.]+)\.example\.com
RewriteCond %{HTTP_HOST} !^$
rewriteRule .* http://example.com.com/index.php?&s=%1

works fine
and

Variable

Options +FollowSymLinks
rewriteEngine on
rewriteCond %{REQUEST_URI} !^/index\.php$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^.]+)$ http://example.com.com/index.php?&v=$1

works fine

How do I combine these two rules to build on each other?

Thx, Gordon

jdMorgan

2:49 am on Apr 21, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Because the conditions are so different, and in some cases mutually-exclusive, it's difficult. One way to do it is to "divide and conquer." First, figure out what needs to be done and get all the "pieces" that are needed, and then do it.

Options +FollowSymLinks
RewriteEngine on
#
RewriteCond %{HTTP_HOST} !^www\.
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.com
RewriteRule ^.*$ - [E=setSub:%1]
#
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^.]+)$ - [E=setVar:$1]
#
# Rewrite with both subdomain and variable
RewriteCond %{ENV:setSub}>%{ENV:setVar} ^(.+)>(.+)$
RewriteRule ^.*$ http://example.com.com/index.php?s=%1&v=%2 [L]
# Rewrite with subdomain only
RewriteCond %{ENV:setSub} ^(.+)$
RewriteRule ^.*$ http://example.com.com/index.php?s=%1 [L]
# Rewrite with variable only
RewriteCond %{ENV:setVar} ^(.+)$
RewriteRule ^.*$ http://example.com.com/index.php?v=%2 [L]

If it is acceptable to have blank values in the query string (for example, "s=&v=foo" or "s=bar&v="), you can eliminate the last three rules, and replace all three with:

# Rewrite with either subdomain or variable or both
RewriteCond %{ENV:setSub}%{ENV:setVar} ^.
RewriteCond %{ENV:setSub}>%{ENV:setVar} ^(.*)>(.*)$
RewriteRule ^.*$ http://example.com.com/index.php?s=%1&v=%2 [L]

Note that I intentionally deleted the third RewriteCond from your original first rule. It wasn't needed, since a blank hostname would never have matched the second RewriteCond.

I also eliminated the first RewriteCond from your second rule, since the rule pattern itself will not match "index.php". You may also wish to eliminate the second RewriteCond (now the first) -- the test for "file exists"-- since I presume that all of your files have file extensions, and "exists" checks are "expensive" because they make requests to the OS filesystem and possibly to the disk itself. Since the rule pattern won't match any URL-path with a period in it, checking for file-exists is unnecessary unless you have extensionless filenames.

The ">" character used in the these rules is an arbitrary string. It implies concatenation, but is used only to delimit the two variables -- i.e. allow the end of one and the beginning of the other to be correctly identified.

Jim

[edited by: jdMorgan at 3:04 am (utc) on April 21, 2009]

GordonB

7:21 am on Apr 21, 2009 (gmt 0)

10+ Year Member



Jim,

Awesome!

Many thanks for your help, it works exactly.

I'd also like to thank you for going to the trouble of explaining your answer, I much appreciate it.

Your attention to detail is fantastic - even with my typos (example.com.com instead of example.com)!

I had thought that a stored variable was necessary as I couldn't write down the logic myself without it, I didn't know how to set it though.

Taking your advice, I've ended up with this as the simplest, shortest code:

Options +FollowSymLinks
RewriteEngine on
#
#Set a variable for the subdirectory if not www
RewriteCond %{HTTP_HOST} !^www\.
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.com
RewriteRule ^.*$ - [E=setSub:%1]
#
#Set a variable for the string after the domain name if not a file and not a directory
# and all files have an extension
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^.]+)$ - [E=setVar:$1]
#
# Rewrite with either subdomain or variable or both
RewriteCond %{ENV:setSub}%{ENV:setVar} ^.
RewriteCond %{ENV:setSub}>%{ENV:setVar} ^(.*)>(.*)$
RewriteRule ^.*$ http://example.com/index.php?s=%1&v=%2 [L]

It works exactly as required.

Your help is much appreciated,
Gordon