mod_rewrite to remove index.php from Codeigniter in subdirectory - apache

Codeigniter applications commonly use mod_rewrite to exclude the string index.php from the url. I have two Codeigniter applications within the same domain. One Codigniter application is in the web root folder, another Codigniter application is in a subfolder of the web root folder.
Codeigniter application 1:
http://domain.com/index.php
Codeigniter application 2 (the landing page application):
http://domain.com/land/index.php
The two Codeigniter applications are each atomic and do not share any files between them. Every file in the Codeigniter framework is in public_html/ and again in public_html/land/. So I need to exclude the string index.php in urls addressing the root / folder and also exclude the string index.php in the /land/ subfolder.
The .htaccess file in the root folder uses the widely recommended mod_rewrite rules (code below) from the Codeigniter wiki, and this set of rules works well for the root Codeigniter application (application 1). These rules reside in web root folder.
<IfModule mod_rewrite.c>
RewriteEngine On
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
#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
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]
</IfModule>
<IfModule !mod_rewrite.c>
# If we don't have mod_rewrite installed, all 404's
# can be sent to index.php, and everything works as normal.
ErrorDocument 404 /index.php
</IfModule>
The above set of rules has no problem removing index.php from the urls in the root Codeigniter application. But this set of rules does not seem to allow the mod_rewrite rules in public_html/land/.htaccess to execute.
When I remove the mod_rewrite rules in public_html/.htaccess, then the mod_rewrite rules in public_html/land/.htaccess start being evaluated.
Is there a way to change the mod_rewrite rules in public_html/.htaccess to handle the special case of a url intended to access the /land/ subfolder?
I think the best solution might be to change the mod_rewrite rules in public_html/.htaccess to allow the mod_rewrite rules in public_html/land/.htaccess to execute when the subfolder is addressed in the url. I am open to any suggestions.
Pre-emptive answer to the question "why don't you just use a subdomain?" 1. Saving money on the SSL certificate. 2) Non-techical users are sometimes confused by subdomains for marketing the base domain name.
Pre-emptive answer to "why don't you combine the Codeigniter applications to use the same files in the framework?" Duplicating the framework files is an easy way to keep the versioning repositories separated.

The problem is the rules in public_html/.htaccess are rewriting the URL's going to /land/, you need a passthrough which makes it so nothing happens when /land/ is requested.Add:
RewriteRule ^land/ - [L]
before the rest of your rules.

Add a rule at the top to just go to the land subfolder if it's part of the request string. That way, the rules in /land/.htaccess will be executed instead of the subsequent rules in /.htaccess. So put this at the top:
RewriteRule ^land.*$ - [NC,L]
This will check if the request begins with 'land' and redirect it to the subdirectory, where .htaccess rules corresponding to that subdirectory will be applied instead.
The reason the existing rule checking for files and folders and not doing the rewrite if the request corresponds to one of them is because whatever follows 'land' in the request is probably not a real file, and so the rewrite rule fires.

Related

htaccess don't protect folders, accessed from central index.php

I have this structure, where 'param' determines which folder must access to:
index.php?param
./folder1/ (index.php + .htaccess)
./folder2/ (index.php + .htaccess)
...
Where index.php do: ...require(key($_GET)."/index.php")...
Every folder have an .htaccess that require authentication by different user names. The problem is, when I authenticate for first time to one of them, then allow me to access to the other folders without their specific authentication. Why?
PD: I have my motivations for do "require(key($_GET)."/index.php")" instead of simply do "/folder1".
If you use require then PHP is loading the index.php file and HTTP Auth isn't enforced (assuming your auth is in the htaccess files). Instead of using require, you can route the request using mod_rewrite. So in the htaccess of your root directory:
RewriteEngine On
RewriteCond %{QUERY_STRING} !^$
RewriteCond %{DOCUMENT_ROOT}/%{QUERY_STRING}/index.php -f
RewriteRule ^index\.php$ /%{QUERY_STRING}/index.php [L]

htaccess force redirect based on cookie not working for sub-directories

I have a folder for one of my domains /site. Here I have a .htaccess file with:
rewriteengine on
rewritebase /
rewritecond %{HTTP_COOKIE} !allow=asdx
rewriterule ^.*$ .set-cookie.php
Basicly I want to redirect all requests that do not have the allow cookie set to "asdx" to another file.
The problem is that I have folders like /site/subdomain1 that have .htaccess files of their own (with rewriteengine on). Accessing one of these files renders the initial redirect (based on the cookie) useless. If I disable the rewriteengine on directive from the sub-folders the cookie-based redirect works again.
How can I make the cookie-based redirect work without actually going to the individual subfolders and adding it there?
use the following for the rewrite rule:
rewriterule ^.*$ .set-cookie.php [R=302,L]

Apache index.php redirect for base and sub directory

I am looking to run WordPress and Magento on the same domain. Wordpress is installed at the root of the site and Magento would be installed at /store/.
I have had the Apache config setup for WordPress (having all requests redirect to index.php), what Apache configuration logic do I need for all requests to /store/* to goto /store/index.php ?
You should be able to simply keep the default Magento .htaccess file in the store directory along with the other Magento files, then exclude anything with that path from your wordpress rewrites. I'm not up to date on what wordpress .htaccess files may look like, but it should simply be a case of adding a RewriteCond.
I would guess that the rewrite for wordpress will look something along the lines of...
RewriteCond %{REQUEST_URI} !-f
RewriteCond %{REQUEST_URI} !-d
RewriteRule (.*) /index.php?$1 [QSA,L]
If this is the case simply add another RewriteCond should do the trick...
RewriteCond %{REQUEST_URI !^store/
Posting the Wordpress .htaccess file may lead to more accurate advice.

Why is my .htaccess file redirecting to full server path instead of relative path?

I've never had a problem with cakePHP before, but something's odd about this server and is causing the redirects in the .htaccess files to behave oddly.
CakePHP uses mod_rewrite in .htaccess files to redirect requests to its own webroot folder. The problem is that the redirects are listing the wrong path and causing a 404 error. My CakePHP application, which is stored in the listings directory, has a .htaccess file as follows:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^$ app/webroot/ [R=301,L]
RewriteRule (.*) app/webroot/$1 [R=301,L]
</IfModule>
(*note that the R=301 causes an external redirect so we can see what is going on from our end. It should really omit this flag and do the redirect internally, transparent to end-users)
This is supposed to redirect any request from http://hostname.com/~username/listings/ to http://hostname.com/~username/listings/app/webroot/
However, rather than simply adding “app/webroot/” to the end as it is supposed to, it is adding the full server path ( /home/username/public_html/listings/app/webroot/ ) resulting in the final URL http://hostname.com/home/username/public_html/listings/app/webroot/ which is obviously incorrect and triggers a 404 error.
The hosting is on a shared hosting account, so that limits what I can do with the settings. I've never seen this happen before, and I'm thinking it's something wrong from the hosting side of things, but if anyone has some helpful suggestions then I can put them to the hosting company as well.
The solution to your question can be found towards the bottom of this page in the cakephp book:
For many hosting services (GoDaddy, 1and1), your web server is actually being served from a user directory that already uses mod_rewrite. If you are installing CakePHP into a user directory (http://example.com/~username/cakephp/), or any other URL structure that already utilizes mod_rewrite, you'll need to add RewriteBase statements to the .htaccess files CakePHP uses (/.htaccess, /app/.htaccess, /app/webroot/.htaccess).
I've deployed CakePHP from my profile's public_html folder as well. I had to change 3 the same .htaccess files mentioned above. Just add RewriteBase /~username/ to the .htaccess files just after RewriteEngine on!
Try removing .htaccess from main file... It worked for me
It was quite simple (using uolhost shared host):
Edit both .htaccess files:
/webroot/.htaccess
/.htaccess
Add the following line:
RewriteBase /
Here is the whole /webroot/.htaccess file:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]

.htaccess mod_rewrite issue

Almost in any project I work on, some issues with .htaccess occur. I usually just find the easiest solution and leave it because I don't have any knowledge or understanding for Apache, servers etc. But this time I thought I would ask you guys.
This is the files and folders in my (simplified) setup:
/modrewrite-test
.htaccess
/config
/inc
/lib
/public_html
.htaccess
/cms
/navigation
index.php
edit.php
/pages
index.php
edit.php
login.php
page.php
The "config", "inc" and "lib" folders are meant to be "hidden" from the root of the website. I try to accomplish this by making a .htaccess-file in the root that redirects the user to "public_html". The .htacess-file contains this:
RewriteEngine On
RewriteRule (.*) public_html/$1
This works perfect. If I type "http://localhost/modrewrite-test/login.php" in my browser, I end up in public_html/login.php which is my intention. So this works fine. The .htaccess-file in "public_html" contains this:
RewriteEngine On
# Root
RewriteRule ^$ page.php [L]
# Login
RewriteRule ^(admin)|(login)\/?$ login.php [L]
# Page (if not a file/directory)
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ page.php?url=$1 [L]
The first rewrite just redirects me to public_html/page.php if I try to reach "http://localhost/modrewrite-test/". The next rewrite is just for the convenience of users trying to log in - so if they try to reach "http://localhost/modrewrite-test/admin" or "http://localhost/modrewrite-test/login" they will end up at the login.php-file. The third and last rewrite handles the rest of the requests. If I try to reach "http://localhost/modrewrite-test/bla/bla/bla" it will just redirect me to public_html/page.php (with the 'url' GET-variable set) instead of finding a folder called "la", containing a folder named "bla" and etc.
All of these things work perfect but a minor issues occurs when I for instance try to reach "http://localhost/modrewrite-test/cms/navigation" without a slash at the end of the URL. When I try to reach that page the browser is somehow redirected to "http://localhost/modrewrite-test/public_html/cms/navigation/". The correct page is shown but why does it get redirected and add the "public_html" part in the URL? The desired behavior is that the URL stays intact and that the page public_html/cms/navigation/index.php is shown.
The files and folders in the (simplified) can be found at http://highbars.com/modrewrite-test.zip
I ran into the same problem with "strange" redirects when trying to access existing directory without slash at end. In my case this redirection was done by mod_dir Apache module. To disable redirection I used DirectorySlash directive. Try putting in .htaccess files following string:
DirectorySlash Off
RewriteBase may help. Try this in public_html/.htaccess:
RewriteEngine On
RewriteBase /
Add the following to /modrewrite-test/.htaccess:
RewriteBase /modrewrite-test
Just to be on the safe side, I'd add the same rule also to /modrewrite-test/public_html/.htaccess. I found that having RewriteBase always set prevents a lot of potential problems in the future. This however means that you might need to update the values if you change the URI structure of your site.
Update:
I don't think that this is possible with your current folder structure. I believe that the problem is that existing subdirectories prevent rewrite rules from firing. Note the behavior please - everything works fine while you are working with non-existent files and directories, thanks to these two conditions:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
However if you try to open any index file from an existing subdirectory, you get redirected to .../public_html/.... Since you can properly open /modrewrite-test/cms/navigation/edit.php, I can only assume that the request is being overwritten by some Apache core directive, which adds slashes at end of folder URLs. Notice that everything works fine if you have an ending-slash at each URL (i.e. the Apache core directory does not need to "correct" your URL, thus everything gets rewritten by your own rewrite rules).
Suggested solution (unless anyone can advise better):
Change /modrewrite-test/public_html/.htaccess as follows:
RewriteEngine On
RewriteBase /modrewrite-test
# Page (if not a file/directory)
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ page.php?url=$1 [L]
Then Remove all PHP files from subfolders and use the Front Controller pattern, i.e. route all requests through your main page.php file and do not delegate anything down below.
You can then use the Factory pattern to initiate individual UIs (i.e. navigation/edit.php) directly from your main page.php file based on contents of $_GET['url'] (make sure to properly sanitize that).
Update #2:
This other post on StackOverflow advises on project structure used by Zend Framework - it essentially shows the approach which I suggested above. It is a valuable information asset regardless if you use Zend Framework or not.