You are on page 1of 2

Digging In To Apaches Rewrite Module And Drupal | Phase2

Digging In To Apaches Rewrite Module


And Drupal
NOVEMBER 13, 2013 IN DEVELOPMENT, DRUPAL

1 of 2

Apaches mod_rewrite module is a powerful tool behind Drupals clean URLs, but it can lead to
some head scratching moments when attempting to implement custom behavior. In this post,
well walk through a few examples and dig into some corner cases of Apaches Rewrite module and
Drupal.
For our first scenario were redirecting all GET requests to SSL except those for robots.txt. This is
pretty straight forward
1
2
3
4
5

RewriteCond
RewriteCond
RewriteCond
RewriteCond
RewriteRule

%{HTTP_HOST} example\.com
%{REQUEST_URI} !^/robots.txt
%{HTTPS} !on
%{REQUEST_METHOD} GET
^ https://example.com%{REQUEST_URI} [L,QSA,R=301]

Where it becomes interesting is if we also want to allow requests handled by Drupal to avoid being
redirected. For example, assume that any RSS feeds are handled by Drupal but there is no need to
force those over SSL. You might think the following would be suicient:
1
2
3
4
5
6

RewriteCond
RewriteCond
RewriteCond
RewriteCond
RewriteCond
RewriteRule

%{HTTP_HOST} example\.com
%{REQUEST_URI} !^/robots.txt
%{REQUEST_URI} !\.rss$
%{HTTPS} !on
%{REQUEST_METHOD} GET
^ https://example.com%{REQUEST_URI} [L,QSA,R=301]

Using only the above, however, results in a redirection being issued to https://example.com
/index.php. This is because while the redirect is bypassed here, Drupals use of the Rewrite module
means that another pass through the rewrite rules is generated and the redirect is happening on
this pass. This pass does not appear to trigger as a sub-request so adding the NS flag to the
RewriteRule does not stop the rule from being applied. Using SetEnvIf, however, provides an
option.
1
2
3
4
5
6
7
8

SetEnvIf Request_URI \.rss$ RSS_REQUEST=TRUE


RewriteCond %{HTTP_HOST} example\.com
RewriteCond %{REQUEST_URI} !^/robots.txt
RewriteCond %{ENV:REDIRECT_RSS_REQUEST} !=TRUE
RewriteCond %{ENV:RSS_REQUEST} !=TRUE
RewriteCond %{HTTPS} !on
RewriteCond %{REQUEST_METHOD} GET
RewriteRule ^ https://example.com%{REQUEST_URI} [L,QSA,R=301]

What is important to notice is that while the SetEnvIf line only sets the variable RSS_REQUEST, we
actually test against both RSS_REQUEST and REDIRECT_RSS_REQUEST. This is because when
Apache is processing the first pass the RSS_REQUEST variable has our desired value but on the
subsequent pass it is renamed to REDIRECT_VARIABLE_NAME, in this case REDIRECT_RSS_REQUEST.
http://www.phase2technology.com/blog/digging-in-to-apaches-rewrite...

8/28/2014 4:49 AM

Digging In To Apaches Rewrite Module And Drupal | Phase2

2 of 2

The SetEnvIf technique can be very useful, especially in places where you may want conditional
authentication provided by the web server. This is commonly done for development or staging
sites to prevent them from being accidentally crawled by search engines and to provide some
security for the sites while they are in development. The conditional authentication can be handy
when there are aspects of the site that cant interoperate with the authentication requirement but
you dont want to make the entire site available. Here is an example of using SetEnvIf to allow
bypassing HTTP Basic authentication for a few dierent paths on a site. As you can see, what we
learned about the REDIRECT_* variable renaming from the Rewrite examples is important.
1
2
3
4
5
6
7
8
9
10
11

AuthType Basic
AuthName "Access Restricted"
AuthUserFile /path/to/the/username/password/file/.htpasswd
Require valid-user
SetEnvIf Request_URI ^/openid/ AUTH_WHITELIST
SetEnvIf Request_URI ^/user/.*/identity AUTH_WHITELIST
SetEnvIf Request_URI ^/sites/.*/files/ AUTH_WHITELIST
Deny from All
Allow from env=AUTH_WHITELIST
Allow from env=REDIRECT_AUTH_WHITELIST
Satisfy Any

If you would like to dig in more on Apaches rewrite module check out the following resources
The mod_rewrite introduction
More detailed description of how rewrite rules are processed
The reference documentation for the rewrite module
Environmental variables in Apache- It was through a comment at the bottom of this page
that I learned about the REDIRECT_ renaming that Apache does.

http://www.phase2technology.com/blog/digging-in-to-apaches-rewrite...

8/28/2014 4:49 AM

You might also like