Deny access to files inside folder but allow a REST API - .htaccess

I am using this .htaccess to simulate a folder full of files (a simple REST API):
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule files/(.*)$ api.php?file=$1 [QSA,NC,L]
Let's call this folder magicfolder where I am using this .htaccess file.
In fact, there is only api.php that is creating every file that is requested.
So, an url like mysite.com/magicfolder/files/image.jpg is converted into mysite.com/magicfolder/api.php?file=image.jpg.
This is great. But I want also to add some rules that makes any real file that exists in magicfolder (logs and even api.php) to be inaccessible for users.

With your shown samples, could you please try following. Please clear your browser cache before testing your URLs. Make sure your htaccess rules file is present inside magicfolder folder.
RewriteEngine On
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [F,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^files/(.*)/?$ api.php?file=$1 [QSA,NC,L]

Related

.htaccess: redirect if file doesn't exists

It is quite popular question, but there is some distinction in my case that makes all more difficult.
Apache2 web server, Yii2 framework with prettyUrl turned on.
Here is initial .htaccess file, provided by Yii2:
RewriteEngine on
# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# otherwise forward it to index.php
RewriteRule . index.php
There is /docs web directory. And I would like to get files from it if they are exist and redirect to /docs-generator/create?file=<file_name> if the file doesn't exists.
So, I have added a rule:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} ^/docs
RewriteRule ^docs/([\w-_.]+) http://kz_proj.test/docs-generator/create?file=$1 [L]
# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# otherwise forward it to index.php
RewriteRule . index.php
It's works but quite strange... First of all, I can't remove my test hostname from http://kz_proj.test/docs-generator/create?file=$1. It doesn't work without full name. The second one is about ^/docs and ^docs/([\w-_.]+) without the leading character. Why first part of these rules can't be the same in my case?
I guess something wrong with the rules...
You can use:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^docs/([\w-_.]+) /docs-generator/create?file=$1 [L,R=301]
# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# otherwise forward it to index.php
RewriteRule ^ index.php
It works with the domain name because it is necessarily a redirect in this case, but not without. I added [R=301] to force the redirection.
No need to add RewriteCond %{REQUEST_URI} ^/docs
because the test is the same with RewriteRule ^docs
And why first part of these rules can't be the same in your case ?
REQUEST_URI always start with a /
and RewriteRule test path never start with a / in .htaccess (why????)

Codeigniter htaccess for multiple applications

Hello guys can you help me how set proper url in codeigniter using multiple applications and i proper .htaccess
Folder Structure
-application
-api
-cms
-system
-api.php
-cms.php
Its works when a use this
http://localhost/kitkat_funs/cms.php/
http://localhost/kitkat_funs/api.php/
But i want this
http://localhost/kitkat_funs/cms/
http://localhost/kitkat_funs/api/
My htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
Please try following steps:
In config=>config.php, replace like following.
$config['index_page'] = 'index.php';
to
$config['index_page'] = '';
Please put following code into your .htaccess file, this might help you to achieve the result.
write your project folder name as rewritebase
RewriteBase /yourprojname/
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/system.*
RewriteRule ^(.*) index.php?/$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+) index.php?/$1 [L]
*take backup of your .htaccess file.
This problem appear when you working with Codeigniter using Multiple application(and multiple index_appname.php. Ofcourse you can add new line in .htaccess everytime you add another application but that is not convenience.
The solution is using basic Regular Expression. You need to write 2 section, one is for address without slash, and the other with more than one slash after index file
Note: in this case the index.php file has prefix "index_" following with app name
# If the user types without trailing slash example www.host.com/kitkat_funs/appname
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(\w*)$ index_$1\.php [L,QSA]
# If the user enter in any system section with slash example www.host.com/kitkat_funs/appname/page/etc
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)\/(.*)$ index_$2\.php/$1 [L,QSA]
Everytime user enter address right after domain name, for example www.host.com/kitkatname/cms
.htaccess will automatically redirect to www.host.com/kitkatname/cms.php
now you can get rid .php extension on your index file

Redirecting all requests from a subdirectory to a specific file

I wanted to redirect all requests from a specific subdirectory (/portfolio/*) to a specific file in the root of my website (portfolio.php). This way I want to be able to create project-specific pages within the same file as where the overview is being created.
I tried the following, but it didn't work since it stopped images from loading (images were located in the /images/portfolio/* directory), and it also disables my custom ErrorDocument...
RewriteRule /portfolio/(.*) /$1 [PT]
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /portfolio.php [L]
Anyone has an idea on how to fix this?
Try getting rid of the first rule and adding the pattern to your last rule:
RewriteRule ^portfolio.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^portfolio/(.+)$ /portfolio.php [L]
And for good measure, make sure multiviews is turned off:
Options -Multiviews

Redirect file type specific requests

In my app, I have the srcs of many images like this:
path/other-path/my-image.jpg
This can get long and can expose some of my file structure to the outside world.
What can I do in .htaccess to redirect a given file extension to a directory?
i.e. my image src is simply "my-image.jpg", .htaccess sees that is a .jpg file and redirects to the folder "www.site.com/my-jpgs/" were "my-image.jpg" resides, thus loading the image.
Here is what I have at the moment:
Options +FollowSymLinks
IndexIgnore */*
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/importers
RewriteCond %{REQUEST_URI} !\.(gif|jpg|png)$
RewriteRule ^(.*)$ public_html/index.php
RewriteBase /
# Ignore rule if the real path exists, use that instead.
RewriteCond %{REQUEST_FILENAME} !-f
# Only use the filename and extension.
RewriteRule (.[^/]*)\.(gif|jpg|png) public_html/images$1.$2 [R,L]
I've sort of got it working, except the browser makes two requests that look like this:
Request URL:http://www.view.com/activity/enquiry/dropdown-btn.gif
Request URL:http://www.view.com/public_html/images/dropdown-btn.gif
The second being correct, how do I correct this so it doesn't make the first incorrect request?
Ordering of rewrite rules is very important in .htaccess. Your problem is incorrect ordering of your rule. You need to move last rule to the top just belowRewriteEngine Online to have external redirect before sending everything off toindex.php`:
Options +FollowSymLinks
IndexIgnore */*
RewriteEngine On
RewriteBase /
# Ignore rule if the real path exists, use that instead.
RewriteCond %{REQUEST_FILENAME} !-f
# Only use the filename and extension.
RewriteRule ^(?:[^/]+/)*([^.]+\.(?:gif|jpe?g|png))$ images/$1 [R,L,NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/importers
RewriteCond %{REQUEST_URI} !\.(gif|jpe?g|png)$
RewriteRule ^ index.php [L]

Help in configuring .htaccess to exclude a path from rewriting

I have a root folder with the following .htaccess configuration
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# otherwise forward it to index.php
RewriteRule . index.php
What I need is, I have installed a wordpress site in a sub directory 'blog/'. Now I am able to access the home page of the blog since I have givien RewriteCond %{REQUEST_FILENAME} !-d. But clicking on a post will redirect me to the index file in root folder. How can I solve this. Please help. Thanks in advance.
Add a RewriteCond to exclude paths which begin with "blog/"
Something like (added some existant rule for context)
# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/?blog/
Not tested, but you get the idea

Resources