RewriteRule (mod_rewrite) guide

apache

mod_rewrite est très utile dans de nombreuses situations. Pourtant, certains comportements n’étaient pas si évidents lorsque j’ai commencé à m’en servir.

Après de nombreux tests, je le comprends beaucoup mieux maintenant. Cela dit, je ne prétends pas le connaître parfaitement. Je fais aussi des erreurs, régulièrement.

Donc, bien que j’ai testé tout cela sur mon serveur local et sur votre hébergement web, ne croyez pas aveuglément ce que je dis. Utilisez-le plutôt comme une suggestion ou une base pour vos propres expériences.

Première chose

Vous avez besoin de ces lignes avant toute règle.


'''Options Followsymlinks'''

# You need this in your .htaccess on some servers.
# You don't need it on PowWeb because it's already set.

'''RewriteEngine on'''

# You must put this line '''once''' before to put RewrteRule.

'''RewriteBase /'''

# You don't have to put this in many cases.
# But specifying it can reduce the risk of endless looping.
#
# Also, certain internal redirect rules and conditions
# will not work well if you don't use this line.
# So, put it, and forget about adding / at the beginning of the
# substitute string

# With "RewriteBase /", substitute string of RewriteRule will have
# forward slash added automatically.
#
# But this have no effect on %{REQUEST_URI}, and it starts with
# forward slash unlike URL of RewriteRule.
#
# RewriteRule URL: "/" is stripped automatically.
# RewriteRule substitute: "/" is added automatically.
# %(REQUEST_URI}: always start with "/".

RewriteRules

# RewriteRule have following format.
# Each part separated by a space.

'''RewriteRule''' REGEX substitution [options if any]

# REGEX is Perl compatible Regular expression.

# ex. RewriteRule ^(abc.*)$ xxx$1 [R]
#
# ^ == beginning of URL
# $ == end of URL
# . (period) == matches any one character
# * == matches with zero or more of previous character.
#
# The URL is matched against REGEX without "http://host.com/",
# and the QUERY_STRING part (the part after ? ) stripped.
# ie. The address: http://zoro.com'''/faint.cgi'''?a=2&b=xxx
# The URL used in the rule: '''/faint.cgi'''
#
# So, this matches any URL starting with "abc".
# And entire URL is grouped by ( ) to be used in the substitution
# (referenced by) $1.
# As an option, this specify external redirect 302 (Temorary)

# RewriteRules may have additional Conditions.
RewriteCond STRING REGEX [optional flags]
RewriteCond STRING expression [optional flags]
RewriteRule REGEX substitution [optional flags]

# For the details of REGEX, expressions, substitutions and options,
# you should read Apache module mod_rewrite documentation.

mod_rewrite documentation
http://httpd.apache.org/docs/mod/mod_rewrite.html

URL rewriting Guide
http://httpd.apache.org/docs/misc/rewriteguide.html

Que se passe-t-il lorsque les règles modifient l’URL (dans le fichier .htaccess) ?

Lorsque la RewriteRule qui modifie l’URL correspond, l’URL modifiée passera par le prochain cycle de traitement depuis le début de l’ensemble des règles, à nouveau.
Il s’agit d’un point très important. C’est à cause de la façon dont Apache gère le contexte par répertoire (.htaccess, ou dans l’onglet ).
Il doit effectuer l’authentification par répertoire et d’autres processus pour le chemin nouvellement généré.

Dans un contexte par serveur ou hôte virtuel (dans httpd.conf), cela ne se produit pas.

ex. RewriteRule ^(.*)$ index.cgi?page=$1 [QSA]

In this example, URL is modified and the RewriteRule will be
applied again.

ex. RewriteRule ^(.*)$ $1?Added_QUERY_STRING [QSA]

In this example, URL is unchanged.
(For this document, URL is the part of address
without "http://host.com/" and "?QUERY_STRING" portion.)

Thus, it will not go through 2nd round of processing
(the modification on QUERY_STRING does not affect this),
unless it's a URL for a directory and transformed according to
the DirectoryIndex directive or when resulting filepath doesn't exist.

ex. RewriteRule ^(abc.*)$ xxx/$1 [L]
RewriteRule ^xxx/(.*)$ yyy/$1

As the 1st rule changes URL, modified URL "/xxx/abcSomething"
will go through next round and checked against from the
1st rule, again.

So, even the 1st rule has [L] (last) option to indicate following
rules to be skipped, '''in the 2nd round''', the URL will match
the next rule, and modified to "/yyy/abcSomething".

Then, this URL will go through 3rd round.
But it will not match any rules, and the processing stops there.

Anti-Leech, économie de bande passante, blocage des référents

Je comprends l’envie de faire ces choses. Cependant, ce n’est pas vraiment efficace, et cela cause souvent plus de maux de tête.

Je ne le recommande pas à moins de bien connaître la réécriture, son efficacité limitée et les problèmes potentiels.

Si vous avec un bon hébergeur, vous avez suffisamment de bande passante pour faire face au « Leeching » habituel. Cependant, la mise à l’écart de certains robots est une bonne pratique. Certains robots accèdent à plus de plusieurs centaines d’éléments par minute. Si votre script est frappé de la sorte, le serveur peut subir une charge importante.

## Keep bad robots off.
## Give them blank page instead of 403. Cost less for thr server

RewriteEngine on
RewriteBase /

RewriteRule ^blank\.txt - [L]

RewriteCond %{HTTP_USER_AGENT} (MSIECrawler|Ninja|Microsoft|MSFront|WebCopier|Pockey) [NC]
RewriteRule ^(.*)$ blank.txt [L]