Reputation: 113
I have successfully added the following code to my Apache HTTPD configuration:
# Force www.
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
# Force https (SSL)
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
Although it works as expected, I have a theoretical question:
Why are there a ^
and $
in 3rd line enforcing "www.", and not in the 6th line enforcing "https"?
Sincerely, Dovid.
Upvotes: 1
Views: 1998
Reputation: 785156
For both of your regex patterns ^(.*)$
and (.*)
will behave same. However guess what, you don't need to use any of them. In fact it is far less error prone also to not to use .*
and use %{REQUEST_URI}
variable that matches full URI (not the relative one like .*
). So I suggest change your rules to this:
# Force www.
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE]
# Force https (SSL)
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE]
NE
is used for not escaping. It is useful to have this flag in case your original URI has some special characters like #
or (,),[,]
etc.^
in RewriteRule
pattern above does nothing but returns true for every match since ^
means start position of a string and it will be always match.Here it is:
RewriteCond %{HTTP_HOST} !^www\. [NC,OR]
RewriteCond %{HTTPS} !on
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^ https://www.%1%{REQUEST_URI} [R=301,L,NE]
Here is the explanation of this rule:
RewriteCond %{HTTP_HOST} !^www\. [NC,OR]
: if HOST_NAME
doesn't start with www.
[NC,OR]
: Ignore case match and OR
s next conditionRewriteCond %{HTTPS} !on
: HTTPS
is not turned onRewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
: This condition will always match since www.
is an optional match here. It is used to capture substring of HTTP_HOST
without starting www.
by using (.+)
pattern in capture group #1 (to be back-referenced as %1
later). Note that (?:..)
is a non-capturing group.RewriteRule ^ https://www.%1%{REQUEST_URI} [R=301,L,NE]
: ^
will always match. This rule will redirect to https://www.%1%{REQUEST_URI}
with R=301
code by adding https://
and www.
to %1
. %1
is back-reference of capture group #1 from RewriteCond
, as mentioned above.Upvotes: 3
Reputation: 12017
They're the same. There's no difference between ^(.*)$
and (.*)
.
.*
matches any string. ^
and $
don't change that since all strings have a start and end.
Upvotes: 2
Reputation: 9377
If using Apache's module mod_rewrite then you can define a RewriteRule.
The keyword or directive RewriteRule
is followed by a Regular Expression (also known as RegEx or pattern). This RegEx (e.g. ^(.*)$
) is used to match input URL's in order to rewrite them.
Within a RegEx pattern ^
marks the start of the line to match, whereas the end is denoted by $
.
Both are called metacharacters and have special meaning:
^: Matches the starting position within the string. In line-based tools, it matches the starting position of any line.
$: Matches the ending position of the string or the position just before a string-ending newline. In line-based tools, it matches the ending position of any line.
Since URLs reaching the HTTP-server always are represented by one single line, these line-delimiting metacharacters can also be omitted without affecting the pattern/rewrite-rule.
Upvotes: 3
Reputation: 4284
It depends if you made the certificate for the domain without www or with www.
In the provided example the redirection (6th line) is done to the domain without www. That guarantees that the correct certificate will be served and browser won't display an alert while visiting your site.
Upvotes: 1