Welcome to WebmasterWorld Guest from 54.224.140.171

Forum Moderators: Ocean10000 & incrediBILL & phranque

redirect the root to https ONLY

common fixes are not working

     
2:07 pm on Dec 31, 2016 (gmt 0)

Senior Member

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month

joined:Mar 7, 2003
posts: 1070
votes: 6


Hi - so I know a basic command to redirect from http to https is this - and it is working nicely.

RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]

However it is creating a double 301 - because of course there are two redirects going on.

One from http://www.example.com/oldsite-page.html to https://www.example.com/newsite-page.html

(and there are about a hundred of these)

and the other 301 apparently is happening due to the unintended consequence of needing to force this:

http://www.example.com/

to

https://www.example.com/

so - how do i write this directive in a way that does both - you know, redirects all explicitly named pages as specified, AND redirects the ROOT, without generating double 301?

[edited by: not2easy at 3:44 pm (utc) on Dec 31, 2016]
[edit reason] Please use example.com for readability [/edit]

4:07 pm on Dec 31, 2016 (gmt 0)

Administrator from US 

WebmasterWorld Administrator not2easy is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month

joined:Dec 27, 2006
posts:3180
votes: 133


Are you redirecting from the old site to the new site page for page and then changing to https after the request comes in? Why not just change the rule at old-site that sends requests to the new site? Just trying to get a clear picture of this.


4:12 pm on Dec 31, 2016 (gmt 0)

Senior Member from NL 

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month

joined:Sept 25, 2005
posts:1396
votes: 163


You haven't included an example of your rewrites for individual pages, but wouldn't it be enough to put the page-level redirects before the SERVER_PORT redirect?
8:09 pm on Dec 31, 2016 (gmt 0)

Senior Member from US 

WebmasterWorld Senior Member lucy24 is a WebmasterWorld Top Contributor of All Time 5+ Year Member Top Contributors Of The Month

joined:Apr 9, 2011
posts:13620
votes: 421


However it is creating a double 301 - because of course there are two redirects going on.

It sounds as if you've got your rules in the wrong order. Within any one category (generally but not always meaning the various flags like [F] or [G]), arrange the rules from most specific to most general. The catchall rules such as https and domain-name canonicalization then go at the very end of your external redirects, so they only apply to requests that haven't already been redirected for other reasons.

This is assuming you have no rules using mod_alias (Redirect or RedirectMatch by that name). If you do, change them to mod_rewrite syntax so they will execute in the intended order.

It's not clear why the root is getting redirected twice, though. It makes sense for other pages, but where else is the root getting redirected? The only way I can think of is if you've got domain-name canonicalization (the "with/without www" redirect) and https as two separate rules. They should be a single rule with two conditions, separated by [OR].
1:38 am on Jan 1, 2017 (gmt 0)

Senior Member

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month

joined:Mar 7, 2003
posts: 1070
votes: 6


can I put my file up here for commentary? I'll munge out the words and domain names but you'll get the drift.

can I do that?
1:41 am on Jan 1, 2017 (gmt 0)

Senior Member

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month

joined:Mar 7, 2003
posts: 1070
votes: 6


RewriteEngine on

#RewriteRule ^ http://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
#RewriteRule ^p/(.*)/(.*)\.html$ product.jhtm?sku=$1 [QSA]
#RewriteRule ^c/([0-9]+)/(.*)\.html$ category.jhtm?cid=$1 [QSA]

RewriteRule ^p/([^/]+)/([^/]+)\.html$ product.jhtm?sku=$1 [QSA]
RewriteRule ^c/([0-9]+)/([^/]+)\.html$ category.jhtm?cid=$1 [QSA]

RewriteRule ^product/([^/])/([^/])\.html$ product.jhtm?sku=$1 [QSA]
RewriteRule ^category/([0-9]+)/([^\/]+)\.html$ category.jhtm?cid=$1 [QSA]

RewriteRule ^OTF$ category.jhtm?cid=1470 [NC]

# redirect html pages to the root domain
RewriteRule ^index\.html$ / [NC,R,L]

ErrorDocument 404 /404.html

#RewriteCond %{SERVER_PORT} 80
#RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]
Redirect permanent /about-xyz-word.html "https://www.example.com/c/1335/About-Us.html"
Redirect permanent /about-ERC-Wiping.html "https://www.example.com/c/1335/About-Us.html"
Redirect permanent /careers.html "https://www.example.com/c/1378/Careers.html"
Redirect permanent /contact.html "https://www.example.com/c/1379/Contact-Us.html"
Redirect permanent /customer-support.html "https://www.example.com/c/1352/Customer-Service.html"

[edited by: phranque at 4:53 am (utc) on Jan 2, 2017]
[edit reason] unlinked url pattern for clarity [/edit]

2:44 am on Jan 1, 2017 (gmt 0)

Senior Member from US 

WebmasterWorld Senior Member lucy24 is a WebmasterWorld Top Contributor of All Time 5+ Year Member Top Contributors Of The Month

joined:Apr 9, 2011
posts:13620
votes: 421


Oh, criminy. Let's talk about order of rules. Before anything else, change all those mod_alias Redirect rules.

:: shuffling papers ::

Well, n/m, I'll just paste in the whole "htaccess cleanup" boilerplate and you can disregard the parts that don't apply.

Cleaning up an htaccess file

Step 1: Organize. Collect all the directives for each module in one place. The server doesn't care, but you-- and anyone who comes along after you-- will appreciate it.

Tip: Use a text editor with a "Find All" window to pull up all lines beginning with the element "Rewrite..." That takes care of mod_rewrite; dump them all at the end for now.

Step 2: Get rid of all <IfModule> envelopes. Not their contents, just the envelopes themselves. These envelopes are hallmarks of mass-produced htaccess files that have to work anywhere, on any server. You are now on your own site. Any given mod is either available to you or it isn't.

Exception: If you use a standard CMS such as WordPress, your htaccess file will contain a group of lines beginning and ending with #comments saying something like "begin WordPress" and "end WordPress". Leave everything in this package unchanged unless you know what you are doing.

Step 3: Sort by module. The server doesn't care what order the directives are listed in, or even if rules from different modules are all garbled together. Each module works separately, seeing only its own directives. But humans need to be able to find things.

For most people it will be most practical to group one-liners at the beginning:

Options -Indexes


is a good start. If your htaccess file contains only one line, that's probably it. Other quick directives are ones starting with words like AddCharset or Expires. Then list your error documents.

If you have any very short Files or FilesMatch envelopes, put them near the top too. For example:
<Files "robots.txt">
Order Allow,Deny
Allow from all
</Files>

<FilesMatch "\.(css|js)">
Header set X-Robots-Tag "noindex"
</Files>


Be sure to have an "Allow from all" envelope for your custom 403 page. If you are on shared hosting and they provide default error-document names such as "forbidden.html", this has probably already been done in the config file. But it does no harm to repeat it.

Step 4: Consolidate redirects.

Step 4a: Get rid of mod_alias. If your htaccess file contains any mod_rewrite directives, it can't use mod_alias (Redirect... by that name), or things may happen in the wrong order. For large-scale updating, use these Regular Expressions, changing \1 to $1 if that's what your text editor uses. Each of these can safely be run as an unsupervised global replace.

# change . to \. in pattern
^(Redirect \d\d\d \S+?[^\\])\.
TO
\1\\.

# now change Redirect to Rewrite
^Redirect(?:Match)? 301 /(.+)
TO
RewriteRule \1 [R=301,L]

# and if needed
^Redirect(?:Match)? 410 /(.+)
TO
RewriteRule \1 - [G]

^Redirect(?:Match)? 403 /(.+)
TO
RewriteRule \1 - [F]


Step 4b: Sort your RewriteRules. At the beginning is the single line

RewriteEngine on


A RewriteBase is almost never needed; get rid of any lines that mention it. Instead, make sure every target begins with either protocol-plus-domain or a slash / for the root.

Sort RewriteRules twice.

First group them by severity. Access-control rules (flag [F]) go first. Then any 410s (flag [G]). Not all sites will have these. Then external redirects (flag [R=301,L] unless there is a specific reason to say something different). Then simple rewrite (flag [L] alone). Finally, there may be a few rules without [L] flag, such as cookies or environmental variables.

Function overrides flag. If your redirects are so complicated that they've been exiled to a separate .php file, the RewriteRule will have only an [L] flag. But group it with the external redirects. If certain users are forcibly redirected to an "I don't like your face" page, the RewriteRule will have an R flag. But group it with the access-control [F] rules.

Then, within each functional group, list rules from most specific to most general. In most htaccess files, the second-to-last external redirect will take care of "index.html" requests. The very last one will fix the domain name, such as with/without www.

Leave a blank line after each RewriteRule, and put a
# comment

before each ruleset (Rule plus any preceding Conditions). A group of closely related rulesets can share an explanation.

Step 5: Notes on error documents.

Reminder: ErrorDocument directives must not include a domain name, or else everything will turn into a 302 redirect. Start each one with a / representing the root.

Caution: Since each module is an island, any module that can issue a 403 must have its own error-document override. "Allow from all" in a <Files> envelope covers mod_authzzzz. If you have RewriteRules that end in [F], make sure your 403 documents can bypass these rules:
RewriteRule ^forbidden\.html - [L]

This rule must go before any rules with the [F] flag.
3:46 am on Jan 1, 2017 (gmt 0)

Senior Member

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month

joined:Mar 7, 2003
posts: 1070
votes: 6


ok, i have no idea what you are talking about. Well on second read through, maybe...

You basically mean put the stuff at the top at the bottom, right?

is this operational, or just neatness?
4:47 am on Jan 1, 2017 (gmt 0)

Administrator from US 

WebmasterWorld Administrator not2easy is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month

joined:Dec 27, 2006
posts:3180
votes: 133


This is a mod_alias Rewrite Rule:
Redirect permanent

Those rules should be changed to mod_rewrite rules. Not just for appearance. That is probably the reason the other (404) problem showed up.

You should not generally mix mod_alias and mod_rewrite because they do not always execute in the order expected and can cause errors and loops. You can find many problems others have reported if you search for "mod_alias" here. Not to go into great detail, but Apache uses different Modules that are not all active and even when they are active they may not execute in some standard sequence. Best to avoid problems and stick to mod_rewrite.

Then be sure that the order the rules appear is the order they should execute. In the order shown they could cause multiple rewrite issues.
4:59 am on Jan 2, 2017 (gmt 0)

Administrator

WebmasterWorld Administrator phranque is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month

joined:Aug 10, 2004
posts:10817
votes: 57


http://httpd.apache.org/docs/current/rewrite/avoid.html [httpd.apache.org]:
when there are Redirect and RewriteRule directives in the same scope, the RewriteRule directives will run first, regardless of the order of appearance in the configuration file.
6:44 am on Jan 2, 2017 (gmt 0)

Senior Member from US 

WebmasterWorld Senior Member lucy24 is a WebmasterWorld Top Contributor of All Time 5+ Year Member Top Contributors Of The Month

joined:Apr 9, 2011
posts:13620
votes: 421


Redirect and RewriteRule directives in the same scope

Does "same scope" mean they appear in the same place (like in the same htaccess or the same <Directory> section), or does it simply mean that requests in a given area will encounter both modules' directives along the way?

In any case it seems as if this line should be displayed a little more prominently in the docs ;)

And then there's...
Some configuration directives are only available in the server configuration file. So if you are in a hosting situation where you only have .htaccess files to work with, you may need to resort to mod_rewrite.

Ya think?

In short: Half of mod_alias's functions (the ones that, er, have to do with aliasing) are only available in the config file. The other half (redirecting) don't play nice with mod_rewrite, which is the only way within htaccess to do domain-name canonicalization or https redirects, and also (I think) the only way ever to do redirects involving changes to the query string. (And, of course, the only way to rewrite internally.) So what was the reason for making mod_alias available in htaccess, again?

It's a very different thing when you're doing something in mod_rewrite that could easily be handled in mod_setenvif and/or mod_auth_thingamajig. That's when you'll hear me muttering about shooting flies with an elephant rifle.
4:16 pm on Jan 8, 2017 (gmt 0)

Senior Member

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month

joined:Mar 7, 2003
posts: 1070
votes: 6


awesome - always learning something new! gots ta do what I gots ta do and I think i got it.

let me just check a few things - so mod_alias is this kind of thing:

Redirect permanent /about-xyz-word.html "https://www.example.com/c/1335/About-Us.html"

and it should be rewritten like this:

Rewrite rule ^/about-xyz-word.html /c/1335/About-Us.html [R=301,L]

?

does that solve some of the issues - or introduce more?

--thanks
6:21 pm on Jan 8, 2017 (gmt 0)

Administrator from US 

WebmasterWorld Administrator not2easy is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month

joined:Dec 27, 2006
posts:3180
votes: 133


Better, but Rules should have the start anchor '^' and an end anchor: $

These rules should be before the canonical (www/index) rewrites.
7:36 pm on Jan 8, 2017 (gmt 0)

Senior Member from US 

WebmasterWorld Senior Member lucy24 is a WebmasterWorld Top Contributor of All Time 5+ Year Member Top Contributors Of The Month

joined:Apr 9, 2011
posts:13620
votes: 421


Redirect permanent /about-xyz-word.html "https://www.example.com/c/1335/About-Us.html"

and it should be rewritten like this:

Rewrite rule ^/about-xyz-word.html /c/1335/About-Us.html [R=301,L]

Make that:
RewriteRule ^about-xyz-word\.html http://www.example.com/c/1335/About-Us.html [R=301,L]
Scroll up to the "htaccess cleanup" boilerplate and you'll find the section on converting mod_alias syntax to mod_rewrite syntax.

Lethal error: there's no space in "RewriteRule". (On the other hand, rule names in Apache aren't case sensitive, though it's best to stick with the standard CamelCase for consistency.)
Lethal error: In mod_rewrite, unlike mod_alias, patterns do not begin with a slash. (Fun fact: mod_rewrite doesn't recognize multiple slashes in the pattern, only in Conditions*, so even requests for example.com//blahblah would not be caught by this rule.)
Non-lethal error: mod_rewrite always uses Regular Expressions, so literal periods should be escaped as \.
Potential error: all targets of external redirects (this applies to both mod_alias and mod_rewrite) should include the full protocol-plus-host; otherwise you risk getting chained redirects if the original request was wrong in some way.


* Source: Direct personal trial-and-error.
11:52 pm on Jan 9, 2017 (gmt 0)

Administrator

WebmasterWorld Administrator phranque is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month

joined:Aug 10, 2004
posts:10817
votes: 57


In mod_rewrite, unlike mod_alias, patterns do not begin with a slash.

it depends on the context.

http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriterule

in general:
What this pattern is compared against varies depending on where the RewriteRule directive is defined.


in per-directory context (RewriteRule directives defined in <Directory> enclosures or .htaccess files such as this case):
The directory path where the rule is defined is stripped from the currently mapped filesystem path before comparison (up to and including a trailing slash). The net result of this per-directory prefix stripping is that rules in this context only match against the portion of the currently mapped filesystem path "below" where the rule is defined.
12:42 am on Jan 10, 2017 (gmt 0)

Senior Member from US 

WebmasterWorld Senior Member lucy24 is a WebmasterWorld Top Contributor of All Time 5+ Year Member Top Contributors Of The Month

joined:Apr 9, 2011
posts:13620
votes: 421


where the RewriteRule directive is defined

OK, I should have said “in htaccess”.

Rhetorical question: Does anyone really have access-related rules--including redirects--lying loose in their config file? Seems like, at a minimum, you'd have one set of rules for /sites/ and a different set for /otherstuff/.

I'm pretty sure that in any context where your pattern involves the requested URL and/or filepath, the module will recognize either ^/blahblah or ^blahblah, but not both; I don't think the leading / is ever optional with an anchor.
 

Join The Conversation

Moderators and Top Contributors

Hot Threads This Week

Featured Threads

Free SEO Tools

Hire Expert Members