Bug 1050329 - part 2 - Add error page for h2 goaway. r=dragana,bzbarsky
authorNicholas Hurley <hurley@mozilla.com>
Thu, 25 Oct 2018 20:46:46 +0000
changeset 443052 8ee3ec2214429e42c473844b86c8c1cbd0d94d15
parent 443051 dd75cefee794aaaef19940f717f69fc70f9a3ff0
child 443053 54a37700d0e65b0a5a30aa920ae41b35cbeb7633
push id34935
push userccoroiu@mozilla.com
push dateFri, 26 Oct 2018 04:43:55 +0000
treeherdermozilla-central@d0b577458d53 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdragana, bzbarsky
bugs1050329
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1050329 - part 2 - Add error page for h2 goaway. r=dragana,bzbarsky This is kind of like the previous patch (where we had a not-very-friendly user experience shutting down misbehaving h2 sessions), but in this case the server has proven to us that it can speak a minimum of h2, so we don't want to just fallback. Instead, when we send a GOAWAY frame because we have detected some error on the part of the server, if it's a top-level page load, we'll show an error page explaining that the server spoke bad http/2, and the site admin(s) need to be contacted. We already did this for INADEQUATE_SECURITY (which is its own special case still), but that didn't cover all the cases. Differential Revision: https://phabricator.services.mozilla.com/D8436
browser/base/content/aboutNetError-new.xhtml
browser/base/content/aboutNetError.xhtml
browser/locales/en-US/chrome/overrides/appstrings.properties
browser/locales/en-US/chrome/overrides/netError.dtd
docshell/base/nsDocShell.cpp
docshell/resources/content/netError.xhtml
dom/locales/en-US/chrome/appstrings.properties
dom/locales/en-US/chrome/netError.dtd
mobile/android/chrome/content/netError.xhtml
mobile/locales/en-US/overrides/appstrings.properties
mobile/locales/en-US/overrides/netError.dtd
netwerk/protocol/http/Http2Session.cpp
xpcom/base/ErrorList.py
--- a/browser/base/content/aboutNetError-new.xhtml
+++ b/browser/base/content/aboutNetError-new.xhtml
@@ -64,16 +64,17 @@
         <h1 id="et_nssBadCert_sts">&certerror.sts.longpagetitle;</h1>
         <h1 id="et_cspBlocked">&cspBlocked.title;</h1>
         <h1 id="et_remoteXUL">&remoteXUL.title;</h1>
         <h1 id="et_corruptedContentErrorv2">&corruptedContentErrorv2.title;</h1>
         <h1 id="et_sslv3Used">&sslv3Used.title;</h1>
         <h1 id="et_inadequateSecurityError">&inadequateSecurityError.title;</h1>
         <h1 id="et_blockedByPolicy">&blockedByPolicy.title;</h1>
         <h1 id="et_clockSkewError">&clockSkewError.title;</h1>
+        <h1 id="et_networkProtocolError">&networkProtocolError.title;</h1>
       </div>
       <div id="errorDescriptionsContainer">
         <div id="ed_generic">&generic.longDesc;</div>
         <div id="ed_captivePortal">&captivePortal.longDesc2;</div>
         <div id="ed_dnsNotFound">&dnsNotFound.longDesc1;</div>
         <div id="ed_fileNotFound">&fileNotFound.longDesc;</div>
         <div id="ed_fileAccessDenied">&fileAccessDenied.longDesc;</div>
         <div id="ed_malformedURI"></div>
@@ -97,16 +98,17 @@
         <div id="ed_nssBadCert_SEC_ERROR_EXPIRED_CERTIFICATE">&certerror.expiredCert.introPara;</div>
         <div id="ed_cspBlocked">&cspBlocked.longDesc;</div>
         <div id="ed_remoteXUL">&remoteXUL.longDesc;</div>
         <div id="ed_corruptedContentErrorv2">&corruptedContentErrorv2.longDesc;</div>
         <div id="ed_sslv3Used">&sslv3Used.longDesc2;</div>
         <div id="ed_inadequateSecurityError">&inadequateSecurityError.longDesc;</div>
         <div id="ed_blockedByPolicy"></div>
         <div id="ed_clockSkewError">&clockSkewError.longDesc;</div>
+        <div id="ed_networkProtocolError">&networkProtocolError.longDesc;</div>
       </div>
       <div id="errorDescriptions2Container">
           <div id="ed2_nssBadCert_SEC_ERROR_EXPIRED_CERTIFICATE">&certerror.expiredCert.secondPara2;</div>
           <div id="ed2_nssBadCert_SEC_ERROR_EXPIRED_CERTIFICATE_sts">&certerror.expiredCert.sts.secondPara;</div>
       </div>
       <div id="whatCanYouDoAboutItTitleContainer">
         <div id="edd_nssBadCert"><strong>&certerror.whatCanYouDoAboutItTitle;</strong></div>
       </div>
--- a/browser/base/content/aboutNetError.xhtml
+++ b/browser/base/content/aboutNetError.xhtml
@@ -61,16 +61,17 @@
         <h1 id="et_nssFailure2">&nssFailure2.title;</h1>
         <h1 id="et_nssBadCert">&certerror.longpagetitle1;</h1>
         <h1 id="et_cspBlocked">&cspBlocked.title;</h1>
         <h1 id="et_remoteXUL">&remoteXUL.title;</h1>
         <h1 id="et_corruptedContentErrorv2">&corruptedContentErrorv2.title;</h1>
         <h1 id="et_sslv3Used">&sslv3Used.title;</h1>
         <h1 id="et_inadequateSecurityError">&inadequateSecurityError.title;</h1>
         <h1 id="et_blockedByPolicy">&blockedByPolicy.title;</h1>
+        <h1 id="et_networkProtocolError">&networkProtocolError.title;</h1>
       </div>
       <div id="errorDescriptionsContainer">
         <div id="ed_generic">&generic.longDesc;</div>
         <div id="ed_captivePortal">&captivePortal.longDesc2;</div>
         <div id="ed_dnsNotFound">&dnsNotFound.longDesc1;</div>
         <div id="ed_fileNotFound">&fileNotFound.longDesc;</div>
         <div id="ed_fileAccessDenied">&fileAccessDenied.longDesc;</div>
         <div id="ed_malformedURI"></div>
@@ -91,16 +92,17 @@
         <div id="ed_nssFailure2">&nssFailure2.longDesc2;</div>
         <div id="ed_nssBadCert">&certerror.introPara;</div>
         <div id="ed_cspBlocked">&cspBlocked.longDesc;</div>
         <div id="ed_remoteXUL">&remoteXUL.longDesc;</div>
         <div id="ed_corruptedContentErrorv2">&corruptedContentErrorv2.longDesc;</div>
         <div id="ed_sslv3Used">&sslv3Used.longDesc2;</div>
         <div id="ed_inadequateSecurityError">&inadequateSecurityError.longDesc;</div>
         <div id="ed_blockedByPolicy"></div>
+        <div id="ed_networkProtocolError">&networkProtocolError.longDesc;</div>
       </div>
     </div>
 
     <!-- PAGE CONTAINER (for styling purposes only) -->
     <div id="errorPageContainer" class="container">
       <div id="text-container">
         <!-- Error Title -->
         <div class="title">
--- a/browser/locales/en-US/chrome/overrides/appstrings.properties
+++ b/browser/locales/en-US/chrome/overrides/appstrings.properties
@@ -36,8 +36,9 @@ unwantedBlocked=The site at %S has been 
 deceptiveBlocked=This web page at %S has been reported as a deceptive site and has been blocked based on your security preferences.
 cspBlocked=This page has a content security policy that prevents it from being loaded in this way.
 corruptedContentErrorv2=The site at %S has experienced a network protocol violation that cannot be repaired.
 remoteXUL=This page uses an unsupported technology that is no longer available by default in Firefox.
 ## LOCALIZATION NOTE (sslv3Used) - Do not translate "%S".
 sslv3Used=Firefox cannot guarantee the safety of your data on %S because it uses SSLv3, a broken security protocol.
 inadequateSecurityError=The website tried to negotiate an inadequate level of security.
 blockedByPolicy=Your organization has blocked access to this page or website.
+networkProtocolError=Firefox has experienced a network protocol violation that cannot be repaired.
--- a/browser/locales/en-US/chrome/overrides/netError.dtd
+++ b/browser/locales/en-US/chrome/overrides/netError.dtd
@@ -234,8 +234,11 @@ certificate.">
 
 <!ENTITY blockedByPolicy.title "Blocked Page">
 
 <!ENTITY clockSkewError.title "Your Computer Clock is Wrong">
 <!ENTITY clockSkewError.longDesc "Your computer thinks it is <span id='wrongSystemTime_systemDate1'/>, which prevents &brandShortName; from connecting securely. To visit <span class='hostname'></span>, update your computer clock in your system settings to the current date, time, and time zone, and then refresh <span class='hostname'></span>.">
 
 <!ENTITY prefReset.longDesc "It looks like your network security settings might be causing this. Do you want the default settings to be restored?">
 <!ENTITY prefReset.label "Restore default settings">
+
+<!ENTITY networkProtocolError.title "Network Protocol Error">
+<!ENTITY networkProtocolError.longDesc "<p>The page you are trying to view cannot be shown because an error in the network protocol was detected.</p><ul><li>Please contact the website owners to inform them of this problem.</li></ul>">
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -4699,16 +4699,20 @@ nsDocShell::DisplayLoadError(nsresult aE
         // Server negotiated bad TLS for HTTP/2.
         error = "inadequateSecurityError";
         addHostPort = true;
         break;
       case NS_ERROR_BLOCKED_BY_POLICY:
         // Page blocked by policy
         error = "blockedByPolicy";
         break;
+      case NS_ERROR_NET_HTTP2_SENT_GOAWAY:
+        // HTTP/2 stack detected a protocol error
+        error = "networkProtocolError";
+        break;
       default:
         break;
     }
   }
 
   // Test if the error should be displayed
   if (!error) {
     return NS_OK;
@@ -7428,16 +7432,17 @@ nsDocShell::EndPageLoad(nsIWebProgress* 
                aStatus == NS_ERROR_MALWARE_URI ||
                aStatus == NS_ERROR_PHISHING_URI ||
                aStatus == NS_ERROR_UNWANTED_URI ||
                aStatus == NS_ERROR_HARMFUL_URI ||
                aStatus == NS_ERROR_UNSAFE_CONTENT_TYPE ||
                aStatus == NS_ERROR_REMOTE_XUL ||
                aStatus == NS_ERROR_INTERCEPTION_FAILED ||
                aStatus == NS_ERROR_NET_INADEQUATE_SECURITY ||
+               aStatus == NS_ERROR_NET_HTTP2_SENT_GOAWAY ||
                NS_ERROR_GET_MODULE(aStatus) == NS_ERROR_MODULE_SECURITY) {
       // Errors to be shown for any frame
       DisplayLoadError(aStatus, url, nullptr, aChannel);
     } else if (aStatus == NS_ERROR_DOCUMENT_NOT_CACHED) {
       // Non-caching channels will simply return NS_ERROR_OFFLINE.
       // Caching channels would have to look at their flags to work
       // out which error to return. Or we can fix up the error here.
       if (!(mLoadType & LOAD_CMD_HISTORY)) {
--- a/docshell/resources/content/netError.xhtml
+++ b/docshell/resources/content/netError.xhtml
@@ -56,16 +56,17 @@
         <h1 id="et_unsafeContentType">&unsafeContentType.title;</h1>
         <h1 id="et_nssFailure2">&nssFailure2.title;</h1>
         <h1 id="et_nssBadCert">&nssBadCert.title;</h1>
         <h1 id="et_cspBlocked">&cspBlocked.title;</h1>
         <h1 id="et_remoteXUL">&remoteXUL.title;</h1>
         <h1 id="et_corruptedContentErrorv2">&corruptedContentErrorv2.title;</h1>
         <h1 id="et_inadequateSecurityError">&inadequateSecurityError.title;</h1>
         <h1 id="et_blockedByPolicy">&blockedByPolicy.title;</h1>
+        <h1 id="et_networkProtocolError">&networkProtocolError.title;</h1>
       </div>
       <div id="errorDescriptionsContainer">
         <div id="ed_generic">&generic.longDesc;</div>
         <div id="ed_dnsNotFound">&dnsNotFound.longDesc;</div>
         <div id="ed_fileNotFound">&fileNotFound.longDesc;</div>
         <div id="ed_fileAccessDenied">&fileAccessDenied.longDesc;</div>
         <div id="ed_malformedURI">&malformedURI.longDesc;</div>
         <div id="ed_unknownProtocolFound">&unknownProtocolFound.longDesc;</div>
@@ -84,16 +85,17 @@
         <div id="ed_unsafeContentType">&unsafeContentType.longDesc;</div>
         <div id="ed_nssFailure2">&nssFailure2.longDesc2;</div>
         <div id="ed_nssBadCert">&nssBadCert.longDesc2;</div>
         <div id="ed_cspBlocked">&cspBlocked.longDesc;</div>
         <div id="ed_remoteXUL">&remoteXUL.longDesc;</div>
         <div id="ed_corruptedContentErrorv2">&corruptedContentErrorv2.longDesc;</div>
         <div id="ed_inadequateSecurityError">&inadequateSecurityError.longDesc;</div>
         <div id="ed_blockedByPolicy"></div>
+        <div id="ed_networkProtocolError">&networkProtocolError.longDesc;</div>
       </div>
     </div>
 
     <!-- PAGE CONTAINER (for styling purposes only) -->
     <div id="errorPageContainer">
 
       <!-- Error Title -->
       <div id="errorTitle">
--- a/dom/locales/en-US/chrome/appstrings.properties
+++ b/dom/locales/en-US/chrome/appstrings.properties
@@ -34,8 +34,9 @@ unwantedBlocked=The site at %S has been 
 deceptiveBlocked=This web page at %S has been reported as a deceptive site and has been blocked based on your security preferences.
 cspBlocked=This page has a content security policy that prevents it from being loaded in this way.
 corruptedContentErrorv2=The site at %S has experienced a network protocol violation that cannot be repaired.
 remoteXUL=This page uses an unsupported technology that is no longer available by default.
 sslv3Used=The safety of your data on %S could not be guaranteed because it uses SSLv3, a broken security protocol.
 weakCryptoUsed=The owner of %S has configured their website improperly. To protect your information from being stolen, the connection to this website has not been established.
 inadequateSecurityError=The website tried to negotiate an inadequate level of security.
 blockedByPolicy=Your organization has blocked access to this page or website.
+networkProtocolError=Firefox has experienced a network protocol violation that cannot be repaired.
--- a/dom/locales/en-US/chrome/netError.dtd
+++ b/dom/locales/en-US/chrome/netError.dtd
@@ -94,8 +94,11 @@
 <!ENTITY remoteXUL.longDesc "<p><ul><li>Please contact the website owners to inform them of this problem.</li></ul></p>">
 
 <!ENTITY inadequateSecurityError.title "Your connection is not secure">
 <!-- LOCALIZATION NOTE (inadequateSecurityError.longDesc) - Do not translate
      "NS_ERROR_NET_INADEQUATE_SECURITY". -->
 <!ENTITY inadequateSecurityError.longDesc "<p><span class='hostname'></span> uses security technology that is outdated and vulnerable to attack. An attacker could easily reveal information which you thought to be safe. The website administrator will need to fix the server first before you can visit the site.</p><p>Error code: NS_ERROR_NET_INADEQUATE_SECURITY</p>">
 
 <!ENTITY blockedByPolicy.title "Blocked Page">
+
+<!ENTITY networkProtocolError.title "Network Protocol Error">
+<!ENTITY networkProtocolError.longDesc "<p>The page you are trying to view cannot be shown because an error in the network protocol was detected.</p><ul><li>Please contact the website owners to inform them of this problem.</li></ul>">
--- a/mobile/android/chrome/content/netError.xhtml
+++ b/mobile/android/chrome/content/netError.xhtml
@@ -229,16 +229,17 @@
         <h1 id="et_nssFailure2">&nssFailure2.title;</h1>
         <h1 id="et_nssBadCert">&nssBadCert.title;</h1>
         <h1 id="et_cspBlocked">&cspBlocked.title;</h1>
         <h1 id="et_remoteXUL">&remoteXUL.title;</h1>
         <h1 id="et_corruptedContentErrorv2">&corruptedContentErrorv2.title;</h1>
         <h1 id="et_sslv3Used">&sslv3Used.title;</h1>
         <h1 id="et_weakCryptoUsed">&weakCryptoUsed.title;</h1>
         <h1 id="et_inadequateSecurityError">&inadequateSecurityError.title;</h1>
+        <h1 id="et_networkProtocolError">&networkProtocolError.title;</h1>
       </div>
       <div id="errorDescriptionsContainer">
         <div id="ed_generic">&generic.longDesc;</div>
         <div id="ed_dnsNotFound">&dnsNotFound.longDesc4;</div>
         <div id="ed_fileNotFound">&fileNotFound.longDesc;</div>
         <div id="ed_fileAccessDenied">&fileAccessDenied.longDesc;</div>
         <div id="ed_malformedURI">&malformedURI.longDesc2;</div>
         <div id="ed_unknownProtocolFound">&unknownProtocolFound.longDesc;</div>
@@ -262,16 +263,17 @@
         <div id="ed_nssFailure2">&nssFailure2.longDesc2;</div>
         <div id="ed_nssBadCert">&nssBadCert.longDesc2;</div>
         <div id="ed_cspBlocked">&cspBlocked.longDesc;</div>
         <div id="ed_remoteXUL">&remoteXUL.longDesc;</div>
         <div id="ed_corruptedContentErrorv2">&corruptedContentErrorv2.longDesc;</div>
         <div id="ed_sslv3Used">&sslv3Used.longDesc;</div>
         <div id="ed_weakCryptoUsed">&weakCryptoUsed.longDesc;</div>
         <div id="ed_inadequateSecurityError">&inadequateSecurityError.longDesc;</div>
+        <div id="ed_networkProtocolError">&networkProtocolError.longDesc;</div>
       </div>
     </div>
 
     <!-- PAGE CONTAINER (for styling purposes only) -->
     <div id="errorPageContainer">
 
       <!-- Error Title -->
       <div id="errorTitle">
--- a/mobile/locales/en-US/overrides/appstrings.properties
+++ b/mobile/locales/en-US/overrides/appstrings.properties
@@ -35,8 +35,9 @@ harmfulBlocked=The site at %S has been r
 deceptiveBlocked=This web page at %S has been reported as a deceptive site and has been blocked based on your security preferences.
 unwantedBlocked=The site at %S has been reported as serving unwanted software and has been blocked based on your security preferences.
 cspBlocked=This page has a content security policy that prevents it from being loaded in this way.
 corruptedContentErrorv2=The site at %S has experienced a network protocol violation that cannot be repaired.
 remoteXUL=This page uses an unsupported technology that is no longer available by default in Firefox.
 sslv3Used=Firefox cannot guarantee the safety of your data on %S because it uses SSLv3, a broken security protocol.
 weakCryptoUsed=The owner of %S has configured their website improperly. To protect your information from being stolen, Firefox has not connected to this website.
 inadequateSecurityError=The website tried to negotiate an inadequate level of security.
+networkProtocolError=Firefox has experienced a network protocol violation that cannot be repaired.
--- a/mobile/locales/en-US/overrides/netError.dtd
+++ b/mobile/locales/en-US/overrides/netError.dtd
@@ -215,8 +215,11 @@ netError.xhtml) because it exposes funct
 <!-- LOCALIZATION NOTE (weakCryptoUsed.longDesc) - Do not translate
      "SSL_ERROR_NO_CYPHER_OVERLAP". -->
 <!ENTITY weakCryptoUsed.longDesc "Advanced info: SSL_ERROR_NO_CYPHER_OVERLAP">
 
 <!ENTITY inadequateSecurityError.title "Your connection is not secure">
 <!-- LOCALIZATION NOTE (inadequateSecurityError.longDesc) - Do not translate
      "NS_ERROR_NET_INADEQUATE_SECURITY". -->
 <!ENTITY inadequateSecurityError.longDesc "<p><span class='hostname'></span> uses security technology that is outdated and vulnerable to attack. An attacker could easily reveal information which you thought to be safe. The website administrator will need to fix the server first before you can visit the site.</p><p>Error code: NS_ERROR_NET_INADEQUATE_SECURITY</p>">
+
+<!ENTITY networkProtocolError.title "Network Protocol Error">
+<!ENTITY networkProtocolError.longDesc "<p>The page you are trying to view cannot be shown because an error in the network protocol was detected.</p><ul><li>Please contact the website owners to inform them of this problem.</li></ul>">
--- a/netwerk/protocol/http/Http2Session.cpp
+++ b/netwerk/protocol/http/Http2Session.cpp
@@ -157,16 +157,18 @@ Http2Session::Shutdown()
     // restarted.
     if (mCleanShutdown &&
         (stream->StreamID() > mGoAwayID || !stream->HasRegisteredID())) {
       CloseStream(stream, NS_ERROR_NET_RESET);  // can be restarted
     } else if (stream->RecvdData()) {
       CloseStream(stream, NS_ERROR_NET_PARTIAL_TRANSFER);
     } else if (mGoAwayReason == INADEQUATE_SECURITY) {
       CloseStream(stream, NS_ERROR_NET_INADEQUATE_SECURITY);
+    } else if (!mCleanShutdown) {
+      CloseStream(stream, NS_ERROR_NET_HTTP2_SENT_GOAWAY);
     } else {
       CloseStream(stream, NS_ERROR_ABORT);
     }
   }
 }
 
 Http2Session::~Http2Session()
 {
@@ -185,18 +187,27 @@ Http2Session::~Http2Session()
   Telemetry::Accumulate(Telemetry::SPDY_GOAWAY_LOCAL, mClientGoAwayReason);
   Telemetry::Accumulate(Telemetry::SPDY_GOAWAY_PEER, mPeerGoAwayReason);
   Telemetry::Accumulate(Telemetry::HTTP2_FAIL_BEFORE_SETTINGS, mPeerFailedHandshake);
 }
 
 inline nsresult
 Http2Session::SessionError(enum errorType reason)
 {
+  LOG3(("Http2Session::SessionError %p reason=0x%x mPeerGoAwayReason=0x%x",
+        this, reason, mPeerGoAwayReason));
   mGoAwayReason = reason;
-  return NS_ERROR_ILLEGAL_VALUE;
+
+  if (reason == INADEQUATE_SECURITY) {
+    // This one is special, as we have an error page just for this
+    return NS_ERROR_NET_INADEQUATE_SECURITY;
+  }
+
+  // We're the one sending a generic GOAWAY
+  return NS_ERROR_NET_HTTP2_SENT_GOAWAY;
 }
 
 void
 Http2Session::LogIO(Http2Session *self, Http2Stream *stream,
                     const char *label,
                     const char *data, uint32_t datalen)
 {
   if (!LOG5_ENABLED())
--- a/xpcom/base/ErrorList.py
+++ b/xpcom/base/ErrorList.py
@@ -332,16 +332,18 @@ with modules["NETWORK"]:
     # The connection was established, but the data transfer was interrupted.
     errors["NS_ERROR_NET_INTERRUPT"] = FAILURE(71)
     # The connection attempt to a proxy failed.
     errors["NS_ERROR_PROXY_CONNECTION_REFUSED"] = FAILURE(72)
     # A transfer was only partially done when it completed.
     errors["NS_ERROR_NET_PARTIAL_TRANSFER"] = FAILURE(76)
     # HTTP/2 detected invalid TLS configuration
     errors["NS_ERROR_NET_INADEQUATE_SECURITY"] = FAILURE(82)
+    # HTTP/2 sent a GOAWAY
+    errors["NS_ERROR_NET_HTTP2_SENT_GOAWAY"] = FAILURE(83)
 
     # XXX really need to better rationalize these error codes.  are consumers of
     # necko really expected to know how to discern the meaning of these??
     # This request is not resumable, but it was tried to resume it, or to
     # request resume-specific data.
     errors["NS_ERROR_NOT_RESUMABLE"] = FAILURE(25)
     # The request failed as a result of a detected redirection loop.
     errors["NS_ERROR_REDIRECT_LOOP"] = FAILURE(31)