开发者

mod_rewrite in <Location /> in apache conf causing rewrite in .htaccess file not to work?

I am using zend framework, which has a nifty example .htaccess used for redirecting non-existing locations to index.php to be processed by the framework:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ /site/index.php [NC,L]

And here is the apache config for /site

Alias /site "/path/to/zf/project/public"
<Directory "/path/to/zf/project/public">
    Options Indexes MultiViews FollowSymLinks
    AllowOverride All
    Order allow,deny
    Allow from all
</Directory>

While we are upgrading the site, I want to redirect all traffic to a specific file (offline.html, for example) except for a certain IP (127.0.0.1, for example), so I am trying to use this rule in the apache config:

<Location />
    Options Indexes MultiViews FollowSymLinks
    AllowOverride All
    Order allow,deny
    Allow from all

    RewriteEngine On
    RewriteBase /
    RewriteCond %{REMOTE_HOST} !^127\.0\.开发者_Go百科0\.1
    RewriteCond %{REQUEST_URI} !/offline\.html$
    RewriteRule .* /offline.html [R=302,L]
</Location>

This seems to work, but for some reason it makes my .htaccess file seem not to work. I can access /site just fine, but I can't go any deeper to, for example, /site/controller/action.

Thanks!


The Apache 2.2 and Apache 2.4 documentation of mod_rewrite clearly state that rewrite rules in <Location> directives should be avoided. This caution was not included in the Apache 2.0 documentation.

Although rewrite rules are syntactically permitted in <Location> and <Files> sections (including their regular expression counterparts), this should never be necessary and is unsupported. A likely feature to break in these contexts is relative substitutions.

So strange things can happen. You could remove the <Location> section (and RewriteBase directive) and use these new rewrite rules directly in the <VirtualHost> definition, without any <Directory> or <Location> section. It's even faster.

The only problem with global level rewrite rules is that you do not have the REQUEST_FILENAME already computed (you could hack that a little but here you do not even need REQUEST_FILENAME).

You also have one error in your RewriteRule, you use a Redirect so the rewrite Rule should use a absolute url:

RewriteRule .* http://www.example.com/offline.html [R=302,L]

About the maintenance page, a classic way of handling it is with these two lines:

ErrorDocument 503 /htdocs/err/503.html
RedirectMatch 503 ^/(?!err/)

Where you do not filter on local IP, but the interesting part is that the code used for maintenance is 503 (temporary unavailable) which is more correct (in fact a redirect 307 is even more correct but old browser could have problems with it). To do the same with a local IP restriction and a RewriteRule it would be:

ErrorDocument 503 /offline.html
RewriteCond %{REMOTE_HOST} !^127\.0\.0\.1
RewriteCond %{ENV:REDIRECT_STATUS} !=503
RewriteRule ^ - [L,R=503]


To have these rules in the htaccess file, you'll have to add/remove them by hand when you want to use "offline mode".

A better way to do this through the application is to create a controller plugin. If the APPLICATION_ENV = 'offline', the plugin would do _forward('offline', 'error', 'default');

Alternatively, you could write the logic in a subclass of Zend_Controller_Action which you use as the base class for your controllers.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜