I am searching for a generic htaccess rewrite which forces the user to use https and www. Hence, the following URLs should all be rewritten to https://www.domain.tld/some/path:
http://domain.tld/some/path
http://www.domain.tld/some/path
https://domain.tld/some/path
https://www.domain.tld/some/path
It should be a generic solution, so that the domain name is not contained in the rule. Most probably, the rule will contain something like %{HTTP_HOST}%{REQUEST_URI} or %1/$1. Please describe why you use the one or the other.
Although there are tons of questions similar to this one, I did not find a solution which combines both - https and www redirection. Hope you can help.
Edit 1:
I tried the solutions by #anubhava, but I am getting a "too many redirects" error. Since the site is a Magento site, the htaccess is slightly more difficult. The following are the two mod_rewrite sections which I tried:
<IfModule mod_rewrite.c>
############################################
## enable rewrites
Options +FollowSymLinks
RewriteEngine on
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
############################################
## you can put here your magento root folder
## path relative to web root
#RewriteBase /magento/
############################################
## uncomment next line to enable light API calls processing
# RewriteRule ^api/([a-z][0-9a-z_]+)/?$ api.php?type=$1 [QSA,L]
############################################
## rewrite API2 calls to api.php (by now it is REST only)
RewriteRule ^api/rest api.php?type=rest [QSA,L]
############################################
## workaround for HTTP authorization
## in CGI environment
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
############################################
## TRACE and TRACK HTTP methods disabled to prevent XSS attacks
RewriteCond %{REQUEST_METHOD} ^TRAC[EK]
RewriteRule .* - [L,R=405]
############################################
## redirect for mobile user agents
#RewriteCond %{REQUEST_URI} !^/mobiledirectoryhere/.*$
#RewriteCond %{HTTP_USER_AGENT} "android|blackberry|ipad|iphone|ipod|iemobile|opera mobile|palmos|webos|googlebot-mobile" [NC]
#RewriteRule ^(.*)$ /mobiledirectoryhere/ [L,R=302]
############################################
## always send 404 on missing files in these folders
RewriteCond %{REQUEST_URI} !^/(media|skin|js)/
############################################
## never rewrite for existing files, directories and links
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
############################################
## rewrite everything else to index.php
RewriteRule .* index.php [L]
</IfModule>
And the second version:
<IfModule mod_rewrite.c>
############################################
## enable rewrites
Options +FollowSymLinks
RewriteEngine on
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^ https://www.domain.tld%{REQUEST_URI} [R=301,L]
############################################
## you can put here your magento root folder
## path relative to web root
#RewriteBase /magento/
############################################
## uncomment next line to enable light API calls processing
# RewriteRule ^api/([a-z][0-9a-z_]+)/?$ api.php?type=$1 [QSA,L]
############################################
## rewrite API2 calls to api.php (by now it is REST only)
RewriteRule ^api/rest api.php?type=rest [QSA,L]
############################################
## workaround for HTTP authorization
## in CGI environment
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
############################################
## TRACE and TRACK HTTP methods disabled to prevent XSS attacks
RewriteCond %{REQUEST_METHOD} ^TRAC[EK]
RewriteRule .* - [L,R=405]
############################################
## redirect for mobile user agents
#RewriteCond %{REQUEST_URI} !^/mobiledirectoryhere/.*$
#RewriteCond %{HTTP_USER_AGENT} "android|blackberry|ipad|iphone|ipod|iemobile|opera mobile|palmos|webos|googlebot-mobile" [NC]
#RewriteRule ^(.*)$ /mobiledirectoryhere/ [L,R=302]
############################################
## always send 404 on missing files in these folders
RewriteCond %{REQUEST_URI} !^/(media|skin|js)/
############################################
## never rewrite for existing files, directories and links
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
############################################
## rewrite everything else to index.php
RewriteRule .* index.php [L]
</IfModule>
Any ideas?
Edit 2:
Just setting up Magento to use https for secure and unsecure base URL as proposed by #anubhava does not solve the problem. The URL http://www.domain.tld/some/path is then redirected to https://www.domain.tld instead of https://www.domain.tld/some/path.
Clear your browser cache and restart your browser first.
Magento setting change
Open admin panel and visit System -> Configration -> Web panel and set Base URL (for both secured and unsecured) as https://www.domain.tld/.
then set
Auto-redirect to Base URL = No
Use Secure URLs in Frontend = Yes
Use Secure URLs in Admin = Yes
Save your settings, clear your Magento cache
Magento .htaccess change
Put this code in your .htaccess in the base magento directory just below RewriteBase line:
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
You could try this:
<IfModule mod_rewrite.c>
RewriteEngine On
# non www to https://www...
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
# non https to http
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
</IfModule>
The first rewrite rule checks if the hostname starts with www and if not, redirects using https and prepends www to the hostname. The flag R=301 signals apache to use a HTTP 301 permanent redirect, the L causes mod_rewrite to stop processing the rule set. For details, have a look at the documentation: http://httpd.apache.org/docs/current/rewrite/
The second rewrite rule catches requests with www but without https://. Hostname and path remain unchanged. Thanks to Nicolás Echániz and Joseph Scott's blog on http://joseph.randomnetworks.com/2004/07/22/redirect-to-ssl-using-apaches-htaccess/ for pointing out the second rule.
Related
All paths with www (www.example.com/posts/categories) redirect to the home page. How can i redirect from .htaccess and keep the full path?
https://www.example.com/posts/categories to https://example.com/posts/categories
current configuration:
<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]
# Send Requests To Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
</IfModule>
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
You've put this rule in the wrong place. It needs to go at the start, immediately after the RewriteEngine directive. By placing it at the end, after the rewrite to index.php, any request for the www subdomain will be redirected to index.php (during the second round of processing).
As a general rule, external redirects should always go before internal rewrites.
You should also consider implementing an HTTP to HTTPS redirect.
I have analyzed my website with the portal web.dev from Google. This told me that I have too many redirects if I call the URL without www and with http:
It goes first to https and without www, then to http with www and only then to https and www.
This is my htacces file:
<IfModule mod_headers.c>
# Allow access from all domains for webfonts (see contao/core-bundle#528)
<FilesMatch "\.(ttf|ttc|otf|eot|woff2?|font\.css)$">
Header set Access-Control-Allow-Origin "*"
</FilesMatch>
</IfModule>
<files serviceaccount.json>
Order allow,deny
Deny from all
</files>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
RewriteRule ^(.*) - [E=BASE:%1]
RewriteCond %{HTTP:Authorization} .
RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^app\.php(?:/(.*)|$) %{ENV:BASE}/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
RewriteRule ^ %{ENV:BASE}/app.php [L]
</IfModule>
I don't see at all where these redirects are implemented. I also found this variant to redirect directly. Even if I put them in the htaccess file, the redirects remain as described above.
<IfModule mod_rewrite.c>
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} ^(.*)$ [NC]
RewriteRule (.*) https://www.%1/$1 [R=301,L]
</IfModule>
Can you tell me how all these redirects come about and why the last code snippet doesn't work?
Some of those redirects might be done by your Hoster. Also, in newer Contao versions, Contao automatically redirects to https in the front end, if HTTPS is enabled in the respective website root's settings in the back end.
In any case, you should implement the redirects yourself, e.g. in your web/.htaccess. For example:
# Redirect to www subdomain
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# Redirect to HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
Note: the www redirect would redirect any domain that does not start with www. to www.. If you have a multidomain setup with different subdomains, you will need to adjust the www. redirect accordingly.
I have just upgraded my website from HTTP to HTTPS and my .htaccess, which worked perfectly before, is now behaving strangely. I have the following in there:
Remove trailing slash
Remove php extension
...plus others, but I guess these are the problematic ones.
The behaviors I'm getting, on an example page, are:
http://www.navanter.com/e-tips - no problem
https://www.navanter.com/e-tips.php - no problem
http://www.navanter.com/e-tips.php - seems to double the URL in the address bar
Am I missing something obvious? Code is:
Order Deny,Allow
DirectoryIndex index.php
# Secure text files
<Files ~ "\.txt$">
Order allow,deny
Deny from all
</Files>
# Redirect non-www to www:
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
ErrorDocument 404 /404.php
RewriteEngine On
# All calls go to SSL
RewriteEngine On
RewriteCond %{ENV:HTTPS} !=on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
# Unless directory, remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/$ https://www.navanter.com/$1 [R=301,L]
# Redirect external .php requests to extensionless url
RewriteCond %{THE_REQUEST} ^(.+)\.php([#?][^\ ]*)?\ HTTP/
RewriteRule ^(.+)\.php$ https://www.navanter.com/$1 [R=301,L]
# Resolve .php file for extensionless php urls
RewriteRule ^([^/.]+)$ $1.php [L]
For this specific problem, your rewrite rules for removing the trailing / and the .php extension shouldn't need the full URL in the substitution. You might also consider reordering some of those rules.
Updated Example:
Require all granted
DirectoryIndex index.php
# Secure text files
<Files ~ "\.txt$">
Require all denied
</Files>
ErrorDocument 404 /404.php
RewriteEngine On
# Redirect HTTP to HTTPS and non-www to www
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^ https://www.%1%{REQUEST_URI} [R=301,L]
# Unless directory, remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ /$1 [R=301,L]
# Redirect external .php requests to extensionless url
RewriteCond %{THE_REQUEST} /([^.]+)\.php [NC]
RewriteRule ^ /%1 [NC,R=301,L]
# Resolve .php file for extensionless php urls
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+)$ /$1.php [NC,L]
A couple things to note here:
The directives above were modified to use the updated apache 2.4 syntax
The RewriteEngine on directive should come before the other rewrite rules
The HTTP -> HTTPS and non-www -> www redirect logic can be done in a single operation
The PHP extension stripping, and subsequent remapping, should be done without the full URL to avoid the duplication behavior you observed. This last bit should fix the problem.
If you need further info on some of the syntax employed here, you can check the mod_rewrite documentation.
we have enabled https in our website and enabled 301 in admin section.
But the issue is with the category or product urls
example: i have https://www.boxdoccia.it/box-doccia/box-doccia-angolari/ , when change to http://www.boxdoccia.it/box-doccia/box-doccia-angolari/ return to homepage
Magento 1.7.0.2
-multiple store (ssl only for boxdoccia.it)
-Auto-redirect to Base URL -> yes 301
-secure and unsecure url -> https://www.boxdoccia.it
this is htaccess:
<IfModule mod_ssl.c>
############################################
## make HTTPS env vars available for CGI mode
SSLOptions StdEnvVars
</IfModule>
<IfModule mod_rewrite.c>
############################################
## enable rewrites
Options +FollowSymLinks
RewriteEngine on
############################################
## workaround for HTTP authorization
## in CGI environment
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
############################################
## TRACE and TRACK HTTP methods disabled to prevent XSS attacks
RewriteCond %{REQUEST_METHOD} ^TRAC[EK]
RewriteRule .* - [L,R=302]
############################################
## always send 404 on missing files in these folders
RewriteCond %{REQUEST_URI} !^/(media|skin|js)/
############################################
## never rewrite for existing files, directories and links
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
############################################
## rewrite everything else to index.php
RewriteRule .* index.php [L]
</IfModule>
############################################
## Prevent character encoding issues from server overrides
## If you still have problems, use the second line instead
AddDefaultCharset Off
#AddDefaultCharset UTF-8
FileETag none
#####
RewriteCond %{HTTP_HOST} ^(.*)boxdoccia.it
RewriteRule ^ - [E=MAGE_RUN_CODE:boxdoccia_it]
RewriteCond %{HTTP_HOST} ^(.*)boxdoccia.it
RewriteRule ^ - [E=MAGE_RUN_TYPE:website]
RewriteCond %{HTTP_HOST} ^(.*)allandmore.com
RewriteRule ^ - [E=MAGE_RUN_CODE:allandmore_com]
RewriteCond %{HTTP_HOST} ^(.*)allandmore.com
RewriteRule ^ - [E=MAGE_RUN_TYPE:website]
RewriteCond %{HTTP_HOST} ^(.*)piattodoccia.it
RewriteRule ^ - [E=MAGE_RUN_CODE:piattodoccia_it]
RewriteCond %{HTTP_HOST} ^(.*)piattodoccia.it
RewriteRule ^ - [E=MAGE_RUN_TYPE:website]
try this after
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
I'm trying to redirect the pretty made language tag ch-de to the Magento store view store code ch_de.
But instead it remove the first param and replace it with second, it just add it at the end. so it always look like mydomain.com/ch-de/ch_en/ even in the switcher which really confuse me.
Here is the part from .htaccess:
SetEnvIf X-Forwarded-Proto https HTTPS=on
############################################
## default index file
DirectoryIndex index.php
<IfModule mod_rewrite.c>
############################################
## enable rewrites
Options +FollowSymLinks
RewriteEngine on
############################################
## you can put here your magento root folder
## path relative to web root
#RewriteBase /magento/
#############################################
## redirect all non-www urls to www
## mod by pagewerkstatt
RewriteCond %{HTTP_HOST} ^[^.]+\.[^.]+$
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
#############################################
## add for "base urls" the trailing Slash
##
RewriteRule ^([^.]+[^/])$ /$1/ [R=301,L]
############################################
## uncomment next line to enable light API calls processing
# RewriteRule ^api/([a-z][0-9a-z_]+)/?$ api.php?type=$1 [QSA,L]
############################################
## rewrite API2 calls to api.php (by now it is REST only)
RewriteRule ^api/rest api.php?type=rest [QSA,L]
SetEnvIf Request_URI "index.php/api/(v2_)?soap/" is_backend=0
RewriteCond %{ENV:REDIRECT_REWRITE_IS_FINISHED} !1
RewriteCond %{REQUEST_URI} !^/[a-z]{2}-[a-z]{2}.*$
RewriteCond %{REQUEST_URI} !^.*/api/.*$
RewriteCond %{REQUEST_URI} !^.*/js/.*$
RewriteCond %{REQUEST_URI} !^.*/skin/.*$
RewriteCond %{REQUEST_URI} !^.*/media/.*$
RewriteCond %{REQUEST_URI} !^.*/adminguru.*$
RewriteRule ^(.*)$ /ch-de/$1 [R,L]
RewriteRule ^ch-de/?(.*) $1 [E=URL_LOCALE:ch-de,E=MAGE_RUN_CODE:ch_de]
RewriteRule ^ch-fr/?(.*) $1 [E=URL_LOCALE:ch-fr,E=MAGE_RUN_CODE:ch_fr]
RewriteRule ^ch-en/?(.*) $1 [E=URL_LOCALE:ch-en,E=MAGE_RUN_CODE:ch_en]
RewriteRule ^de-de/?(.*) $1 [E=URL_LOCALE:de-de,E=MAGE_RUN_CODE:de_de]
RewriteRule ^de-en/?(.*) $1 [E=URL_LOCALE:de-en,E=MAGE_RUN_CODE:de_en]
############################################
## workaround for HTTP authorization
## in CGI environment
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
############################################
## TRACE and TRACK HTTP methods disabled to prevent XSS attacks
RewriteCond %{REQUEST_METHOD} ^TRAC[EK]
RewriteRule .* - [L,R=405]
############################################
## redirect for mobile user agents
#RewriteCond %{REQUEST_URI} !^/mobiledirectoryhere/.*$
#RewriteCond %{HTTP_USER_AGENT} "android|blackberry|ipad|iphone|ipod|iemobile|opera mobile|palmos|webos|googlebot-mobile" [NC]
#RewriteRule ^(.*)$ /mobiledirectoryhere/ [L,R=302]
############################################
## always send 404 on missing files in these folders
RewriteCond %{REQUEST_URI} !^/(media|skin|js)/
############################################
## never rewrite for existing files, directories and links
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
############################################
## rewrite everything else to index.php
SetEnv REWRITE_IS_FINISHED 1
RewriteRule .* index.php [L]
You can see it here: http://www.sponser.ch/
I would be very thankful for any advice.