General .htaccess rewrite rules for multiple server directory configurations - apache

I have the following directory structure on my local development web server:
/www
/f3-app-1
/application
/config
/core
/resources
/ui
/index.php
/f3-app-2
...
/f3-app-3
...
I keep all of my web apps (f3-app-1, f3-app-2, ...) in sub-folders of the document root. I am accessing the app with http://localhost/f3-app-1/ and I am not using any virtual hosts.
I need to redirect everything (except for files in ui and resources) to index.php. To achieve this I am using something like the following in .htaccess file:
Options -Indexes
RewriteEngine On
RewriteCond %{REQUEST_URI} \.ini$
RewriteRule \.ini$ - [R=404]
RewriteCond %{REQUEST_URI} !^/f3-app-1/ui/
RewriteCond %{REQUEST_URI} !^/f3-app-1/resources/
RewriteRule .* index.php [L,QSA]
My hosting provider's production server is using virtual hosts to allow multiple websites. After transferring files to their web server I need to change the .htaccess file to something like:
...
RewriteCond %{REQUEST_URI} !^/ui/
RewriteCond %{REQUEST_URI} !^/resources/
RewriteRule .* index.php [L,QSA]
Is there any way to make these mod_rewrite rules to work relative to web application's or .htaccess directory?

You can make /f3-app-1 optional:
RewriteCond %{REQUEST_URI} !^(/f3-app-1)*/ui/
RewriteCond %{REQUEST_URI} !^(/f3-app-1)*/resources/
But this is bad practice.
The proper way to do it is to have virtual hosts on your development environment too. This will solve this, and any other issue related to paths in general.

Related

Apache 2.4 .htaccess - Point All Requests to index.html With One Exception

I currently have the following .htaccess:
<IfModule mod_rewrite.c>
Options Indexes FollowSymLinks
RewriteEngine On
RewriteBase /production/
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
</IfModule>
The web server's document root is currently the /production folder referenced in the above (the .htaccess file is in the parent folder since /production is deleted and rebuilt with every code commit). The above will direct all traffic to my site to index.html.
I would like to make an exception to this. If the request is www.mydomain.com/specialrequest, I would like a PHP script called script.php in the parent folder to run.
To review, this is my /var/www/html directory:
-html
-production
-anotherfolder
-.htaccess
-script.php
Apache is pointing to /var/www/html/production and I would like all requests to go to the index.html file in that directory unless the request is /specialrequest - in which case, I would like script.php to run.
Apache is pointing to /var/www/html/production
So, /var/www/html/production really is defined as the DocumentRoot. And so your .htaccess file is located above the document root. And the file you want to rewrite to (upon receiving this special request) is also above the document root.
Unfortunately, you can't rewrite to a file that is above the document root using .htaccess (regardless of where that .htaccess file is located). This is because the RewriteRule substitution in per-directory .htaccess files takes a URL-path, so trying to rewrite to a URL above the document root is simply invalid. If, however, you had access to the server config (or virtual host) then you could rewrite to a filesystem path (including above the document root) - instead of a URL-path - using this method.
So, script.php would need to be within the document root in order to be able to do this using .htaccess. In which case, you could do something like:
RewriteEngine On
# Exception
RewriteRule ^specialrequest$ /script.php [L]
# Front controller
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
But in this case, script.php is would need to be located at /html/production/script.php (in the document root), not at /html/script.php (above the document root) - as in your current filesystem structure.
Incidentally, the RewriteBase /production/ directive in your .htaccess file is entirely superfluous. You're not using a relative path substitution anyway, but since /production is the document root then /index.html (a document root relative URL-path) will rewrite to /production/index.html anyway.
If, however, you could write this directly in your server config (or virtual host), then you could do what you require. For example:
RewriteEngine On
# Rewrite to filesystem path (in the server config)
RewriteRule ^/specialrequest$ /var/www/html/script.php [L]
# Front controller
RewriteRule ^/index\.html$ - [L]
RewriteCond %{LA-U:REQUEST_FILENAME} !-f
RewriteCond %{LA-U:REQUEST_FILENAME} !-d
RewriteRule ^/. /index.html [L]

How to configure .htaccess for using Yii2 with Opencart in subfolder

I have an issue with proper configuration .htaccess file for Yii2 basic application.
I want to use Yii2 framework with Opencart store which a have installed to the /shop subfolder.
According to Yii2 server setup guide, I need to set /web directory as a DocumentRoot. But then my /shop directory (which is located in a root of Yii2 installation) becomes non web-accessible.
So I decided to break the rules and set my Yii-root as DocumentRoot and redirect all of the requests to the /web dir with assistance of Apache's mod_rewrite.
Please help me to create valid .htaccess file for Yii-root folder (in Opencart folder I've put it's default .htaccess file with just changing RewriteBase to /shop. It seems work properly)
I need something like this:
Lets assume I set DocumentRoot /var/www, then:
http://sitename.com => /var/www/web/index.php
http://sitename.com/any-non-file-request => /var/www/web/index.php
http://sitename.com/favicon.ico => /var/www/web/favicon.ico
http://sitename.com/shop => /var/www/shop
Works now. .htaccess file in /var/www (root of Yii2 installation)
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_URI} !^/web
RewriteRule ^(.*)$ web/$1 [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^web/(.*)$ web/index.php [L]

Incorrectly configured htaccess file that should direct to subdirectory

I've got a CMS installed in a sub-directory of my webspace and I'm having a little trouble figuring out how to configure the htaccess file.
mysite.com contains a splash page that should stay there for now. The idea is that mysite.com/dev should open the index page of the CMS. I suppose I could go with a subdomain but I'll have to research what to do in this case. Either way all of this is just temporary so whatever works is good.
You can see from the below code I've been messing around and I've commented out a lot of stuff. (I've also not bothered to copy more that I think is probably nonsense.)
#Display PHP Errors
php_flag display_errors Off
RewriteEngine On
RewriteBase /
#RewriteCond %{HTTP_HOST} .
#RewriteCond %{HTTP_HOST} !^www\.mysite\.com\dev [NC]
# For Friendly URLs
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /dev/index.php?q=$1 [L,QSA]
I should note that I'm with a hosting company any my root path is something like
/content/hosting/l/u/mysite.com/web
I've tried to add this (and truncated versions) to my htaccess file but without success.
If dev is your CMS and you want site/dev to open index.php in dev, your htaccess file for dev only needs this line:
DirectoryIndex index.php

www I added to HTTP_HOST via htaccess file disappears when redirecting to second htaccess file

I am struggling with an htaccess file. Actually, it is two files.
But first things first, so my questions are:
1) Why does my .htaccess(1) file add the www at the beginning of the HTTP_HOST and the slash at the end of folder REQUEST_URI IF AND ONLY IF the .htaccess(2) file is not there (deleted or renamed)?
2) What is wrong with the RewriteRule and conditions that I wrote in .htaccess(2) to redirect the REQUEST_URI to /publicfolder/REQUEST_URI? Conditions doesn't seem to work and when I surf to domain.com/nonpublicfolder it goes to domain.com/domainfolder/publicfolder/nonpublicfolder.
My website is structured as follows:
/
.htaccess(1)
domainfolder/
.htaccess(2)
publicfolder/
genericfolder/
index.extention
file.extention
nonpublicfolder/
So I have one htaccess file in the root folder ( .htaccess(1) ) where I:
add 'www' at the beginning of the HTTP_HOST;
add '/' at the end of REQUEST_URI if it does not end with a file extension;
redirect domain.com/anyfolder/anyfile.extention to domain.com/domainfolder/anyfolder/anyfile.extention;
like so:
<IfModule mod_rewrite.c>
# System symbolic links are allowed.
Options +FollowSymlinks
# Runtime rewriting engine enabled.
RewriteEngine On
# HTTP_HOST starts with 'www'.
RewriteCond %{HTTP_HOST} ^(?!www\.) [NC]
RewriteRule ^.*$ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,NC]
# Folder requests end with '/'.
RewriteCond %{REQUEST_URI} ![^/]+\.[a-zA-Z0-9]+$ [NC]
RewriteRule [^/]$ %{REQUEST_URI}/ [R=301,NC]
# Files and folders are in the 'domainfolder' folder.
RewriteCond %{REQUEST_URI} !^/?domainfolder/ [NC]
RewriteRule ^.*$ /domainfolder%{REQUEST_URI} [R=301,NC]
</IfModule>
And then I have my .htaccess(2) file - in the domainfolder folder - where I redirect files and folders requests to the publicfolder folder IF AND ONLY IF they are not pointing to the notpublicfolder folder or to the Google Site Verification file:
<IfModule mod_rewrite.c>
# Runtime rewriting engine enabled.
RewriteEngine On
# Public files and folders are in the 'publicfolder' folder.
RewriteCond %{REQUEST_URI} !^/?domainfolder/publicfolder/ [NC]
RewriteCond %{REQUEST_URI} !^/?domainfolder/nonpublicfolder/ [NC]
RewriteCond %{REQUEST_URI} !^/?domainfolder/googlexxx.html$ [NC]
RewriteRule ^/?(.+)$ /publicfolder/$1 [R=301,NC,L]
</IfModule>
Thank you very much for your time and patience.
(1) mod_rewrite does multiple passes and on each by default it will only open the first .htaccess file it finds walking up the folder hierarchy from the requested file. read my Tips for debugging .htaccess rewrite rules for more discussion of this. Yes you can use a Options setting to change this behaviour but this has a performance hit and I would suggest that you avoid doing so.
(2) When using hierachical .htaccess files, mod_rewrite has to associate URI path to the current directory and can get this wrong. The RewriteBase directive tells mod_rewrite what the true association is, so use this.
Rule order is important. If you don't have a local Apache instance where you have root privilege and can enable rewrite logging, you need to build up your access file(s) incrementally rule-by-rule, testing at each step because you only get a work/doesn't work return. Again my tips explains how to do this.

Pointing subdomains to a "directory"

I have two questions regarding pointing subdomains to a directory:
Currently I run local, but I can run my site on a fake domain i have set up (with hosts file), its called mysite.com. How can i (by server settings?) do so All subdomains will point to / ? Example anders.mysite.com should show mysite.com and asdassdd.mysite.com also.
Maybe 1. is not necessary, but how do i by htaccess point anders.mysite.com to mysite.com/anders ? Important notice is that should not redirect.
Why i thought of 1. is because I do not want to specify anywhere in the htaccess or any apache/domain setting, what the subdomain are, since this will be dynamic (created by logged in users in my webapplication)
Currently the users can use mysite.com/anders/ which is a URI they have created, and not a real directory. In the Kohana bootstrap I am then grabbing the URI and showing the relevant user page.
I am using Kohana MVC framework and have this in my htaccess:
# Turn on URL rewriting
RewriteEngine On
# Installation directory
RewriteBase /
# Protect hidden files from being viewed
<Files .*>
Order Deny,Allow
Deny From All
</Files>
# Protect application and system files from being viewed
RewriteRule ^(?:application|modules|system)\b.* index.php/$0 [L]
# Allow any files or directories that exist to be displayed directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Rewrite all other URLs to index.php/URL
RewriteRule .* index.php/$0 [PT]
Any help appreciated!
For 1, in your vhost just add a ServerAlias:
ServerAlias *.mysite.com
Then any subdomain (www included) will get pointed to the same document root.
If you want to put subdomains in their own directory (and since you have access to server config), you can use mod_vhost_alias and the VirtualDocumentRoot directive:
VirtualDocumentRoot /path/to/your/htdocs/%1
So if you request blah.mysite.com, you'll end up in /path/to/your/htdocs/blah as the doc root.
If it's a matter of you needing directory names of non-existent directories in the URI so that Kohana can route them, you'll need to make sure you have mod_proxy loaded:
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} ^([^.]+)\.
RewriteCond %{REQUEST_URI} !^/%1/
RewriteRule ^(.*)$ /%1/$1 [L,P]
To proxy the request back to Kohana with the right URI.
how do i by htaccess point anders.mysite.com to mysite.com/anders ? Important notice is that should not redirect.
You can use this rule:
RewriteCond %{HTTP_HOST}:%{REQUEST_URI} ^([^.]+)\.[^:]+:(?!/\1/).*$
RewriteRule ^ /%1%{REQUEST_URI} [L]