13

I hope this is a simple YES or NO answer (please specify why)

Q1: Does it matter in which order rules are placed in htaccess?
Especially when they are completely separated items.

Q2: If yes, am I applying the right order?
I want to to speed up the htacces engine and not overload it with unneccessary rules.

Q3. Any tips as are welcome about what to remove/add.
Thanks!


# DirectoryIndex index.php /index.php
AddDefaultCharset UTF-8
RewriteEngine on
# Options All
# Options +FollowSymLinks
# Options +FollowSymLinks -Indexes -ExecCGI
# RewriteBase /

#####################################################

<IfModule mod_headers.c>
    ExpiresActive On
    ExpiresDefault M172800
    Header unset ETag
    FileETag None
    Header unset Pragma

    ##### STATIC FILES
    <FilesMatch "\\.(ico|jpg|png|gif|svg|swf|css|js|fon|ttf|eot|xml|pdf|flv)$">
        ExpiresDefault M1209600
        Header set Cache-Control "public, max-age=1209600"
    </FilesMatch>

    ##### DYNAMIC PAGES
    <FilesMatch "\\.(php)$">
        ExpiresDefault M604800
        Header set Cache-Control "public, max-age=604800"
    </FilesMatch>
</IfModule>

#####################################################

#  /page123 and /page123/ will all go to /page123.php
RewriteRule ^(.+)/$  /$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php

####################################################
    
# NO WWW   http://www. becomes always http://
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]

##############################################################
# add own extensions that will be interpreted as php
AddType application/x-httpd-php .php
AddType image/svg+xml svg svgz
AddType text/css css
AddType text/javascript js
AddEncoding gzip svgz

##############################################################

ErrorDocument 500 /
ErrorDocument 404 /

5 Answers 5

15

Well, .htaccess files use the same format as the regular Apache configuration file, so the same rules apply.

Most config settings do not depend on order, but some do - depends on the setting.

RewriteRule and RewriteCond e.g. are sensitive to order, so in that case the answer is YES.

See e.g.

http://wiki.apache.org/httpd/RewriteRule

for an explanation of the order that these are evaluated.

6

It does matter. Quoting from the documentation for RewriteRule:

The order in which these rules are defined is important - this is the order in which they will be applied at run-time.

1
  • 2
    Within mod_rewrite, it matters - yes. However, the OP isn't specifically addressing mod_rewrite and there are many other directives from other modules in the OP's .htaccess file. In short, directives from different modules (and in different containers) execute independently and in a predefined order, regardless of their apparent order in the config file.
    – MrWhite
    Commented Sep 9, 2017 at 15:01
3

I cannot speak on how the order of <files> vs <Rewrite>, for example, affects performance. I am trying to find that out myself. I've been unable to find any info about this, so possibly it does not matter??

However, I'd like to point out that between Rewrite vs Redirect (and RedirectMatch), the order of execution may not be in the order listed, although that's often what people may expect..
Specifically, the mod_rewrite and mod_alias modules are processed/executed independantly, and in that order.

  1. All mod_rewrite directives (Rewrite) are executed (in order they are listed).
  2. THEN all mod_alias directives (Redirect and RedirectMatch) are executed in the order they are listed in the file.

So, even if a Redirect proceeds a Rewrite, the Redirect will be processed only after all the Rewrites have been processed.

One way to keep the file "readable" if you have both redirects and rewrites, is to not use the mod_alias module at all. Instead, use only mod_rewrite. Rewrite with the [R] flag essentially turns it into a rewrite.
This webmaster's Answer shows how.

Now, all the directives will be executed in the order they appear in the file, so there are no nasty surprises, or confusion about the order of execution. Alternatively, you could physically relocate all the Redirect and RedirectMatch directives to the "bottom" of the file, so as to remind yourself that they won't be executed until after the Rewrites anyway.

Here are some good StackExchange answers that enlightened on to this point:

As for the rest, I have not been able to find any info on performance between placing files before or after rewrites, for example. The only performance based advice I found, is that if one has access to server configuration files, then it's best to move as much as possible from the .htaccess file to the config file, and disable .htaccess files altogether (or specify specific directories where .htaccess files should be read).

The logic there is that rules placed in the config file need only be read once. If htaccess processing is turned on, then for every request, every directory of the server (at or higher than the requested directory) must be searched for possible htaccess files, whether they exist or not. And if they do, every one must be read anew.

0
2

There is much more than "the order does matter" to this question. Apache has a complex processing algorithm of its config files - this may be surprising. Here is my understanding from what I've discovered.

Briefly, Apache doesn't "execute" config files line by line. It pre-processes the config files (server config, .htaccess etc.), extracts configs related to different modules using a special algorithm (it may be surprising, see below) and then gives respective "extracted" configs to each module so that they process just the rules they understand. I.e. mod_headers gets its own config with statements it understands, mod_rewrite gets its own config etc.

The main takeaway is - each module processes its own config as if other modules don't exist (again, the config that was pre-processed by Apache, which may not match what one would naturally expect) - don't expect that different modules can be naturally mixed to work together (e.g. as modules in JavaScript or other programming languages). If you set an environment variable in mod_rewrite then you cannot read it in <If> statement located below in your config and in most other modules' statements (to be precise, you can do it if the other module is processed after mod_rewrite, but you often don't know the processing order).

About Apache's config extraction algorithm

Apache's config consists of sections. <Directory>, <If>, <Files> tags etc. each enclose a section. Sections may be nested (<Files> inside of a <Directory>).

Apache goes through the sections in its predefined order (briefly, all <Directory> sections are parsed first, all <Files> go next, then the <Locations>, then <If>s), finds the first section (in the order above!!!) that matches the current request context (directory path, file name pattern, <If> tag condition etc.), extracts config statements related to specific module (say, mod_rewrite). This is the first set of config statements for this module. Then it looks for the next matching section - if it exists then Apache extracts all config statements from this second section (this is the second set of config statements) and gives both sets of config statements for mod_rewrite to merge those sets together. "Merging" may mean "replacing", or it may mean "appending" etc. - this is defined by specific module (an example for mod_rewrite, see "Per-Directory Rewrites" note there). The same happens with any other section that matches current context. After all the matching sections are processed (extracted by Apache and merged together by specific module) we get the final config for this module. The whole process happens for every module.

After that each module gets its chance to process the HTTP request using its final configuration. To remind, modules do all their processing one by one.

Full description from Apache

If you want a more in-depth understanding, here is a link to "How the sections are merged" chapter in Apache docs. Please pay special attention to the "Relationship between modules and configuration sections", that has useful examples of how tricky section processing order and resulting module configuration may be.

-1

I have the same concern posted but this is a server admin site perspective which allows them to restart apache after an apache server config change.

So far, the best response I've received is to list File related directives first.

This makes sense related to apache's need to manage directories and htaccess instructions in each directory.

So, list file related directives first, then obvious blocks to end the apache htaccess process in order of the obvious.

Possible solution to optimize the requests: - request url related corrections - Directory related restrictions - Index related restrictions - file related restrictions - proxy restrictions <-- kill all - empty user agent <-- kill all ... the list is endless fun

My concern related to sequence of directives. For instance, should I set Index, file, and Header directives before RewriteConds?

1
  • footnote: RewriteRule pattern substitution [flags] do Not answer this obvious application processing question!
    – Testbench
    Commented Feb 18, 2015 at 22:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .