Apache RewriteRule on application hosted in subfolder leads to infinite loop - apache

I'm currently hosting a PHP application on Apache. This application is behind a CloudFront distribution that sends all requests with cms/* to my application.
I used the following .htaccess file and hoped to make things work:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /cms
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*) index.php [L]
</IfModule>
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE text/javascript
AddOutputFilterByType DEFLATE application/json
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript
</IfModule>
I get an Internal Server Error and in the Apache Error logs this can be found:
AH00124: Request exceeded the limit of 10 internal redirects due to probable configuration error.
What am I doing wrong?

My CMS is running in the document root of the Apache server.
If the CMS is in the document root then you should remove the RewriteBase /cms directive entirely.
The presence of RewriteBase /cms results in the request being internally rewritten to /cms/index.php (not /index.php) and if this file does not exist then you will naturally get a rewrite-loop (the preceding condition checks that the request does not map to a file or directory).
In other words (with some additional improvements):
DirectoryIndex index.php
RewriteEngine on
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]
DirectoryIndex is likely already set in the server config, although it is necessary here.
The first RewriteRule directive is an optimization to prevent unnecessary filesystem checks when the request is rewritten.
There is no need to traverse and capture the entire URL-path in the last RewriteRule directive (ie. ^(.*)). The regex . (a single dot) is sufficient, and more efficient.
No need for the <IfModule mod_rewrite.c> wrapper, unless these directives are optional.

I solved it the following way:
I put the application on the Apache server in a cms folder and kept the current .htaccess as is. It might also work with keeping it in the Apache root folder and setting the RewriteBase to something like ../ if that works with Apache but I'm happy with the current solution.

Related

Rewrite htaccess directory to behave as a external website

So I have one website, for example http://example.com/ and another one http://example.myeshop.com/. I want to make accessible URL http://example.com/eshop to be same as http://example.myeshop.com/, but no redirects. Also when someone use link like http://example.com/eshop/contact it would have same effect as http://example.myeshop.com/contact and so on. This is my .htaccess file:
IndexIgnore */*
RewriteEngine On
RewriteRule /eshop/(.*) http://example.myeshop.com/$1 [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/xhtml text/html text/plain text/xml text/javascript application/x-javascript text/css
</IfModule>
FileETag none
But doesn't seem to be working. Can you help me how to achieve such a thing?
What you are looking for is mod-proxy. Enable proxy module on your server and then you can use this :
RewriteEngine on
RewriteRule ^eshop/(.*)$ http://example.myeshop.com/$1 [P]
This will internally forword all requests of example.com to example.myeshop.com . You will get an internal server error if the proxy module isnt enabled.
If you have access to httpd.conf you can use below rules in your httpd.conf file where section for mod_proxy is mentioned or might be you have to put in extra/httpd-ajp.conf.
ProxyPass /eshop/ http://example.myeshop.com/
ProxyPassReverse /eshop/ http://example.myeshop.com/
These two lines should be uncommented in your httpd.conf file.
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so

CakePHP .htaccess settings and shared ssl certificate

My shared host offers shared SSl certificate like the following:
https://host###.HostMonster.com/~username
Where host### is the hosting server for my account there.
I use CakePHP app on the root of public_html where I have public_html/webroot path and I use the following .htaccess settings on public_html:
# Turn off the ETags
Header unset ETag
FileETag None
# Turn off the Last Modified header except for html docs
<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|mp3)$">
Header unset Last-Modified
</FilesMatch>
<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf|mp3)$">
Header set Expires "Thu, 15 Jan 2015 20:00:00 GMT"
</FilesMatch>
<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf|mp3)$">
Header set Cache-Control "max-age=31449600"
</FilesMatch>
# Use PHP5.3 as default
AddHandler application/x-httpd-php54 .php
Redirect /Hosting/Q/ http://sub.mydomain.net/
<IfModule mod_rewrite.c>
RewriteEngine on
#RewriteCond %{HTTPS} =on
#RewriteBase /~twoindex/
RewriteRule ^$ webroot/ [L]
RewriteRule (.*) webroot/$1 [L]
</IfModule>
AddType audio/mpeg mp3
AddType text/xml xml
When I try to access https://host15.HostMonster.com/~myuser where host15 is my host server, I got 404 error.
I tried the following:
Creating a simple html file and placing it on public_html and then accessing it using https://host15.HostMonster.com/~myuser/simple.html. It also returns 404 error.
I tried to comment out the two lines after RewriteEngine on but no success too.
Removing the contents of the .htaccess file i.e making it empty, allowed me to access simple.html via https successfully.
The last try, is not a real option for me because it will destroy my CakePHP application. However, it approved that it is a problem related with rewriting rules in the .htaccess. So, I need to know how to modify the .htaccess to allow accessing my CakePHP application while allowing accessing the simple.html or better a sub directory on public_html
Update
I tried the following rule, but it ended with the error This webpage has a redirect loop when I try to access https://host15.HostMonster.com/~myuser/folder and it keeps everything fine for the CakePHP application.:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_HOST} ^host15\.HostMonster\.com [NC]
RewriteRule ^(.*)$ /~myuser/$1 [R,L]
RewriteRule ^$ webroot/ [L]
RewriteRule (.*) webroot/$1 [L]
</IfModule>

Passenger Apache Rails 403 forbidden. 2 Urls pointing to the same app 1 works other doesnt

I have a strange problem where I have two separate urls pointing to the same Rails application
staging.abcxyz.com
staging.abcttt.com
My setup runs apache with passenger. The important thing to note here is that both urls point to the same Rails application in the Document Root directory and are just served by a different urls internally.
Problem
When i try to access staging.abcxyz.com it works and the application is rendered and everything works as expected.
When i try to access staging.abcttt.com apache returns a 403 forbidden.
Apache Config
This is apache configuration of the url that doesn't work for me. Its exactly the same as the one that works expect for changes in the urls.
&ltVirtualHost *:80&gt
ServerName staging.abcttt.com
ServerAlias www.staging.abcttt.com
DocumentRoot /srv/abcxyz/current/public/
&ltDirectory /srv/abcxyz/current/public/&gt
Order allow,deny
Allow from all
Options FollowSymLinks
AllowOverride None
&lt/Directory&gt
RewriteEngine on
RewriteRule ^/$ /s/home [P]
RailsAutoDetect On
RackEnv staging
RailsEnv staging
RailsSpawnMethod smart
## PassengerAppGroupName
#
# By default, Passenger groups applcations by the the path they are served out of,
# ie /srv/yourapp/current.
#
# At times, it may be useful be serving the same app from multiple vhosts, but have
# them be have different workers. For example, you may have a /ping URL that needs to
# respond quickly, without being affected by the rest of the app. In this case, you can:
#
# * create a new vhost pointing at the same app
# * set PassengerAppGroupName to ping
# * configure a proxy to forward /ping to the new vhost
PassengerAppGroupName abcxyz
# Deflate
&ltIfModule mod_deflate.c&gt
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css application/x-javascript application/javascript application/json
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
&lt/IfModule&gt
RequestHeader set X-Request-Start "%t"
RewriteEngine On
# Check for maintenance file and redirect all requests
ErrorDocument 503 /system/maintenance.html
RewriteCond %{REQUEST_URI} !\.(css|jpg|png|gif)$
RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f
RewriteCond %{SCRIPT_FILENAME} !maintenance.html
RewriteRule ^.*$ /system/maintenance.html [R=503,L]
# Rewrite index to check for static
RewriteCond %{THE_REQUEST} ^(GET|HEAD)
RewriteCond %{DOCUMENT_ROOT}/index.html -f
RewriteRule ^/?$ /index.html [QSA,L]
# Rewrite to check for Rails non-html cached pages (i.e. xml, json, atom, etc)
RewriteCond %{THE_REQUEST} ^(GET|HEAD)
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f
RewriteRule ^(.*)$ $1 [QSA,L]
# Rewrite to check for Rails cached html page
RewriteCond %{THE_REQUEST} ^(GET|HEAD)
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.html -f
RewriteRule ^(.*)$ $1.html [QSA,L]
&lt/VirtualHost&gt
Questions
I don't understand why this would be a permissions issue because staging.abcxyz.com can already access the folder. Am i missing something here since both are served from the same directory
Could it be something to do the with the PassengerAppGroupName - but i'm not particularly concerned about having a separate worker send respond to a particular request
I'd really appreciate any help on this. Thanks.
Update
A thing that i notice is if I use the R [redirect] flag instead of the P [proxy] the application works and redirects to the right url but i want to be an internal redirect which does not reflect on the browser.

Why I do I get 403 Forbidden when viewing files affected by Apache RewriteRule if I have `Options -FollowSymLinks`?

I wanted to serve .xhtml files as
application/xhtml+xml if the browser says that it accepts it.
text/html otherwise
Then, I had this code:
<Files "*.xhtml">
RewriteEngine on
RewriteCond %{HTTP:Accept} !application/xhtml\+xml
RewriteRule .* - [T=text/html]
</Files>
And it worked well.
The problem is that, after disabling FollowSymLinks (I don't use symbolic links), instead of the .xhtml file I get 403 Forbidden error.
Why? Is RewriteRule .* - [T=text/html] a symbolic link?

.htaccess for rewrite url affecting web-dev folder

Okay there is 2 questions,
First, I'm new with htaccess and have a lot of problem figure out how to make good Rewrited URL for google SEO so i've made this :
Options +FollowSymlinks
RewriteEngine on
### [... other language ...]
### English product URL
# Product page : (url/en/products/items-1.html)
RewriteRule ^([a-z]+)/[P-p]roducts/item-([0-9]+)\.html$ produits.php?lang=$1&art=$2 [L,NC]
# List of categories of a division (url/en/products/items-1-1.html)
RewriteRule ^([a-z]+)/[P-p]roducts/item-([0-9]+)-([0-9]+)\.html$ produits.php?lang=$1&idc=$2&catd=$3 [L,NC]
# List of subcategories of a categorie (url/en/products/items-1-1-1.html)
RewriteRule ^([a-z]+)/[P-p]roducts/item-([0-9]+)-([0-9]+)-([0-9]+)\.html$ produits.php?lang=$1&idc=$2&catd=$3&catt=$4 [L,NC]
# List of sub-sub-categories of a sub-categorie (url/en/products/items-1-1-1-1.html)
RewriteRule ^([a-z]+)/[P-p]roducts/item-([0-9]+)-([0-9]+)-([0-9]+)-([0-9]+)\.html$ produits.php?lang=$1&idc=$2&catd=$3&catt=$4&catq=$5 [L,NC]
### Mod Rewrite to make url more friendly EN
RewriteRule ^([a-z]+)/[B-b]ecome-a-[C-c]lient client.php?lang=$1 [L,NC]
RewriteRule ^([a-z]+)/[C-c]ontact-[U-u]s contact.php?lang=$1 [L,NC]
RewriteRule ^([a-z]+)/[O-o]ops erreur.php?lang=$1 [L,NC]
RewriteRule ^([a-z]+)/[I-i]ndustrial-[D-d]ivision industriel.php?lang=$1 [L,NC]
RewriteRule ^([a-z]+)/[C-c]art panier.php?lang=$1 [L,NC]
RewriteRule ^([a-z]+)/[S-s]earch recherche.php?lang=$1 [L,NC]
RewriteRule ^([a-z]+)/[H-h]ealt-[D-d]ivision sanitaire.php?lang=$1 [L,NC]
RewriteRule ^([a-z]+)/[H-h]ome index.php?lang=$1 [L,NC]
### Compression Mod
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/php
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript
## [... errors page ...]
The problem now is that if I would reach something for developpement purpose I can't do it
Exemple : I copy the whole website into a folder named work a the root of the domain so the url would be
www.website-url.com/work
at this point everything is fine I can access this part, but if I would access products.php I just can do it... I know that I can't reach it with the rewrite like www.website-url.com/work/products/items-1.html but I should be able to access it directly no ?
My second questions is that I would use compression for my server to make the website load more faster for client because I have a lot of javascipt working with jQuery a lot. But I can't make it work, I've checked with online tools and never pass compression test.
Thanks for your help !