Htaccess rewrite with %REQUEST_FILENAME condition - apache

I stucked. I need to:
all request with domain.com/api/... rewrite to public/ directory
all others request rewrite to frontend/index.html
but if request is a file, then rewrite just to 'frontent/'
I had two htaccess files:
.htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/api/ [NC]
RewriteRule ^(.*)$ public/$1 [L]
RewriteRule ^(.*)$ frontend/$1 [L]
</IfModule>
frontend/.htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
# Send Requests To Front...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [L]
</IfModule>
It was working but now I need to remove the one from frontend directory without loosing it's rules. I changed the main .htaccess:
<IfModule mod_rewrite.c>
RewriteEngine On
# Send request to backend
RewriteCond %{REQUEST_URI} ^/api/ [NC]
RewriteRule ^(.*)$ public/$1 [L]
# Send request to frontend
RewriteCond frontend/%{REQUEST_FILENAME} !-d
RewriteCond frontend/%{REQUEST_FILENAME} !-f
RewriteRule ^ frontend/index.html [L]
# Request for file
RewriteRule ^(.*)$ frontend/$1
</IfModule>
But it doesn't work. I think that this conditions are wrong:
RewriteCond frontend/%{REQUEST_FILENAME} !-d
RewriteCond frontend/%{REQUEST_FILENAME} !-f
because all request (others than api) are rewrited to frontend/index.html which i mentioned.
Could anybody show me where did I mistake?

Related

ERR_TOO_MANY_REDIRECTS after updating .htaccess rules

I'm getting an ERR_TOO_MANY_REDIRECTS error on my website. I have set up a .htaccess file on my Apache server containing the following:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule (.*) index.html [L]
RewriteRule ^index\.html$ - [L]
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R=301]
</IfModule>
This is cobbled together from two sources: Ember.js' routing tutorial and a guide to forcing HTTPS.
There must be some kind of redirect loop somewhere here, but I am unable to determine where it's coming from.
Update: I was able to get it working using the following.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.html [L]
RewriteRule ^index\.html$ - [L]
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>

htaccess redirecting all urls except one to a different domain not working

I'm trying to redirect all urls except http://shop.mysite.com/enquiry/ to a different domain like below but it's redirecting everything to "example.com", including the "enquiry" page.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !^/enquiry/
RewriteRule .* https://www.example.com [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}/index.html !-f
RewriteCond %{REQUEST_FILENAME}/index.php !-f
RewriteRule ^(.*)$ index.php
</IfModule>
So how do I make sure "enquiry" isn't redirected?
Your final RewriteRule for index.php is probably causing an additional redirect to occur in the PHP script.
You could try moving the redirect below this rule:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}/index.html !-f
RewriteCond %{REQUEST_FILENAME}/index.php !-f
RewriteRule ^(.*)$ index.php
RewriteCond %{REQUEST_URI} !^/enquiry/?
RewriteRule .* https://www.example.com [R=301,L]
</IfModule>
In addition, you will need to add some more rewrite conditions to exclude referenced scripts/stylesheets from being redirected too.
For a negative condition, you should THE_REQUEST variable instead of REQUEST_URI:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} !/enquiry[?\s/] [NC]
RewriteRule ^ https://www.example.com [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}/index.html !-f
RewriteCond %{REQUEST_FILENAME}/index.php !-f
RewriteRule ^ index.php [L]
</IfModule>
THE_REQUEST variable represents original request received by Apache from your browser and it doesn't get overwritten after execution of some rewrite rules. Example value of this variable is GET /index.php?id=123 HTTP/1.1
Make sure to clear your browser cache or use a new browser when testing.

http url added to the https url when viewed

I have a strange problem. When I open my domain in SSL mode , the http url get appended to it.
This is my http url
This is my SSL url
** other url for https are opening normally , although CSS and images are not loaded. eg Login page
I am clueless whats going on. Please help
Edit : This is my .htaccess
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
RewriteCond %{HTTPS} on
RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI}
# 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>
Try this
# Force https
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Edit:
Below is my live server setting working with laravel 5.2.
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
# Force https
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Force Non-www
RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
# 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>

htaccess RewriteRule rewrite to subfolder

I am trying to rewrite the url 'test' to a subdirectory in /public. This is a Laravel App end I want to run the content in public/test independend of Laravel so I should be prevented to go through the Laravel router.
/test/whatever should be invisbly forwarded to /public/test/whatever (The url should stay /test/whatever).
I now have this:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/test/ [NC]
RewriteRule ^(.*)$ public/test/$1 [L]
RewriteRule ^(.*)$ public/$1 [L]
</IfModule>
So far this is forwarding to: /public/test/test/(index.php)
I think I am close...
Update:
In the public directory is also a .htaccess file (Original, from Laravel 5.4):
<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>
You only need the last rule
RewriteRule ^(.*)$ public/$1 [L]
for the root dir .htaccess file. This will rewrite everything to the public/.htaccess, including requests starting with /test.
As long as public/test/ is a directory, and any requested URLs starting with /test/ are real files inside public/test, this will be sufficient, because the conditions
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
will prevent existing files and directories to be handled by index.php.
If test is not an existing directory, or the requests for /test/... are not real files, you need additional rules. Possibly in /public/.htaccess or in /public/test/.htaccess.
The reason for /test being rewritten to /public/test/test was the combination of
# /.htaccess
RewriteRule ^(.*)$ public/test/$1 [L]
where (.*) already includes test, which becomes public/test/test, and then
# /public/.htaccess
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
because public/test/test is not an existing file or directory (-> RewriteCond), and is therefore handled by this rule.

simple Apache RewriteCond and RewriteRule issue

I'm trying to follow https://github.com/crwilliams/diary-user-interface/wiki/cachebusting
If I set my HTML code to:
href="/myDir/myFile.2013103000.html"
and add to .htaccess:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)\.(\d+)\.(html)$ $1.$3 [L]
</IfModule>
I see "Page not found" error as the browser goes to: https://www.mycompany.com/myDir/myFile.2013103000.html
Any idea what could be happening?
What can I do to trouble shoot?
Sitting at the webpage with the link, if I change .htaccess to this:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^(.+) https://www.mycompany.com/myDir/myFile.html [L]
</IfModule>
and then click the link it works (but obviously this just for troubleshooting).
UPDATE
Here's the complete .htaccess file in case something following the above can be identified as the problem:
# attempt to implement version control with cachebusting
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)\.(\d+)\.(html)$ $1.$3 [L]
</IfModule>
# Pruning irrelevant parts (Phil)
# force SSL and www
RewriteCond %{HTTP_HOST} ^mycompany\.com$ [OR]
RewriteCond %{HTTPS} !on
RewriteRule ^(.*)$ https://www.mycompany.com/$1 [R=301,L]
# Redirect index.html to a specific subfolder;
Redirect permanent /index.html https://www.mycompany.com/home/
# enable pretty url
<IfModule mod_rewrite.c>
RewriteBase /home/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}/index.html !-f
RewriteCond %{REQUEST_FILENAME}/index.php !-f
RewriteRule . index.php [L]
</IfModule>
I'd remove that last block and put it in a separate .htaccess file in your /home directory, eg
# /home/.htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
# not sure about the next 3 lines though
RewriteCond %{REQUEST_FILENAME}/index.html !-f
RewriteCond %{REQUEST_FILENAME}/index.php !-f
RewriteRule . index.php [L]
</IfModule>