Forum Moderators: phranque
RewriteRule ^foo/(?:(lorem|ipsum)/)?[^/]+/([0-9]+)/? /bar/view/?topic=$1&id=$2 [NC,QSA,NE,L]
RewriteRule ^foo/(lorem|ipsum)/?$ /bar/?topic=$1 [NC,QSA,L]
# I broke this next in to 2 lines so that I ONLY match text after foo if there's a / separating it
RewriteRule ^foo/([\w\.-]+)/?$ /bar/$1 [NC,L]
RewriteRule ^foo/?$ /bar [NC,L]
LogLevel alert rewrite:trace3
canonicalization redirect
I honestly have no idea what that isYes, you do, you've just blanked-out on what it is called ;) It’s the redirect that captures all the
RewriteEngine on
# this is new, I haven't uploaded it yet for fear of crashing the server again
#
# no way to set its own log, I just have to grep it from the general error log
# to read log in SSH, this is the command on Apache's site but it never completes:
# tail -f /var/log/apache2/error_log|fgrep '[rewrite:'
#
# I wrote this one and it works; I use "head" to limit to 10 results
# grep "\[rewrite:" /var/log/apache2/error_log | head
LogLevel alert rewrite:trace3
# Force https://www
RewriteCond %{HTTP_HOST} !^(www|ww2|images)\. [NC]
RewriteRule ^ https://ww2.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# Cache for 1 year; 1 month = 2628000
<FilesMatch "load_subnav\.php|\.(ico|css|js|jpg|jpeg|png|gif)$">
Header set Cache-Control "max-age=31536000, public"
</FilesMatch>
# Hack / Exploit Attempts
RewriteCond %{HTTP_REFERER} service.dropdowndeals.com [NC,OR]
RewriteCond %{REQUEST_URI} ^/(?:crossdomain|wp-|administrator)|(?:a|b|shell|tiki-register|who|xmlrpc)\.php [NC,OR]
RewriteCond %{QUERY_STRING} (?:(?:information|table)_schema|example_dbname|union+all+select) [NC]
RewriteRule .* - [F]
RewriteRule ^(?:post|view)\.php /index.php [L]
# Stub files; not sure if they're still relevant, I set them up a few years ago due to Adsense redirects
RewriteRule ^(ad(?:form|motion|rime|tech)|bonzai|contobox|doubleclick|exponential|eyeblaster|eyewonder|flashtalking|flite|ipinyou|jivox|knorex|kpsule|linkstorm|liquidus|mediaplex|mixpo|pointroll|predicta|revjet|rockabox|sociomantic|spongecell|unicast)/(.+) /stubs/$1/$2 [L]
# Touch icons
# I used to have a ton of these in the error log, so this just makes sure they all find something
RewriteRule ^apple-touch-icon.+\.png$ /apple-touch-icon.png [L] I always have this unintended-redirect possibility at the back of my mind, because the same thing happens if you neglect to put an early [L] rule involving your error documents...
The [NS] flag is sometimes useful, but it does not apply to requests arising from mod_rewrite itself.
RewriteRule ^403\.php - [L]
In addition to the unwanted-canonicalization issue (which makes your error-document names visible to the outside world), this also prevents infinite loops if you have RewriteRules that issue a 403 on their own. Note that this is an exception to the usual “List rules in order of severity” principle. In fact I’ve got a whole clutch of them, involving things like robots.txt and hotlink.png that are largely independent of ordinary access controls.
# Force https://www
RewriteCond %{HTTP_HOST} !^(www|ww2|images)\. [NC]
RewriteRule ^ https://ww2.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L] # Hack / Exploit Attempts this may as well precede the canonicalization redirectsYes indeed, and it ties in with what I said about grouping RewriteRules by order of severity. With rare exceptions, anything with [F] flag should go before anything with [R] flag. (And if you've got anything with [G] flag--most common in older sites where you’ve removed things over the years--that generally belongs between the two.)
these rulesets should be combined so a request for http://example.com/ doesn't result in chained redirects.
RewriteCond %{REQUEST_URI} !^/robots\.txt
RewriteCond %{HTTPS} !on [OR]
RewriteCond %{HTTP_HOST} !^example\.com$
RewriteRule (.*) https://example.com/$1 [R=301,L]
You can leave out the first Condition if it worries you; I’ve found it useful. Note the [OR] separating the two essential conditions. If you want to be superefficient, list the two in most-likely-to-succeed order. (This is a general principle for anything OR-delimited or pipe|delimited. Conversely, anything AND-delimited gets listed in most-likely-to-fail order.) But why do they? Why isn’t each one in its own VirtualHost section?
I actually don’t know if there is any measurable difference between the (.*) $1 capture approach, or the %{REQUEST_URI} approach. As so often, though, it may be more a matter of personal coding preference.
but I think that $1 would require a hard-coded / before $1, where %{REQUEST_URI} would notYes, certainly. But I was wondering which way, if any, makes significantly less work for the server. The (.*) business is already a teeny bit of superfluous work, since 9 requests out of 10 are already correct and then the capture just gets thrown away. (This is why I use a %1 arrangement, two steps forward and one back, with the index redirect--where it's more like 999 out of 1000 requests are correct to start with.)
This is why I use a %1 arrangement...
I'm finally right about something!Yes, and that’s precisely why I use the %1 approach in the specific and narrowly delimited case of an index redirect. Capturing in this case is moderately complex--in my case
RewriteRule index\.html$ https://example.com/%1 [R=301,NS,L]
where the [NS] flag is to exclude mod_dir activity. And then--only in the exceedingly rare case where the pattern matches--we go to a RewriteCond whose sole purpose is to do the actual capture. these rulesets should be combined so a request for http://example.com/ doesn't result in chained redirects.