Wed, 31 Dec 2014 07:22:50 +0100
Correct previous dual key logic pending first delivery installment.
1 <?xml version="1.0" encoding="UTF-8"?>
3 <!DOCTYPE html [
4 <!ENTITY % htmlDTD
5 PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
6 "DTD/xhtml1-strict.dtd">
7 %htmlDTD;
8 <!ENTITY % netErrorDTD
9 SYSTEM "chrome://global/locale/netError.dtd">
10 %netErrorDTD;
11 <!ENTITY % globalDTD
12 SYSTEM "chrome://global/locale/global.dtd">
13 %globalDTD;
14 ]>
16 <!-- This Source Code Form is subject to the terms of the Mozilla Public
17 - License, v. 2.0. If a copy of the MPL was not distributed with this
18 - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
20 <html xmlns="http://www.w3.org/1999/xhtml">
21 <head>
22 <meta name="viewport" content="width=device-width; user-scalable=false;" />
23 <title>&loadError.label;</title>
24 <link rel="stylesheet" href="chrome://global/skin/netError.css" type="text/css" media="all" />
25 <!-- If the location of the favicon is changed here, the FAVICON_ERRORPAGE_URL symbol in
26 toolkit/components/places/src/nsFaviconService.h should be updated. -->
27 <link rel="icon" type="image/png" id="favicon" sizes="64x64" href="chrome://browser/skin/images/errorpage-warning.png"/>
29 <script type="application/javascript"><![CDATA[
30 // Error url MUST be formatted like this:
31 // moz-neterror:page?e=error&u=url&d=desc
32 //
33 // or optionally, to specify an alternate CSS class to allow for
34 // custom styling and favicon:
35 //
36 // moz-neterror:page?e=error&u=url&s=classname&d=desc
38 // Note that this file uses document.documentURI to get
39 // the URL (with the format from above). This is because
40 // document.location.href gets the current URI off the docshell,
41 // which is the URL displayed in the location bar, i.e.
42 // the URI that the user attempted to load.
44 function getErrorCode()
45 {
46 var url = document.documentURI;
47 var error = url.search(/e\=/);
48 var duffUrl = url.search(/\&u\=/);
49 return decodeURIComponent(url.slice(error + 2, duffUrl));
50 }
52 function getCSSClass()
53 {
54 var url = document.documentURI;
55 var matches = url.match(/s\=([^&]+)\&/);
56 // s is optional, if no match just return nothing
57 if (!matches || matches.length < 2)
58 return "";
60 // parenthetical match is the second entry
61 return decodeURIComponent(matches[1]);
62 }
64 function getDescription()
65 {
66 var url = document.documentURI;
67 var desc = url.search(/d\=/);
69 // desc == -1 if not found; if so, return an empty string
70 // instead of what would turn out to be portions of the URI
71 if (desc == -1)
72 return "";
74 return decodeURIComponent(url.slice(desc + 2));
75 }
77 function retryThis(buttonEl)
78 {
79 // Note: The application may wish to handle switching off "offline mode"
80 // before this event handler runs, but using a capturing event handler.
82 // Session history has the URL of the page that failed
83 // to load, not the one of the error page. So, just call
84 // reload(), which will also repost POST data correctly.
85 try {
86 location.reload();
87 } catch (e) {
88 // We probably tried to reload a URI that caused an exception to
89 // occur; e.g. a nonexistent file.
90 }
92 buttonEl.disabled = true;
93 }
95 function initPage()
96 {
97 var err = getErrorCode();
99 // if it's an unknown error or there's no title or description
100 // defined, get the generic message
101 var errTitle = document.getElementById("et_" + err);
102 var errDesc = document.getElementById("ed_" + err);
103 if (!errTitle || !errDesc)
104 {
105 errTitle = document.getElementById("et_generic");
106 errDesc = document.getElementById("ed_generic");
107 }
109 var title = document.getElementsByClassName("errorTitleText")[0];
110 if (title)
111 {
112 title.parentNode.replaceChild(errTitle, title);
113 // change id to the replaced child's id so styling works
114 errTitle.classList.add("errorTitleText");
115 }
117 var sd = document.getElementById("errorShortDescText");
118 if (sd)
119 sd.textContent = getDescription();
121 var ld = document.getElementById("errorLongDesc");
122 if (ld)
123 {
124 ld.parentNode.replaceChild(errDesc, ld);
125 // change id to the replaced child's id so styling works
126 errDesc.id = "errorLongDesc";
127 }
129 // remove undisplayed errors to avoid bug 39098
130 var errContainer = document.getElementById("errorContainer");
131 errContainer.parentNode.removeChild(errContainer);
133 var className = getCSSClass();
134 if (className && className != "expertBadCert") {
135 // Associate a CSS class with the root of the page, if one was passed in,
136 // to allow custom styling.
137 // Not "expertBadCert" though, don't want to deal with the favicon
138 document.documentElement.className = className;
140 // Also, if they specified a CSS class, they must supply their own
141 // favicon. In order to trigger the browser to repaint though, we
142 // need to remove/add the link element.
143 var favicon = document.getElementById("favicon");
144 var faviconParent = favicon.parentNode;
145 faviconParent.removeChild(favicon);
146 favicon.setAttribute("href", "chrome://global/skin/icons/" + className + "_favicon.png");
147 faviconParent.appendChild(favicon);
148 }
149 if (className == "expertBadCert") {
150 showSecuritySection();
151 }
153 if (err == "remoteXUL") {
154 // Remove the "Try again" button for remote XUL errors given that
155 // it is useless.
156 document.getElementById("errorTryAgain").style.display = "none";
157 }
159 if (err == "cspFrameAncestorBlocked") {
160 // Remove the "Try again" button for CSP frame ancestors violation, since it's
161 // almost certainly useless. (Bug 553180)
162 document.getElementById("errorTryAgain").style.display = "none";
163 }
165 if (err == "nssBadCert") {
166 // Remove the "Try again" button for security exceptions, since it's
167 // almost certainly useless.
168 document.getElementById("errorTryAgain").style.display = "none";
169 document.getElementById("errorPage").setAttribute("class", "certerror");
170 addDomainErrorLink();
171 }
172 else {
173 // Remove the override block for non-certificate errors. CSS-hiding
174 // isn't good enough here, because of bug 39098
175 var secOverride = document.getElementById("securityOverrideDiv");
176 secOverride.parentNode.removeChild(secOverride);
177 }
178 }
180 function showSecuritySection() {
181 // Swap link out, content in
182 document.getElementById('securityOverrideContent').style.display = '';
183 document.getElementById('securityOverrideLink').style.display = 'none';
184 }
186 /* In the case of SSL error pages about domain mismatch, see if
187 we can hyperlink the user to the correct site. We don't want
188 to do this generically since it allows MitM attacks to redirect
189 users to a site under attacker control, but in certain cases
190 it is safe (and helpful!) to do so. Bug 402210
191 */
192 function addDomainErrorLink() {
193 // Rather than textContent, we need to treat description as HTML
194 var sd = document.getElementById("errorShortDescText");
195 if (sd) {
196 var desc = getDescription();
198 // sanitize description text - see bug 441169
200 // First, find the index of the <a> tag we care about, being careful not to
201 // use an over-greedy regex
202 var re = /<a id="cert_domain_link" title="([^"]+)">/;
203 var result = re.exec(desc);
204 if(!result)
205 return;
207 // Remove sd's existing children
208 sd.textContent = "";
210 // Everything up to the link should be text content
211 sd.appendChild(document.createTextNode(desc.slice(0, result.index)));
213 // Now create the link itself
214 var anchorEl = document.createElement("a");
215 anchorEl.setAttribute("id", "cert_domain_link");
216 anchorEl.setAttribute("title", result[1]);
217 anchorEl.appendChild(document.createTextNode(result[1]));
218 sd.appendChild(anchorEl);
220 // Finally, append text for anything after the closing </a>
221 sd.appendChild(document.createTextNode(desc.slice(desc.indexOf("</a>") + "</a>".length)));
222 }
224 var link = document.getElementById('cert_domain_link');
225 if (!link)
226 return;
228 var okHost = link.getAttribute("title");
229 var thisHost = document.location.hostname;
230 var proto = document.location.protocol;
232 // If okHost is a wildcard domain ("*.example.com") let's
233 // use "www" instead. "*.example.com" isn't going to
234 // get anyone anywhere useful. bug 432491
235 okHost = okHost.replace(/^\*\./, "www.");
237 /* case #1:
238 * example.com uses an invalid security certificate.
239 *
240 * The certificate is only valid for www.example.com
241 *
242 * Make sure to include the "." ahead of thisHost so that
243 * a MitM attack on paypal.com doesn't hyperlink to "notpaypal.com"
244 *
245 * We'd normally just use a RegExp here except that we lack a
246 * library function to escape them properly (bug 248062), and
247 * domain names are famous for having '.' characters in them,
248 * which would allow spurious and possibly hostile matches.
249 */
250 if (endsWith(okHost, "." + thisHost))
251 link.href = proto + okHost;
253 /* case #2:
254 * browser.garage.maemo.org uses an invalid security certificate.
255 *
256 * The certificate is only valid for garage.maemo.org
257 */
258 if (endsWith(thisHost, "." + okHost))
259 link.href = proto + okHost;
260 }
262 function endsWith(haystack, needle) {
263 return haystack.slice(-needle.length) == needle;
264 }
266 ]]></script>
267 </head>
269 <body id="errorPage" dir="&locale.dir;">
271 <!-- ERROR ITEM CONTAINER (removed during loading to avoid bug 39098) -->
272 <div id="errorContainer">
273 <div id="errorTitlesContainer">
274 <h1 id="et_generic">&generic.title;</h1>
275 <h1 id="et_dnsNotFound">&dnsNotFound.title;</h1>
276 <h1 id="et_fileNotFound">&fileNotFound.title;</h1>
277 <h1 id="et_malformedURI">&malformedURI.title;</h1>
278 <h1 id="et_unknownProtocolFound">&unknownProtocolFound.title;</h1>
279 <h1 id="et_connectionFailure">&connectionFailure.title;</h1>
280 <h1 id="et_netTimeout">&netTimeout.title;</h1>
281 <h1 id="et_redirectLoop">&redirectLoop.title;</h1>
282 <h1 id="et_unknownSocketType">&unknownSocketType.title;</h1>
283 <h1 id="et_netReset">&netReset.title;</h1>
284 <h1 id="et_notCached">¬Cached.title;</h1>
286 <!-- Since Fennec not yet have offline mode, change the title to
287 connectionFailure to prevent confusion -->
288 <h1 id="et_netOffline">&connectionFailure.title;</h1>
290 <h1 id="et_netInterrupt">&netInterrupt.title;</h1>
291 <h1 id="et_deniedPortAccess">&deniedPortAccess.title;</h1>
292 <h1 id="et_proxyResolveFailure">&proxyResolveFailure.title;</h1>
293 <h1 id="et_proxyConnectFailure">&proxyConnectFailure.title;</h1>
294 <h1 id="et_contentEncodingError">&contentEncodingError.title;</h1>
295 <h1 id="et_unsafeContentType">&unsafeContentType.title;</h1>
296 <h1 id="et_nssFailure2">&nssFailure2.title;</h1>
297 <h1 id="et_nssBadCert">&nssBadCert.title;</h1>
298 <h1 id="et_cspFrameAncestorBlocked">&cspFrameAncestorBlocked.title;</h1>
299 <h1 id="et_remoteXUL">&remoteXUL.title;</h1>
300 <h1 id="et_corruptedContentError">&corruptedContentError.title;</h1>
301 </div>
302 <div id="errorDescriptionsContainer">
303 <div id="ed_generic">&generic.longDesc;</div>
304 <div id="ed_dnsNotFound">&dnsNotFound.longDesc2;</div>
305 <div id="ed_fileNotFound">&fileNotFound.longDesc;</div>
306 <div id="ed_malformedURI">&malformedURI.longDesc;</div>
307 <div id="ed_unknownProtocolFound">&unknownProtocolFound.longDesc;</div>
308 <div id="ed_connectionFailure">&connectionFailure.longDesc;</div>
309 <div id="ed_netTimeout">&netTimeout.longDesc;</div>
310 <div id="ed_redirectLoop">&redirectLoop.longDesc;</div>
311 <div id="ed_unknownSocketType">&unknownSocketType.longDesc;</div>
312 <div id="ed_netReset">&netReset.longDesc;</div>
313 <div id="ed_notCached">¬Cached.longDesc;</div>
315 <!-- Change longDesc from netOffline to connectionFailure,
316 suggesting user to check their wifi/cell_data connection -->
317 <div id="ed_netOffline">&connectionFailure.longDesc;</div>
319 <div id="ed_netInterrupt">&netInterrupt.longDesc;</div>
320 <div id="ed_deniedPortAccess">&deniedPortAccess.longDesc;</div>
321 <div id="ed_proxyResolveFailure">&proxyResolveFailure.longDesc2;</div>
322 <div id="ed_proxyConnectFailure">&proxyConnectFailure.longDesc;</div>
323 <div id="ed_contentEncodingError">&contentEncodingError.longDesc;</div>
324 <div id="ed_unsafeContentType">&unsafeContentType.longDesc;</div>
325 <div id="ed_nssFailure2">&nssFailure2.longDesc;</div>
326 <div id="ed_nssBadCert">&nssBadCert.longDesc2;</div>
327 <div id="ed_cspFrameAncestorBlocked">&cspFrameAncestorBlocked.longDesc;</div>
328 <div id="ed_remoteXUL">&remoteXUL.longDesc;</div>
329 <div id="ed_corruptedContentError">&corruptedContentError.longDesc;</div>
330 </div>
331 </div>
333 <!-- PAGE CONTAINER (for styling purposes only) -->
334 <div id="errorPageContainer">
336 <!-- Error Title -->
337 <div id="errorTitle">
338 <h1 class="errorTitleText" />
339 </div>
341 <!-- LONG CONTENT (the section most likely to require scrolling) -->
342 <div id="errorLongContent">
344 <!-- Short Description -->
345 <div id="errorShortDesc">
346 <p id="errorShortDescText" />
347 </div>
349 <!-- Long Description (Note: See netError.dtd for used XHTML tags) -->
350 <div id="errorLongDesc" />
352 <!-- Override section - For ssl errors only. Removed on init for other
353 error types. -->
354 <div id="securityOverrideDiv">
355 <a id="securityOverrideLink" href="javascript:showSecuritySection();" >&securityOverride.linkText;</a>
356 <div id="securityOverrideContent" style="display: none;">&securityOverride.warningContent;</div>
357 </div>
358 </div>
360 <!-- Retry Button -->
361 <button id="errorTryAgain" onclick="retryThis(this);">&retry.label;</button>
363 </div>
365 <!--
366 - Note: It is important to run the script this way, instead of using
367 - an onload handler. This is because error pages are loaded as
368 - LOAD_BACKGROUND, which means that onload handlers will not be executed.
369 -->
370 <script type="application/javascript">initPage();</script>
372 </body>
373 </html>