mod_rewrite .htaccess HTTPS - mod-rewrite

I would like to force the browser to redirect to HTTPS always if someone types in:
http://www.mydomain.com/user
or
http://www.mydomain.com/user/
Both of the above 2 links should redirect to: https://www.mydomain.com/user
Right now the 2nd to bottom line of code works correctly:
RewriteRule ^user$ https://www.mydomain.com/user/ [R,QSA]
will indeed redirect the browser to HTTPS but if http://www.mydomain.com/user/ is input then it won't redirect to HTTPS. How can I achieve this?
Options +FollowSymLinks
RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_HOST} ^mydomain.com [NC]
RewriteRule ^(.*)$ http://www.mydomain.com/$1 [L,R=301]
RewriteRule ^user$ https://www.mydomain.com/user/ [R,QSA]
RewriteRule ^user/$ public/index.php?var1=x&var2=y [L,QSA]

Use these rules:
Options +FollowSymLinks
RewriteEngine on
RewriteBase /
# force www domain name
RewriteCond %{HTTP_HOST} ^mydomain.com [NC]
RewriteRule ^(.*)$ http://www.mydomain.com/$1 [L,R=301]
# force HTTPS for some pages
RewriteCond %{HTTPS} =off [NC]
RewriteRule ^user/?$ https://www.mydomain.com/user/ [R=301,L]
RewriteRule ^user/$ public/index.php?var1=x&var2=y [L,QSA]
It will redirect to HTTPS:
if HTTP is current protocol (so no redirection if already on HTTPS)
regardless of trailing slash presence: both /user and /user/ will do the job (but will do nothing if /user/something-here will be requested).

How about this ...
RewriteRule ^user/(.+)/?$ public/index.php?var1=x&var2=y [L,R=301]
RewriteRule ^user/?$ https://www.mydomain.com/user/ [L,QSA]
RewriteRule ^(.*)/?$ http://www.mydomain.com/$1 [L,R=301]

Related

non www url is redirecting to homepage

I have .htaccess settings to get any non-www request to www.
It works for the home page, but when I check other URLs it goes to the home page.
Here are my settings (UPDATED): Top part is coming from laravel
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
RewriteRule (.*?)index\.php/*(.*) /$1$2 [R=301,NE,L]
#First rewrite any request to the wrong domain to use the correct one (here www.)
RewriteCond %{HTTP_HOST} ^[^.]+\.[^.]+$
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [L,R=301]
#Now, rewrite to HTTPS:
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{HTTP_USER_AGENT} libwww-perl.*
RewriteRule .* ? [F,L]
</IfModule>
For example
https://example.com goes to https://www.example.com.
But https://example.com/contact doesn't go to https://www.example.com/contact. Instead, it goes to https://www.example.com.
What can be the problem and solution?
but https://example.com/contact doesn't go to https://www.example.com/contact
Assuming you are not simply using extensionless URLs (ie. /contact maps to /contact.php) with MultiViews/mod_negotiation then you must have other mod_rewrite directives that route these requests.
It looks like you may have put these directives in the wrong order.
The external redirects in your question need to go near the top of your .htaccess before any internal rewrites to a front-controller.
Aside:
#First rewrite any request to the wrong domain to use the correct one (here www.)
RewriteCond %{HTTP_HOST} ^[^.]+\.[^.]+$
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [L,R=301]
This rule should be redirecting to https://, not http://. Otherwise you are going to get multiple, unnecessary redirects (https to http and back to https).
RewriteCond %{HTTP_USER_AGENT} libwww-perl.*
RewriteRule .* ? [F,L]
This rule (currently last), needs to go at the top. Generally, any blocking directives should be first. You can also simplify/optimise this a bit...
RewriteCond %{HTTP_USER_AGENT} libwww-perl
RewriteRule ^ - [F]
L is implied when using F. If there is no substitution string then you should use -, not ?.
UPDATE: Following your updated question, my initial answer/hypothesis is confirmed... your directives are in the wrong order. Your external redirects need to go before the Laravel front-controller.
Otherwise, in its current order, a request of the form example.com/contact is first internally rewritten to index.php by the Laravel front-controller and then there will be an external redirect to the canonical scheme + hostname, so the net result is you are redirected to the homepage.
The cPanel redirect you mentioned in comments simply manifests itself as a rule in .htaccess (which you've already included). But note that all cPanel redirects are placed (often incorrectly) at the end of the .htaccess file (this is stated in the cPanel docs).
So, in summary, your directives should be written like this:
Options -MultiViews -Indexes
RewriteEngine on
#
# BLOCKING DIRECTIVES
#
# Block certain requests
RewriteCond %{HTTP_USER_AGENT} libwww-perl
RewriteRule ^ - [F]
#
# CANONICAL REDIRECTS
#
# Redirect non-www to www + HTTPS
RewriteCond %{HTTP_HOST} ^[^.]+\.[^.]+$
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [L,R=301]
# Redirect HTTP to HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Remove index.php
RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
RewriteRule (.*?)index\.php/*(.*) /$1$2 [R=301,NE,L]
#
# Laravel directives follow...
#
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
ıt seems that is working with this
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
## Force https and www
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\.example\.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [L,R=301]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
RewriteCond %{HTTP_USER_AGENT} libwww-perl.*
RewriteRule .* ? [F,L]
RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
RewriteRule (.*?)index\.php/*(.*) /$1$2 [R=301,NE,L]
</IfModule>
Any extra suggestions to optimize are accepted with pleasure

Laravel - htaccess redirect from www to non-www and from http to https with request uri goes to index.php

I've tried several solutions but none of them seem to work. I have a Laravel application(public folder is removed) and i wanted to redirect the user to HTTPS and a non-www version of my website
Here is an example of the action i wanted to accomplish
Redirect http://example.com to https://example.com
Redirect http://www.example.com to https://example.com
Redirect https://www.example.com to https://example.com
I was able to accomplish that using the following code on htaccess
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.example.com$ [NC]
RewriteRule (.*) https://example.com [R=301,L]
Now, since the website has many links, i wanted to redirect the users without losing any text after the domain. Here is an example
Redirect https://www.example.com/electronics/laptops/hp to https://example.com/electronics/laptops/hp
I tried many variations using $ and request_uri but they keep redirecting to https://example.com/index.php. After searching for answers here, the last thing i tried looked something like this, which yielded the same result
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
RewriteRule ^ https://example.com%1%{REQUEST_URI} [L,R=301,NE]
This seems to redirect any traffic that comes as https://www.example.com/string1/string2/string3 to https://example.com/index.php
So how can i redirect traffic as intended and which is a better practice. Write two rules or combine the rules using If statements.
I would like to use htaccess only methods, no middleware.
I had the same problem
You should put this code on top of .htaccsee file after
RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://yourdoamin.com%{REQUEST_URI} [L,R=301,NC]
if you put this after
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
your page redirect to yourdomain.com/index.php
To redirect www requests to non-www without losing the path or the query string this is the right format:
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
RewriteRule (.*) https://example.com/$1 [R=301,L]
If your website is on a server without a reverse proxy, you can easily redirect non-HTTPS requests to HTTPS as following:
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
In case there is a reverse proxy or a load balancer you need to check the forwarded headers, depending on the proxy configuration (eg. X-Forwared-Proto)
Try out this one
# Redirect from http to https
RewriteEngine on
# Redirect to HTTPS
RewriteCond %{HTTPS} off
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# (http://www.example.com/foo will be redirected to http://example.com/foo)
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ http%{ENV:protossl}://%1%{REQUEST_URI} [L,R=301]
# to redirect index.php to the root
RewriteCond %{THE_REQUEST} ^.*/index\.php
RewriteRule ^(.*)index.php$ /$1 [R=301,L]
I had the same problem
You should put this code on top of .htaccsee file after
RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://yourdoamin.com%{REQUEST_URI} [L,R=301,NC]
if you put this after
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
your page redirect to yourdomain.com/index.php
After spending a few hours searching the web and testing different suggestions, I found the solution.
.htaccess in the public_html
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} !^public
RewriteRule ^(.*)$ public/$1 [L]
</IfModule>
.htaccess in the public folder
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
# Redirect to https
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://yourdomain.com/$1 [R,L]
# Redirect to non www
RewriteCond %{HTTP_HOST} ^www.yourdomain.com$ [NC]
RewriteRule ^(.*)$ https://yourdomain.com/$1 [R=301,L]
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
# This made the trick for me
# Remove index.php from the url
RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
RewriteRule (.*?)index\.php/*(.*) /$1$2 [R=301,NE,L]
</IfModule>
I hope this will work for others too

redirect all pages including sub pages to new domain

I tried this:
RedirectMatch 301 (.*) http://olddomain.com$1
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^olddomain.com$ [NC]
RewriteRule ^(.*)$ http://newdomain.com/$1 [L,R=301]
But all subpages are not redirected.
Try this,
RewriteEngine On
# Take care of www.old.com.au
RewriteCond %{HTTP_HOST} ^www.old.com.au$ [NC]
RewriteRule ^(.*)$ http://www.new.com/$1 [L,R=301]
RewriteCond %{QUERY_STRING} ^attachment_id=([0-9]*)$ [NC]
RewriteRule ^$ http://www.new.com/? [R=301,NE,NC,L]
It's simple, I was just using this to do some special rewriting for my own, here is your code:
Put this inside your /www/.htaccess file:
RewriteEngine on
// Rules to redirect to another domain
RewriteCond %{HTTP_HOST} ^example.com [NC,OR]
RewriteCond %{HTTP_HOST} ^www.example.com [NC]
RewriteRule ^(.*)$ http://example.net/$1 [L,R=301,NC]
Check http://www.inmotionhosting.com/support/website/redirects/setting-up-a-301-permanent-redirect-via-htaccess, for 3 more ways to make a redirection.
Are you setting directive AllowOverride All in your Apache config?
Is the mod_rewrite module working?

Redirect subdomain, but only if site root requested

I can't seem to find an answer to this specific question:
How can I forward http://play.domain.com -- but NOT http://play.domain.com/xxx
To:
http://work.domain.com
Where "xxx" is any string.
In other words, if the user requests the site root, redirect, otherwise stay on the chosen URL.
I've tried
RewriteEngine On
RewriteCond %{HTTP_HOST} !work.domain.com [NC]
RewriteRule ^(.*)$ http://work.domain.com.com/$1 [R=301,L]
But it's not doing anything :-/
Enable mod_rewrite and .htaccess through httpd.conf and then put this code in your .htaccess under DOCUMENT_ROOT directory:
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^play\.domain\.com$ [NC]
RewriteRule ^/?$ http://work.domain.com/ [R=301,L]
Try:
RewriteEngine On
RewriteCond %{HTTP_HOST} !work.domain.com [NC]
RewriteRule ^$ http://work.domain.com.com/ [R=301,L]
to only redirect the blank request.

mod_rewrite to force SSL for a subfolder

I try to make a redirect from a special folder to a special host.
When somebody enter http://mydomain.com/administrator he should be redirected to https://a-otherdomain.com/mydomain.com/administrator
What I have is this in a .htaccess file in DOCUMENT_ROOT .. but it want work :(
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} (^|\.)mydomain\.com$ [NC]
RewriteCond %{REQUEST_URI} ^/administrator(/*) [NC]
RewriteRule ^/administrator/(.*)$ https://a-otherdomain.com/mydomain.com/administrator/$1 [QSA,R=301,L]
Any Ideas?
Update:
now I use this, which works in apache configuration files for the vhost:
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} (^|\.)mydomain\.com$ [NC]
RewriteCond %{REQUEST_URI} ^/administrator/ [NC]
RewriteRule ^/(.*)$ https://a-otherdomain.com/mydomain.com/$1 [R=301,L]
Thanks,
Thomas
RewriteRule doesn't match leading slash in a URI.
Try this code:
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} (^|\.)mydomain\.com$ [NC]
RewriteRule ^administrator(/.*|)$ https://a-otherdomain.com/mydomain.com/$0 [R=302,L,NC]
Once you verify it is working fine, replace R=302 to R=301. Avoid using R=301 (Permanent Redirect) while testing your mod_rewrite rules.

Resources