Allow indexing subdirectories but not root directory - .htaccess

I have a site where subdirectories are generated automatically, and need to be indexable under .htaccess
However, I don't want someone to be able to go to the root of these subdirectories and to view them all. I also don't want anything other than these subdirectories to be indexable.
E.g.
/ ~ Has "Options -Indexes" (Non-Indexable)
/foo/ ~ Has "Options -Indexes" (Non-Indexable)
/foo/bar/ ~ Has "Options +Indexes" (Indexable)
/foo/baz/ ~ Has "Options +Indexes" (Indexable)
It's not possible for me to generate an individual .htaccess file for every subdirectory individually, the system I'm using doesn't support it.

I'm assuming there's no other way to solve this problem (without possibly using the Apache config), so I'm just allowing the index recursively (i.e. from /foo), then inside /foo 's .htaccess file:
Options +Indexes
RewriteEngine on
RewriteCond %{REQUEST_URI} ^/foo[/]?$
RewriteRule (.*) / [R=301,L]
To just redirect people to the homepage. Also put a meta refresh redirect in there just incase.

Related

How to make a subfolder unreachable and files undownloadable from root directory using htaccess?

I want to make a subfolder, named backups unreachable and files within it downloadable with the aid of .htaccess placed in the home directory. I don't want to create a secondary .htaccess file in the subfolder.
I did several rewrite and deny commands but no effect.
You can do the following with mod_rewrite at the top of the root .htaccess file to block (ie. 403 Forbidden) any requests to /backups or /backups/<anything>. For example:
RewriteEngine On
# Block any HTTP requests to "/backups" subdirectory
RewriteRule ^backups($|/) - [F]
Note that when used in .htaccess, the URL-path that then RewriteRule pattern matches against does not start with a slash.
Alternatively, use mod_authz_core inside an Apache expression to target just the /backups subdirectory. For example:
# Block any HTTP requests to "/backups" subdirectory
<If "%{REQUEST_URI} =~ m#^/backups($|/)#">
Require all denied
</If>

Htaccess caching system in subfolder not working

Sorry if this is a duplicate: I found many questions about caching system, but my problem seems to tied to the fact that the whole script is working within a subfolder.
All I need to do is implementing a simple caching system for my website, but I can't get this to work.
Here's my .htaccess file (widely commented to be clear - sorry if too many comments are confusing):
RewriteEngine on
# Map for lower-case conversion of some case-insensitive arguments:
RewriteMap lc int:tolower
# The script lives into this subfolder:
RewriteBase /mydir/
# IMAGES
# Checks if cached version exists...
RewriteCond cache/$1-$2-$3-{lc:$4}.$5 -f
# ...if yes, redirects to cached version...
RewriteRule ^(hello|world)\/image\/([a-zA-Z0-9\.\-_]+)\/([a-zA-Z0-9\.\-_]+)\/([a-zA-Z0-9\.\-_\s]+)\.(png|gif|jpeg?|jpg)$ cache/$1-$2-$3-{lc:$4}.$5 [L]
# ...if no, tries to generate content dynamically.
RewriteRule ^(hello|world)\/image\/([a-zA-Z0-9\.\-_]+)\/([a-zA-Z0-9\.\-_]+)\/([a-zA-Z0-9\.\-_\s]+)\.(png|gif|jpeg?|jpg)$ index.php?look=$1&action=image&size=$2&data=$3&name=$4&format=$5 [L,QSA]
# OTHER
# This is always non-cached.
RewriteRule ^(hello|world)\/([a-zA-Z0-9\.\-_\s]+)\/([a-zA-Z0-9\.\-_\s]+)?\/?$ index.php?look=$1&action=$2&name=$3 [QSA]
Now, the issue is that the RewriteCond seems to be always failing, as the served image is always generated by PHP. I also tried prepending a %{DOCUMENT_ROOT}, but is still not working. If I move the whole script to the root directory, it magically starts working.
What am I doing wrong?
Well one thing that you are doing wrong is trying to use a rewrite map in an .htaccess file. in the first place. According to the Apache documentation:
The RewriteMap directive may not be used in <Directory> sections or .htaccess files. You must declare the map in server or virtualhost context. You may use the map, once created, in your RewriteRule and RewriteCond directives in those scopes. You just can't declare it in those scopes.
If your ISP / sysadmin has already defined the lc map then you can use it. If not then you can only do case-sensitive file caching on Linux, because its FS naming is case sensitive. However, since these are internally generated images, just drop the case conversion and stick to lower case.
%{DOCUMENT_ROOT} may not be set correctly at time of mod_rewrite execution on some shared hosting configurations. See my Tips for debugging .htaccess rewrite rules for more hints. Also here is the equivalent lines from my blog's .htaccess FYI. The DR variable does work here, but didn't for my previous ISP, to I had to hard-code the parth
# For HTML cacheable blog URIs (a GET to a specific list, with no query params,
# guest user and the HTML cache file exists) then use it instead of executing PHP
RewriteCond %{HTTP_COOKIE} !blog_user
RewriteCond %{REQUEST_METHOD}%{QUERY_STRING} =GET [NC]
RewriteCond %{DOCUMENT_ROOT}html_cache/$1.html -f
RewriteRule ^(article-\d+|index|sitemap.xml|search-\w+|rss-[0-9a-z]*)$ \
html_cache/$1.html [L,E=END:1]
Note that I bypass the cache if the user is logged on or for posts and if any query parameters are set.
Footnote
Your match patterns are complicated because you are not using the syntax of regexps: use the \w and you don't need to escape . in [ ] or / . Also the jpeg isn't right is it? So why not:
RewriteRule ^(hello|world)/image/([.\w\-]+)/([.\w\-]+)/([\w\-]+\.(png|gif|jpe?g))$ \
cache/$1-$2-$3-$4 [L]
etc.. Or even (given that the file rule will only match for valid files in the cache)
RewriteRule ^(hello|world)/image/(.+?)/(.+?)/(.*?\.(png|gif|jpe?g))$ \
cache/$1-$2-$3-$4 [L]
The non-greedy modifier means that (.+?) is the same as ([^/]+) so doing hacks like ../../../../etc/passwd won't walk the file hierarchy.

Is it possible to wildcard a filename string to password protect a file with htaccess?

Example: wp_file*.log -- what that should do is to password protect every file whose filename start with wp_file and ends with .log -- for example wp_file-22.log and wp_file_randomfile.log.
Possible?
The way I would make this, is by adding a rewrite rule for those files, redirect to some PHP file with the origional request in the GET. The PHP file can than show a password box and eventually the content of the log file once logged in.
RewriteEngine On
RewriteRule wp_file(.*)\.log /somePHPfile.php?logFile=wp_file$1 [L]
(not tested)
If you dont need access to the log files via your website (but use e.g. ftp), than you can rewrite the requests to those files to another page
RewriteEngine On
RewriteRule wp_file(.*)\.log /index.php [L]

remove directory after main url using htaccess

With the following url http://www.example.com/de/here/ I want to remove the "de" directory (or whatever may be in front of the "here" directory, if anything even is in front of it) so a user is directed to http://www.example.com/here/ instead, which is a directory that does actually exist.
The url could even be something like http://www.example.com/it/here/ or any other combination of 2 letters.
The url could also just be http://www.example.com/here/ in which case I don't want anything removed at all.
I have searched for a solution here but cant seem to make anything work correctly so any help would be much appreciated.
You can use this kind of htaccess :
RewriteEngine On
RewriteBase /
RewriteRule ^[A-Za-z]{2}/(.*)$ $1 [L,R=301]
Example of redirections caused by this code :
http://www.example.com/de/foo/ => http://www.example.com/foo/
http://www.example.com/de/ => http://www.example.com/
http://www.example.com/it/bar/ => http://www.example.com/bar/
http://www.example.com/FR/baz/ => http://www.example.com/baz/
Please note you won't be able to access the language (de, it, fr...) anymore.
Another point, be careful with this kind of url (the redirection will be executed twice) :
http://www.example.com/de/go/ => http://www.example.com/go/
http://www.example.com/go/ => http://www.example.com/
EDIT
Now I've got more details, here is an htaccess you can you to remove the language for specified folders :
RewriteEngine On
RewriteBase /
RewriteRule ^[A-Za-z]{2}/here/(.*)$ here/$1 [L,R=301]
RewriteRule ^[A-Za-z]{2}/anotherfolder/(.*)$ anotherfolder/$1 [L,R=301]

Htaccess rewrite if address is subfolder?

I have the following URLs:
www.mydomain.com/client
www.mydomain.com/client/index.php
www.mydomain.com/client/index.php?a=b
www.mydomain.com/client/index.php?a=b&b=c
The following two htaccess files exist:
www.mydomain.com/.htaccess
www.mydomain.com/client/.htaccess
I want to edit "www.mydomain.com/client/.htaccess" so that if you go to www.mydomain.com/client, that it redirects the user to mydomain.com/client/clientarea.php. In other words, 1 and 2 must redirect to mydomain.com/client/clientarea.php, but 3 and 4 must not.
How do I do that?
Try this:
RewriteEngine on
RewriteBase /
RewriteRule ^client$ /clientarea.php [L]
RewriteRule ^client/index.php$ /clientarea.php [L]
htaccess files are parsed in the order they're discovered, so the top level one (mydomain.com/.htaccess) will be parsed and executed before Apache even considers looking down in the .../client sub-directory. As such, you'd have to modify your rewrite rule to check if the request contains a subdirectory, and NOT process it if one's found.

Resources