Forum Moderators: phranque
boilerplate on cleaning up an htaccess file.
<Files ~ "\.xml$">
<IfModule !mod_authz_core.c>
Deny from all
</IfModule>
<Files ~ "\.xml$">
<RequireNone>
Require mod_authz_core
</RequireNone>
</Files>
Would this work?If you are running Apache 2.4, then yes. If you are not, then no. If you are on shared hosting, as implied by the use of htaccess, you are probably not on 2.4 yet.
RewriteCond %{THE_REQUEST} \.xml
RewriteCond %{REQUEST_URI} !/sitemap\.xml
RewriteRule \.xml - [F]But that may not be even remotely what you are trying to achieve; it's just one off-the-top-of-my-head ruleset.
There is a mod_rewrite.c to handle rewrites for fancy urlsThe <IfModule> envelope is most often used with directives that use that specific mod--but it doesn't have to be. (I once experimented on my test site. Basically it means "If this mod is not available, pretend you don't see the enclosed lines of text--independent of what they might happen to say.")
This contains two RewriteCond and a RewriteRule
<!--#printenv --> <IfModule mod_access.c>
SetEnv MOD_mod_access 1
</IfModule>
<IfModule mod_actions.c>
SetEnv MOD_mod_actions 1
</IfModule>
<IfModule mod_alias.c>
SetEnv MOD_mod_alias 1
</IfModule>et cetera, using all the mod names you can think of--or, to keep it shorter, all the mod names that you currently find in your <IfModule> envelopes. If you want to be really thorough, open the apache docs for versions 2.2 and 2.4, and copy all the module names. # blocks direct access to the XML files - they hold all the data!
<Files ~ "\.xml$">
<IfModule !mod_authz_core.c>
Deny from all
</IfModule>
<IfModule mod_access_compat.c>
Deny from all
</IfModule>
<IfModule mod_authz_core.c>
<IfModule !mod_access_compat.c>
Require all denied
</IfModule>
</IfModule>
</Files>
<Files sitemap.xml>
<IfModule !mod_authz_core.c>
Allow from all
</IfModule>
<IfModule mod_access_compat.c>
Allow from all
</IfModule>
<IfModule mod_authz_core.c>
<IfModule !mod_access_compat.c>
Require all granted
</IfModule>
</IfModule>
</Files>
It is 2.4Ooh, I'm envious. (Hm, keyplyr, our mutual host seems to have missed their deadline. Wasn't there some blahblah about third quarter of 2017?)
Ooh, I'm envious.Don't be. I'm not there yet but that's probably (most likely is) my fault.
<Files ~ "\.xml$">
<RequireNone>
Require mod_authz_core
</RequireNone>
</Files> # comment-line like thisto test whether it's the overall structure, or some syntactic detail, that's making your server unhappy. Require mod_authz_coreI thought “Require" directives pertained to aspects of the request. The <RequireNone> envelope basically corresponds to anything that was previously introduced by "Deny from".
Require ip various-numbers-hereis the exact replacement of your old "Deny from" IP-based lines. The other one that works as a direct translation is Require env blahblahreplacing "Deny from env=blahblah". I ran the code through a validatorAn Apache validator, you mean?
<Files ~ "\.xml$">
<RequireNone>
Require mod_authz_core
</RequireNone>
</Files> Neither validator understood <RequireNone>Double-check if there's an overall setting for which version of Apache you're validating. If there isn't--or if you've explicitly selected 2.4 and you still get an error--then, well, cross that validator off your list. The three locutions <RequireAll> <RequireAny> and <RequireNone> belong to the same mod, so it's obviously nonsense for a validator to recognize one of them but not another.
Remember that apache config files apply to all requests, whether external or internal.
The <Files> directive limits the scope of the enclosed directives by filename. It is comparable to the <Directory> and <Location> directives. It should be matched with a </Files> directive. The directives given within this section will be applied to any object with a basename (last component of filename) matching the specified filename. <Files> sections are processed in the order they appear in the configuration file, after the <Directory> sections and .htaccess files are read, but before <Location> sections. Note that <Files> can be nested inside <Directory> sections to restrict the portion of the filesystem they apply to.
IfModules for xml
# blocks direct access to the XML files - they hold all the data!
<Files ~ "\.xml$">
<IfModule !mod_authz_core.c>
Deny from all
</IfModule>
<IfModule mod_access_compat.c>
Deny from all
</IfModule>
<IfModule mod_authz_core.c>
<IfModule !mod_access_compat.c>
Require all denied
</IfModule>
</IfModule>
</Files>
<Files sitemap.xml>
<IfModule !mod_authz_core.c>
Allow from all
</IfModule>
<IfModule mod_access_compat.c>
Allow from all
</IfModule>
<IfModule mod_authz_core.c>
<IfModule !mod_access_compat.c>
Require all granted
</IfModule>
</IfModule>
</Files>
<Files ~ "\.xml$">
Deny from all
</Files>
<Files sitemap.xml>
Allow from all
</Files> <Files ~ "\.xml$">
Require all denied
</Files>
<Files sitemap.xml>
Require all granted
</Files>
# handle rewrites for fancy urls
<IfModule mod_rewrite.c>
RewriteEngine on
# Usually RewriteBase is just '/', but
# replace it with your subdirectory path
#RewriteBase /ipcodesign/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule /?([A-Za-z0-9_-]+)/?$ index.php?id=$1 [QSA,L]
</IfModule>
#
#
# 301 code redirect
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteEngine on
# 301 code redirect
# if the requested protocol is not HTTPS or
RewriteCond %{HTTPS} !on [OR]
# if the provided Host header value (if any) is not exactly the canonical hostname (or null)
RewriteCond %{HTTP_HOST} !^(www\.example\.com)?$
# externally redirect any such noncanonical protocol or hostname requests using a 301 status code to the same requested path on the canonical protocol and hostname
RewriteRule (.*) https://www.example.com/$1 [R=301,L]
# handle rewrites for fancy urls
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule /?([A-Za-z0-9_-]+)/?$ index.php?id=$1 [QSA,L]
RewriteRule /?([A-Za-z0-9_-]+)/?$ index.php?id=$1 [QSA,L]
/index.php?id=$1 [QSA,L]with leading slash representing the root. Personally I would say [\w-]+ at a savings of eight bytes, but we all know about individual coding styles. And since this is htaccess, we can be certain there will be no leading slash, making it RewriteRule ^([A-Za-z0-9_-]+)/?$ /index.php?id=$1 [QSA,L]Or was there something about subdirectories that I missed? Shouldn't matter, though, if there's no opening anchor; it's the same capture either way. (And where did the optional final / come from? Usually with rewrites you don't want to leave anything optional or suddenly you're getting Duplicate Content all over the place and search engines asking for /long-complicated-file-name/index.html.)