views:

1433

answers:

3

This is an Apache question you've probably come across before. I want to have one source package that I can deploy to my workstation, my staging server, and my production server, but for it to load different .htaccess settings based on what the URL was.

Note that I was using a kludge with an IfModule call, but that won't work with our new production server because it shares all the same modules as my staging server.

Note I need to bundle SetEnv with these rewrites. Currently if you use RewriteCond, it only ties to the following RewriteRule, but not the SetEnv underneath.

A: 

Here is a simple example that should be enough for you to change it to meet your requirements:

<IfModule mod_rewrite.c>
    RewriteEngine On

    RewriteBase /

    RewriteCond %{HTTP_HOST} !^localhost
    RewriteCond %{HTTP_HOST} !^www\.
    RewriteRule (.*) http://www.%{HTTP_HOST}/$1 [R=301,L]
</IfModule>
Does that work kind of serially, where I can then append another RewriteCond below it with more RewriteRule entries, and it will only apply to the previous RewriteCond? I mean, in normal programming languages and markup you have some kind of start/stop block, whether it be curly braces. But not here
Also, is RewriteBase / important?
The problem with this approach is that it only works for RewriteRule, try and also use it for SetEnv or php_value and it doesn't work. That's why I used the IfModule kludge.
A: 

Instead of using SetEnv, use the environment variable setting capabilities of RewriteRule itself:

RewriteCond %{HTTP_HOST} =foo.com
RewriteRule ^ - [E=VARNAME:foo]

RewriteCond %{HTTP_HOST} =bar.com
RewriteRule ^ - [E=VARNAME:bar]

Although I prefer doing this sort of thing by passing flags to the httpd process at startup and looking for them using IfDefine blocks.

<IfDefine FOO>
SetEnv VARNAME foo
</IfDefine>

<IfDefine BAR>
SetEnv VARNAME bar
</IfDefine>
Michael Cramer
It should be noted that the php_value directive in Apache cannot be called in the first example -- only environment variables. In the second example, this is the best choice because you can literally define your server. However, this only works if you control the environment. If you are on a shared host, you have no way to control passing a parameter to the httpd process. Therefore, you look for inverse of this with <IfDefine !FOO>.
I found I can use IfDefine because my prod server is 100% controlled by me and I can mess with the /etc/sysconfig/httpd OPTION parameter and make it OPTIONS="-D prod". On the staging server, which is shared, I had to use IfDefine !prod and then stack an IfModule expires_module underneath it. On my workstation, I had to use IfDefine !prod followed by IfModule !expires_module. This gave me one .htaccess file that worked in dev, staging/test, and production.
A: 

On Ubuntu Linux, the IfDefine's variable is set in

/etc/apache2/envars

and is called APACHE_ARGUMENTS. So, at the bottom of that file I had to add:

export APACHE_ARGUMENTS="-D dev"

...and then bounce the server with:

/etc/init.d/apache2 stop
/etc/init.d/apache2 start

However, there's a Debian article on this topic that discusses this here. In that example, the file to edit is /etc/default/apache2 and the variable is called APACHE_DEFINES.

Likewise, on some systems it is a variable named OPTIONS that is set in /etc/sysconfig/httpd.

So, what you really need to do is look for the start section in your apache2ctl file. So, begin by doing a "whereis apache2ctl" to find where that script is, cat it out and find the start section with the apache2 directive in it, and see if the variable it passes is OPTIONS, APACHE_ARGUMENTS, APACHE_DEFINES, or something else. Then, see which file you need to edit by experimentation with either /etc/sysconfig/httpd, /etc/default/apache2, or /etc/apache2/envvars.

Volomike