summaryrefslogtreecommitdiffstats
path: root/toolkit/actors/AboutHttpsOnlyErrorChild.sys.mjs
blob: 20313d30c04bdff51f3a767943eb31d4cda494e0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";

import { RemotePageChild } from "resource://gre/actors/RemotePageChild.sys.mjs";

const lazy = {};

XPCOMUtils.defineLazyServiceGetter(
  lazy,
  "@mozilla.org/network/serialization-helper;1",
  "nsISerializationHelper"
);

export class AboutHttpsOnlyErrorChild extends RemotePageChild {
  actorCreated() {
    super.actorCreated();

    // If you add a new function, remember to add it to RemotePageAccessManager.sys.mjs
    // to allow content-privileged about:httpsonlyerror to use it.
    const exportableFunctions = [
      "RPMTryPingSecureWWWLink",
      "RPMOpenSecureWWWLink",
    ];
    this.exportFunctions(exportableFunctions);
  }

  RPMTryPingSecureWWWLink() {
    // try if the page can be reached with www prefix
    // if so send message to the parent to send message to the error page to display
    // suggestion button for www

    const httpsOnlySuggestionPref = Services.prefs.getBoolPref(
      "dom.security.https_only_mode_error_page_user_suggestions"
    );

    // only check if pref is true otherwise return
    if (!httpsOnlySuggestionPref) {
      return;
    }

    // get the host url without the path with www in front
    const wwwURL = "https://www." + this.contentWindow.location.host;
    fetch(wwwURL, {
      credentials: "omit",
      cache: "no-store",
    })
      .then(data => {
        if (data.status === 200) {
          this.contentWindow.dispatchEvent(
            new this.contentWindow.CustomEvent("pingSecureWWWLinkSuccess")
          );
        }
      })
      .catch(() => {
        dump("No secure www suggestion possible for " + wwwURL);
      });
  }

  RPMOpenSecureWWWLink() {
    // if user wants to visit suggested secure www page: visit page with www prefix and delete errorpage from history
    const context = this.manager.browsingContext;
    const docShell = context.docShell;
    const httpChannel = docShell.failedChannel.QueryInterface(
      Ci.nsIHttpChannel
    );
    const webNav = docShell.QueryInterface(Ci.nsIWebNavigation);
    const triggeringPrincipal =
      docShell.failedChannel.loadInfo.triggeringPrincipal;
    const oldURI = httpChannel.URI;
    const newWWWURI = oldURI
      .mutate()
      .setHost("www." + oldURI.host)
      .finalize();

    webNav.loadURI(newWWWURI, {
      triggeringPrincipal,
      loadFlags: Ci.nsIWebNavigation.LOAD_FLAGS_REPLACE_HISTORY,
    });
  }
}