CakePHP [.htaccess], static files as the root of project - .htaccess

I would like to be able to access static files at the root of my project, in a folder at the same level of app/. It's because that is the only directory to wich I have the permission to read-write files on my server, so our images are uploaded there.
So if someone writes this URL:
www.mysite.com/img-rw
It displays images in the folder at [project-root]/my-rw-dir
Any ideas on how to edit .htaccess files for something like this to be done?
Thanks

Taking into account that this is a course project (as the OP said in comments) and you are NOT concerned about security flaws, here is what you could do.
By default CakePHP has 3 nested .htaccess files:
/.htaccess (Project root folder)
/app/.htaccess
/app/webroot/.htaccess
The first (topmost) of them is the first to respond when you try to access www.mysite.com:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^$ app/webroot/ [L]
RewriteRule (.*) app/webroot/$1 [L]
</IfModule>
Clearly, this sends the user request right into the /app/webroot folder. We could use the conditional check that exists in /app/webroot/.htacess to, instead of promptly redirecting to webroot, check if the given URL matches to a file or folder. In order to do so, you'll need to update the parent (/.htaccess) file:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d # Checks if the given URL matches to a folder
RewriteCond %{REQUEST_FILENAME} !-f # Checks if the given URL matches to a file
#RewriteRule ^$ app/webroot/ [L] # This line is commented, should be removed
RewriteRule (.*) app/webroot/$1 [L]
</IfModule>
This way, the request will only be redirected to /app/webroot if none of the conditions are met. If you need only to return files, than you could remove RewriteCond %{REQUEST_FILENAME} !-d, which verifies if the URL matches to a folder ( -d = directory).
A cleaner version that would only check for files should look like this:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) app/webroot/$1 [L]
</IfModule>
With this tweak, accessing www.mysite.com/image.jpg should return the file image.jpg hosted at your project root (/image.jpg).

For anyone wondering, this works great :
.htaccess (project root)
<IfModule mod_rewrite.c>
RewriteEngine on
# This folder is a subfolder of project root but contains static images
# Accessed like so: www.mysite.com/imgrw/[file name]
RewriteRule ^imgrw/(.*)$ /dir-at-root-level/img/$1 [L]
# Everything else is handled by cakephp webroot
RewriteCond %{REQUEST_URI} !(dir-at-root-level) [NC]
RewriteRule ^(.*) app/webroot/$1 [L]
</IfModule>

Related

How do i use htaccess rules to rewrite to a certain file?

I have to create a page handler, which should read the URL, and do specific operations based on querystring.
I'd need to use .htaccess to do some URL rewriting thing to point everything at a certain file which does the processing, in such a fashion:
https://example.com/folder/page1/
https://example.com/folder/page2/
And the processing file is https://example.com/folder/index.php
Is there any way to do that (possibly by removing the index.php part)?
try this out and see if this helps you achieve what you are looking for.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /folder/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]
</IfModule>
The above code is taken for reference from WordPress and it should work when the "RewriteBase /folder/" folder name is updated with your folder and .htaccess file has to be placed in the root/folder directory where your index.php file is located.

How do you redirect all request to public/ folder in laravel 5

I have a classic Larevel 5 project structure and I need to redirect all requests to public/.
I am on a classic hosting environment so public/ is a subfolder of my document root.
I shall imagine it can be done via .htaccess but I still need to figure out how. Anyone can help?
Thanks
There are two solutions:
1. Using .htaccess with mod_rewrite
RewriteEngine on
RewriteCond %{REQUEST_URI} !^public
RewriteRule ^(.*)$ public/$1 [L]
2. You can add a index.php file containing the following code and put it under your root Laravel folder (public_html folder).
<?php
header('Location: public/');
You don't need to change anything in Laravel's default public/.htaccess file.
Just create a new .htaccess in the same level your public folder and add the following content to it:
DirectoryIndex index.php
RewriteEngine On
RewriteRule ^$ public/index.php [L]
RewriteRule ^((?!public/).*)$ public/$1 [L,NC]
That simple!
This is an extract from another answer which may also help you.
--
Modify your public_html/.htaccess to redirect all requests to the public subfolder.
# public_html/.htaccess
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
# Redirect All Requests To The Subfolder
RewriteRule ^ /public
</IfModule>
Make sure you have the proper public_html/public/.htaccess (GitHub).
# public_html/public/.htaccess
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
# Handle Authorization Header
RewriteCond %{HTTP:Authorization}
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
</IfModule>
If you use cPanel, then:
1.Go to folder:
/var/cpanel/userdata/my_domain
2.Edit the both domains:
my.domain and my.domain_SSL
Add to the documentroot section /public:
documentroot: /home/user/public_html/public
3.Rebuild Apache config:
/scripts/rebuildhttpdconf && service httpd restart
if you using apache , add .htaccess file to your root directory with this lines :
RewriteEngine on
RewriteCond %{REQUEST_URI} !^public
RewriteRule ^(.*)$ public/$1 [L]
and make sure your apache redirect and rewrite modules is working fine .
you can use vhost to redirect the all request to your public directory with set public as root of your project .
The ideal scenario is to have /home/user/public as a symlink from /home/user/laravel/public.

Multiple Rewrite Rules, Try A then B

I have the following directory structure:
root
--/inc
--/img
--/docs
---/public
----/contact
-----/img
------telephone.jpg
-----contact.php
---/private
My aim is to make each folder under 'docs' a 'contained' webpage. Each folder will have it's own /img/ folder, and a /bin/ folder too, which could contain anything from Mp3s to PDFs.
Currently I am routing everything through to index.php, and then manually redirecting the file from there. But this is proving to be very slow. What I was thinking would be faster would be something like this in my .htaccess if say, an image was trying to be accessed via /contact/telephone.png:
try /img/{url_path}
Otherwise, try /docs/$1/img/$2
Otherwise route through index.php
How could I go about doing this? Currently my .htaccess is as follows:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
# if file not exists
RewriteCond %{REQUEST_FILENAME} !-f
# if dir not exists
RewriteCond %{REQUEST_FILENAME} !-d
# avoid 404s of missing assets in our script
#RewriteCond %{REQUEST_URI} !^.*\.(jpe?g|png|gif|css|js)$ [NC]
RewriteRule .* index.php [QSA,L]
</IfModule>
Any help appreciated! Thanks
You can do something like this in your DOCUMENT_ROOT/.htaccess file:
RewriteEngine On
# check if this image path exists in docs/<folder>/img first
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}/docs/$1/img/$2 -f
RewriteRule ^([^/]+)/(.+?)/?$ /docs/$1/img/$2 [L]

Exclude a root folder from CakePHP app

I am trying to exclude a first level directory from Cake (root folder app), as it should hold a different app.
/ holds the app
/development/ holds the tested version of the app
The directory structure:
Public folder
.htaccess [modified]
app
.htaccess [unmodified]
webroot
.htaccess [unmodified]
index.php [unmodified]
...
...
lib
Cake
...
development
app
webroot
index.php [dumps $_SERVER for test purposes]
So, my development structure still doesn't have an app inside (nor .htaccesses), just to test if my root .htaccess works.
This is my modification of the root .htaccess:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_URI} ^/development.*
RewriteRule (.*) - [L]
RewriteRule ^$ app/webroot/ [L]
RewriteRule (.*) app/webroot/$1 [L]
</IfModule>
What happens:
/development/ shows the apache index of development folder
/development/app/ shows the apache index of app folder
/development/app/webroot shows the root app (request is captured in spite of the development url match).
/development/app/webroot SHOULD show me my /development/app/webroot/index.php file, right?
What the hell am I missing here?
This turned out to be an oddball bug on my server.
The resulting .htaccess which works now is:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_URI} !^/development(?:$|/)
RewriteRule ^$ app/webroot/ [L]
RewriteCond %{REQUEST_URI} !^/development(?:$|/)
RewriteRule (.*) app/webroot/$1 [L]
</IfModule>
For reasons unknown to me, if I SSH'd to my user account and edited the .htaccess files through the command line, it wouldn't work!
When I uploaded the same files (via SFTP), it started working properly.
I am using cPanel (11.34.1) on CentOS (5.9).
Another example: if you wish to "ignore" multiple sub-folders on a CakePHP installation, you can use this pattern:
<IfModule mod_rewrite.c>
RewriteEngine on
# /development, /version1.5 and /version1.8 directories
# they all hold independent apps
# or completely non-cake-related content
RewriteCond %{REQUEST_URI} !^/(?:development|version1\.5|version1\.8)(?:$|/)
RewriteRule ^$ app/webroot/ [L]
RewriteCond %{REQUEST_URI} !^/(?:development|version1\.5|version1\.8)(?:$|/.*)
RewriteRule (.*) app/webroot/$1 [L]
</IfModule>
Note that both RewriteCond instructions are identical.

.htaccess Rewrite direct file access

I have been looking all over and I can't find a solution that works for me.
I'm trying to redirect http://example.com/files/file.ext -> http://example.com/users/documents/file.ext
No matter what I try when I got directly to the file it downloads it. The GET request for the file doesn't show in any of my apache logs either. I have logging on debug.
[Edit]
The files I'm trying to download are of various types including ppt, pdf, xls, zip, doc, etc. I want to rewrite the filename to the end of the new URI. I am also using CodeIgniter so /users/documents/ is a RESTy uri.
Anyone have a fix?
Here is my .htaccess file:
<IfModule mod_rewrite.c>
RewriteEngine On
Options +FollowSymLinks
RewriteBase /
#Removes access to the system folder by users.
#Additionally this will allow you to create a System.php controller,
#previously this would not have been possible.
#'system' can be replaced if you have renamed your system folder.
RewriteCond %{REQUEST_URI} ^system.*
RewriteRule ^(.*)$ /index.php?/$1 [L]
#When your application folder isn't in the system folder
#This snippet prevents user access to the application folder
#Submitted by: Fabdrol
#Rename 'application' to your applications folder name.
RewriteCond %{REQUEST_URI} ^application.*
RewriteRule ^(.*)$ /index.php?/$1 [L]
#Checks to see if the user is attempting to access a valid file,
#such as an image or css document, if this isn't true it sends the
#request to index.php
<IfModule mod_php5.c>
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [N]
RewriteCond %{REQUEST_URI} ^/files/ [NC]
RewriteRule ^/files/(.*)$ /users/documents/$1 [L,R=301]
</IfModule>
<IfModule !mod_php5.c>
RewriteRule ^(.*)$ index.php?/$1 [L]
</IfModule>
</IfModule>
If this is in your htaccess file, try replacing this line:
RewriteRule ^/files/(.*)$ /users/documents/$1 [L,R=301]
with:
RewriteRule ^/?files/(.*)$ /users/documents/$1 [L,R=301]
And putting the condition and rule before any of the index.php routing rules.
I went to http://martinmelin.se/rewrite-rule-tester/ and tested my rewrite rules.
It said the RewriteCond wasn't matching anything, but when I remove the rule it matches.
Working Rule:
RewriteRule ^/?files/(.*)$ /users/documents/$1 [L,R=301]
Moving this to the top of the htaccess file fixes the issue.

Resources