Forum Moderators: phranque
<IfModule mod_rewrite.c>
RewriteEngine on
##
# Forbid direct viewing txt files in pages folder
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\ (.*)/pages/(.*)\.txt [NC]
RewriteRule ^ "-" [F]
##
# SITE SPECIFIC ACTION
# Remove index php root only
# ACTION (i) exclude named subfolders
# eg (folder1) or (folder1|folder2) etc
RewriteCond %{REQUEST_URI} !(admin|diagnostics|visits) [NC]
# ACTION (ii) set site folder from site root
# eg / for root or /cms/ for subfolder
RewriteRule ^index\.php$ /cms/ [R=301,L]
##
# Remove php extensions
# ACTION (iii) exclude named subfolders
# eg (folder1) or (folder1|folder2) etc
RewriteCond %{REQUEST_URI} !(admin|diagnostics|visits) [NC]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\ (.*)\.php [NC]
RewriteRule ^ %1 [R=301,L]
# END SITE SPECIFIC
##
# Rewrite non php URLs to php on server
# php URLs still usable
# Is not a directory
RewriteCond %{REQUEST_FILENAME} !-d
# Is an actual php file
RewriteCond %{REQUEST_FILENAME}\.php -f
# Internally rewrite to actual php file
Rewrite-rule ^(.*)$ $1.php
##
# If not found then relative path to error 404 file
# Is not an actual file or directory
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* inc/404.php [L]
</IfModule> I would prefer not to have to introduce RewriteBase.No need to, because (a) the default RewriteBase is already / (root of whatever site you're currently on) and, more importantly, (b) every RewriteRule target should begin with either https://example.com/ (for external redirects) or / (for internal rewrites), making the RewriteBase question entirely moot.
every RewriteRule target should begin with either https://example.com/ (for external redirects)
RewriteRule ^index\.php$ /cms/ [R=301,L]
RewriteRule ^index\.php$ https://www.example.com/cms/ [R=301,L] RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\ (.*)\.php [NC]
RewriteRule ^ %1 [R=301,L]
RewriteRule ^(.+)\.php$ https://www.example.com/$1 [R=301,L] # If not found then relative path to error 404 file
# Is not an actual file or directory
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* inc/404.php [L]
# If not found then 410 Gone response
# Is not an actual file or directory
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . - [G] RewriteCond %{HTTPS} !on [OR]
RewriteCond %{HTTP_HOST} !^(www\.example\.com)?$ [NC]
RewriteRule (.*) https://www.example.com/$1 [R=301,L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\ (.*)\.php [NC]Here I'd go with option C. Since the vast majority of requests will not end in .php, why make the server go to the work of a capture that ends up being thrown away--especially one that can’t help being inefficient. Instead something like
RewriteRule ^ %1 [R=301,L]
something like this:
RewriteRule ^(.+)\.php$ https://www.example.com/$1 [R=301,L]
RewriteCond %{THE_REQUEST} /([^.]+)\.php
RewriteRule \.php$ https://example.com/%1 [R=301,L,NS]
where the [NS] flag immediately excludes things like auto-indexes (if any directory allows them) or, conversely, directory indexes in /index.php, and then the RewriteCond takes care of anything left over. That's assuming there don't happen to be literal . periods in a normal URL. (Perfectly legal, but a lot of rules are much easier if you don't use them.) RewriteCond %{REQUEST_FILENAME} !-dThis would seem to be superfluous, unless the site actually has directories named /directory.php/. (Legitimate robots will ask for directories without final slash, so if you have a /directory.php/ there will be requests for /directory.php without slash.)
<IfModule mod_rewrite.c>
RewriteEngine on
# 1 ESSENTIAL ACCESS CONTROL
# Forbid direct viewing txt files in pages folder
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\ (.*)/pages/(.*)\.txt [NC]
RewriteRule ^ "-" [F]
# 2 ESSENTIAL GENERIC INTERNAL REWRITES
# Rewrite non php URLs to php on server
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
# If not found then relative path to error 404 file
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* inc/404.php [L]
</IfModule> <IfModule mod_rewrite.c>
RewriteEngine on
# 1 ESSENTIAL ACCESS CONTROL
# Forbid direct viewing txt files in pages folder
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\ (.*)/pages/(.*)\.txt [NC]
RewriteRule ^ "-" [F]
# 2 OPTIONAL SITE SPECIFIC EXTERNAL REDIRECTS USER EDITS
# Remove index php root only
RewriteCond %{REQUEST_URI} !(admin|diagnostics|visits) [NC]
RewriteRule ^index\.php$ https://files.domain.com/cms/ [R=301,L]
# Remove php extensions root only
RewriteCond %{REQUEST_URI} !(admin|diagnostics|visits) [NC]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\ (.*)\.php [NC]
RewriteRule ^(.+)\.php$ https://files.domain.com/cms/$1 [R=301,L]
# Hostname canonicalization redirect 1 if not sub domain
# RewriteCond %{HTTP_HOST} ^www\. [NC]
# RewriteRule (.*) https://files.domain.com/cms/$1 [R=301,L]
# Hostname canonicalization redirect 2
RewriteCond %{HTTPS} off
RewriteRule (.*) https://files.domain.com/cms/$1 [R=301,L]
# 3 ESSENTIAL GENERIC INTERNAL REWRITES
# Rewrite non php URLs to php on server
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
# If not found then relative path to error 404 file
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* inc/404.php [L]
</IfModule> I have not understood exactly what phranque is suggesting.
how this is an especially inefficient captureI wouldn’t say “especially” inefficient. Just run-of-the-mill vanilla inefficient, like any rule that has non-final .+ or .* because then the server has to backtrack “oh, whoops, I was supposed to leave room for .php at the end”.
this will fail to match requests for any directory names containing dots in url paths or any php filenames containing 2 or more dotsYes, that’s right. That’s why I specified that this handy time-saver can only be used if your file or directory names (whether real or virtual) do not contain literal dots. This, in turn, obviously depends on the site: apache dot org, to take the obvious example, has directory names with dots because that’s where they keep information about version numbers (2.0, 2.2, 2.4); any site involving IP lookups will have URLs ending in 1.2.3.4 ... and so on.
when I go to a non-existent URL on 'files.domain.com/cms/' the status code is 404 Not Found. That is when I use Developer tools in Chrome. The address bar shows files.domain.com/cms/non-existent-page and the content of inc/404.php is displayed, including a link back to the sub-domain plus the sub-directoryThat would seem to be exactly the intended result. What’s the problem?
That would seem to be exactly the intended result. What’s the problem?