How to combine two .htaccess re-directs? - .htaccess

In my MVC application, I'm directing all of my requests to my index.php file using an .htaccess file. In addition, I'd like to enforce SSL. Using this post, I've added '#enforce https' code . However, when I add the code to my .htaccess file, my browser complains that it will be unable to complete the request. How can I have both rewrite rules in the same file?
RewriteEngine On
#redirect to index.php as appropriate
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.+)$ index.php?url=$1 [QSA,L]
#enforce https
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

The rule that rewrites to index.php has a regex: ^(.+)$, which matches everything. That includes anything you want to redirect. You need to have your redirect rules before your routing rules. Additionally, you need to make sure the nothing in index.php will redirect the browser back to non-SSL:
RewriteEngine On
#enforce https
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
#redirect to index.php as appropriate
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.+)$ index.php?url=$1 [QSA,L]

Related

Rewriting to add "www" failing along with internal rewrites in htaccess

This is the htaccess for my website currently:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !^(article/?).*$
RewriteRule ^article/?(.*)$ article.php?$1 [L, QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !^(info/?).*$
RewriteRule ^info/?(.*)$ info.php?$1 [L, QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !^(admin/?).*$
RewriteRule ^admin/?(.*)$ admin.php?$1 [L, QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?$1 [L, QSA]
# Force to SSL
RewriteCond %{HTTP:HTTPS} !1
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301, L]
# Force to WWW
RewriteCond %{HTTP_HOST} !^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301, L]
If the cache is cleared on the browser and I attempt to load "rotak.ro/article/rain", it redirects to "https://rotak.ro/article/rain", and I therefore fail to load external php css and java files because of the missing www.
If instead I load "rotak.ro", it correctly adds the www to the start of the url.
I'm assuming the RewriteCond for the WWW is failing to confirm in the cases where there are multiple slashes in the url, but I don't understand what's going on wrongly.
I'd like every url written, so rotak.ro/article/rain or rotak.ro/info/cookies to redirect to https://wwww.rotak.ro/ ....
How should I go about fixing this issue?
Have your htaccess rules file in following manner. You need to change order of redirect and www implementation rules. Then we need not to have multiple rules for your internal rewrite that could be handled within a single rules set itself.
Make sure to clear your browser cache before testing your URLs.
RewriteEngine ON
#Force to SSL
RewriteCond %{HTTP:HTTPS} !1
RewriteRule ^(.*)/?$ https://%{HTTP_HOST}/$1 [R = 301, L, NE]
#Force to WWW
RewriteCond %{HTTP_HOST} !^www\.(.*)$ [NC]
RewriteRule ^(.*)/?$ https://www.%{HTTP_HOST}/$1 [L, NE]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(article|info|admin)/?(.*)/?$ $1.php?$2 [NC,L, QSA]
NOTE: When we are putting redirection 301 in www rules it was affecting internal rules, so we had to remove it off. Even for OP internal rewrites were NOT working with OP's attempts.

htaccess rewrite http to https and remove subdirectory from url

Hi I am use Deployer to deploy a Craft CMS website. The site is symlinked to the directory called 'current'. I am using mod rewrite to remove the /current/public from the url in the document root like so:
RewriteEngine On
RewriteCond %{REQUEST_URI} !current/public/
RewriteRule (.*) /current/public/$1 [L]
And inside the current/public folder there is this htaccess to remove the index.php and create nice urls:
RewriteEngine On
# Send would-be 404 requests to Craft
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/(favicon\.ico|apple-touch-icon.*\.png)$ [NC]
RewriteRule (.+) index.php?p=$1 [QSA,L]
Edit - Test
The following works to force HTTPS but I end with urls looking like:
example.com/current/public/about etc
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !=https
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=302,L]
# Send would-be 404 requests to Craft
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/(favicon\.ico|apple-touch-icon.*\.png)$ [NC]
RewriteRule (.+) index.php?p=$1 [QSA,L]
How can I adjust this to force the site to always use HTTPS?
This will redirected all http request to https.
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteCond %{HTTP_HOST} ^(www.)?yourdomainname.com
RewriteRule ^(.*)$ https://www.yourdomainname.com/$1 [R,L]
Hope this will help you
The following is what I managed to get working:
RewriteEngine on
RewriteRule ^(.*)$ current/public/$1
RewriteCond %{HTTP:X-Forwarded-Proto} !=https
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=302,L]

Why are clean URLs not working when redirecting to https?

I added some lines in my htacess file to redirect all http requests to https. Now when I type in a URL like: http://example.com/frames/view/4701362, it redirects to: https://example.com/index.php?q=frames/view/4701362. I can go to the page manually: https://example.com/frames/view/4701362 and the URL does not get changed.
I have Clean URLs set up
Htaccess file
<IfModule mod_rewrite.c>
RewriteEngine on
#some more stuff here, unrelated
# Rewrite URLs of the form 'x' to the form 'index.php?q=x'.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
</IfModule>
Edit:
I tried reversing the Drupal index.php?q= line and the https lines like this...
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
But then my site did not load properly and said Page not found even at the homepage.
Thanks to #MikeRockett above, I was able to figure this out. In addition to his suggestion, I had to add [L,R=301] to the RewriteRule line.
<IfModule mod_rewrite.c>
RewriteEngine on
#some more stuff here, unrelated
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Rewrite URLs of the form 'x' to the form 'index.php?q=x'.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
</IfModule>

Avoid infinite loop with 301 redirects

I'm using .htaccess to redirect
http://www.example.com/foo/
to
http://www.example.com/foo/bar
This is my code:
redirect 301 /foo/ http://www.example.com/foo/bar
However this produces a feedback loop, something like
http://www.example.com/foo/barbarbarbarbarbar etc.
I've tried placing delimiters around it:
redirect 301 ^/foo/$ http://www.example.com/foo/bar
but then the redirect simply doesn't take place. I'm probably missing some very simple point of syntax. Any ideas? Thanks.
EDIT
Here's my (almost) full .htaccess file:
RewriteEngine On
RewriteBase /
# Canonical is www version
RewriteCond %{HTTP_HOST} !^www.example.com$ [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [L,R=301]
#redirect => http unless special page
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} !^/(javascripts|images|library|stylesheets)
RewriteRule ^(.*)$ http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
#redirect => https for special pages
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# send to router
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [L]
Have your rules like this:
RewriteEngine On
RewriteBase /
# Canonical is www version
RewriteCond %{HTTP_HOST} !^www\.example\.com$ [NC]
RewriteRule ^ http://www.example.com%{REQUEST_URI} [L,R=301]
#redirect => http unless special page
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{HTTPS} on
RewriteCond %{THE_REQUEST} !/(javascripts|images|library|stylesheets)
RewriteRule ^(.*)$ http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
#redirect => https for special pages
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{HTTPS} off
RewriteRule !^index\.php$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteRule ^foo/?$ /foo/bar [L,NC,R=301]
# send to router
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [L]
make sure to test this in a new browser or clear your browser cache before testing.
For your information, it really depends on your hosting provider. It may be behind a Load Balancer and you don't have the proper env var set (like HTTPS and others...).
In my case (Infomaniak), nothing actually worked and I got infinite redirect loop.
The right way to do this for Infomaniak is actually explained in their support site:
RewriteEngine on
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule (.*) https://your-domain.com/$1 [R=301,L]
So, always check with your hosting provider. Hopefully they have an article explaining how to do this. Otherwise, just ask the support.
It depends on what is the resource that you want to expose with your redirect.
Is it a file or a directory.
if you would expose a directory under bar you should try :
RedirectMatch 301 ^/foo/ http://www.example.com/foo/bar/
if you would redirect to a file you should use this syntax :
redirect 301 /foo http://www.example.com/foo/bar
you can see this post for more informations
Instead of using redirect, you can use passthrough.
RewriteRule ^/foo$ /foo/bar [PT]

Redirecting all requests to index.php without direct access

I have the following code in my .htaccess file.
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
This redirects all requests to index.php. However I am still able to access www.mydomain.com/index.php directly from the URL. As www.mydomain.com servers the same content as www.mydomain.com/index.php will this be recorded as duplicated in google, if so how do I prevent it.
Insert this rule before existing rule to remove index.php from URI:
RewriteCond %{THE_REQUEST} /index\.php [NC]
RewriteRule ^(.*?)index\.php$ /$1 [L,R=301,NC,NE]

Resources