1

On a service available through different subdomains/domains, I want to be able to use only one .htaccess file. For each possible value of %{HTTP_HOST}, I have set up if blocks like this:

<if "%{HTTP_HOST} == 'staging.project.example.org'">
    [detailed configuration...]
</if>

<if "%{HTTP_HOST} == 'development.project.example.org'">
    [detailed configuration...]
</if>

This works well with access configuration lines like:

<if "%{HTTP_HOST} == 'staging.project.example.org'">
    AuthType Basic
    AuthUserFile ".htusers"
    Require user example
    Order deny,allow
    Deny from all
   Allow from xxx.xx.xx.xxx
</if>

But RewriteRule lines like this will be ignored by Apache:

<if "%{HTTP_HOST} == 'production.project.example.org'">
    RewriteEngine On
    RewriteBase /
    RewriteCond %{REQUEST_URI} !^/maintenance\.html$
    RewriteRule ^(.*)$ https://www.project.example/maintenance.html [R=307,P]
</if>

Is it possible to use RewriteRule with if in .htaccess? I think it might be because of

"Only directives that support the directory context can be used within this configuration section."
in https://httpd.apache.org/docs/2.4/en/mod/core.html#if

but is there a way around this?

3840
  • 376
  • 3
  • 16
  • Mod_rewrite does support the directory context, so it passes that criteria, although I'm not saying it should definitely work. When you say it doesn't work, in what way? What happens when you try it? –  Feb 02 '17 at 16:08
  • Nothing happens - the RewriteRules inside ``if``are ignored. – 3840 Feb 02 '17 at 16:12
  • you should just concatenate "If" statements or declare and if that checks for both things, also, do not mix P and R flags in mod_rewrite since they are meant for different things, do you want to redirect or rev proxy? – Daniel Ferradal Feb 02 '17 at 16:13

3 Answers3

1

I don't think rewrite rules can work in an if directive, but you can include the same logic in the rewrite rule itself:

RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} production.project.example.org
RewriteCond %{REQUEST_URI} !^/maintenance\.html$
RewriteRule ^(.*)$ https://www.project.example/maintenance.html [R=307,P]

The RewriteCond statements form a logical AND giving you the same logic as if you encapsulated in if directives

arco444
  • 22,002
  • 12
  • 63
  • 67
  • instead of flagging my comment for removal, at least try to fix the R,P flags in your answer, stackoverflow doesn't let me because its just 2 characters. – Daniel Ferradal Feb 03 '17 at 11:18
0

If and mod_rewrite in some cases can play the exact same roles, for instance, in mod_rewrite an "If" would be like RewriteCond.

So.. do not mix them together, use one, or the other.

Daniel Ferradal
  • 2,727
  • 1
  • 13
  • 19
0

To answer my own question: For host-specific rules within the same .htaccess file, I did this, which uses a logic similar to this other answer.

SetEnvIfNoCase Host staging.project.example.org $ require_auth=true
AuthType Basic
AuthUserFile "/path/to/your/.htusers"
Order Deny,Allow
Deny from env=require_auth
Allow from xxx.xx.xx.xx # to allow certain IPs without login
Require user ... # users from the .htusers file above that are allowed to login
Satisfy any

Using this setting, any access using the host staging.project.example.org will need to go through authentication or match a whitelisted IP.

Multiple lines of SetEnvIfNoCase are possible.

3840
  • 376
  • 3
  • 16