Merge mozilla-central to autoland. a=merge on a CLOSED TREE
authorRazvan Maries <rmaries@mozilla.com>
Thu, 20 Dec 2018 00:01:42 +0200
changeset 451404 3e8d6cb4fd38bfea0ebbc2555c6ca9ef60175038
parent 451403 b7d436b51196c02130a9cef9acb67d4b5c17693e (current diff)
parent 451377 951340085daf6eabaff4a3098ac064fdbebb38d0 (diff)
child 451405 adad39927668ea74fdfc72aa3dd3571e9d1a2043
push id35237
push userrmaries@mozilla.com
push dateThu, 20 Dec 2018 04:52:39 +0000
treeherdermozilla-central@1260c07d4b17 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone66.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
Merge mozilla-central to autoland. a=merge on a CLOSED TREE
docshell/base/nsDocShell.cpp
netwerk/base/nsPILoadGroupInternal.idl
testing/web-platform/meta/fetch/api/basic/request-headers-case.any.js.ini
--- a/build/moz.configure/toolchain.configure
+++ b/build/moz.configure/toolchain.configure
@@ -1594,16 +1594,18 @@ option('--enable-hardening', env='MOZ_SE
 
 @depends('--enable-hardening', '--enable-address-sanitizer',
          '--enable-optimize', c_compiler, target)
 def security_hardening_cflags(hardening_flag, asan, optimize, c_compiler, target):
     compiler_is_gccish = c_compiler.type in ('gcc', 'clang')
 
     flags = []
     js_flags = []
+    ldflags = []
+    js_ldflags = []
 
     # FORTIFY_SOURCE ------------------------------------
     # If hardening is explicitly enabled, or not explicitly disabled
     if hardening_flag.origin == "default" or hardening_flag:
         # Require optimization for FORTIFY_SOURCE. See Bug 1417452
         # Also, undefine it before defining it just in case a distro adds it, see Bug 1418398
         if compiler_is_gccish and optimize and not asan:
             # Don't enable FORTIFY_SOURCE on Android on the top-level, but do enable in js/
@@ -1616,37 +1618,49 @@ def security_hardening_cflags(hardening_
         # fstack-protector ------------------------------------
         # Enable only if hardening is not disabled and ASAN is
         # not on as ASAN will catch the crashes for us
         if compiler_is_gccish and not asan:
             # mingw-clang cross-compile toolchain has bugs with stack protector
             if target.os != 'WINNT' or c_compiler == 'gcc':
                 flags.append("-fstack-protector-strong")
 
+        if c_compiler.type == 'clang-cl':
+            flags.append("-guard:cf")
+            js_flags.append("-guard:cf")
+            # nolongjmp is needed because clang doesn't emit the CFG tables of
+            # setjmp return addresses https://bugs.llvm.org/show_bug.cgi?id=40057
+            ldflags.append("-guard:cf,nolongjmp")
+            js_ldflags.append("-guard:cf,nolongjmp")
+
     # If ASAN _is_ on, undefine FOTIFY_SOURCE just to be safe
     if asan:
         flags.append("-U_FORTIFY_SOURCE")
         js_flags.append("-U_FORTIFY_SOURCE")
 
     # fno-common -----------------------------------------
     # Do not merge variables for ASAN; can detect some subtle bugs
     if asan:
         # clang-cl does not recognize the flag, it must be passed down to clang
         if c_compiler.type == 'clang-cl':
             flags.append("-Xclang")
         flags.append("-fno-common")
 
     return namespace(
         flags=flags,
+        ldflags=ldflags,
         js_flags=js_flags,
+        js_ldflags=js_ldflags,
     )
 
 
 add_old_configure_assignment('MOZ_HARDENING_CFLAGS', security_hardening_cflags.flags)
+add_old_configure_assignment('MOZ_HARDENING_LDFLAGS', security_hardening_cflags.ldflags)
 add_old_configure_assignment('MOZ_HARDENING_CFLAGS_JS', security_hardening_cflags.js_flags)
+add_old_configure_assignment('MOZ_HARDENING_LDFLAGS_JS', security_hardening_cflags.js_ldflags)
 
 # Code Coverage
 # ==============================================================
 
 js_option('--enable-coverage', env='MOZ_CODE_COVERAGE',
           help='Enable code coverage')
 
 
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -144,17 +144,16 @@
 #include "nsIWebProgress.h"
 #include "nsIWidget.h"
 #include "nsIWindowWatcher.h"
 #include "nsIWritablePropertyBag2.h"
 #include "nsIWyciwygChannel.h"
 
 #include "nsCommandManager.h"
 #include "nsPIDOMWindow.h"
-#include "nsPILoadGroupInternal.h"
 #include "nsPIWindowRoot.h"
 
 #include "IHistory.h"
 #include "IUrlClassifierUITelemetry.h"
 
 #include "mozIThirdPartyUtil.h"
 
 #include "nsArray.h"
@@ -6677,21 +6676,16 @@ nsresult nsDocShell::EndPageLoad(nsIWebP
 
   nsCOMPtr<nsITimedChannel> timingChannel = do_QueryInterface(aChannel);
   if (timingChannel) {
     TimeStamp channelCreationTime;
     rv = timingChannel->GetChannelCreation(&channelCreationTime);
     if (NS_SUCCEEDED(rv) && !channelCreationTime.IsNull()) {
       Telemetry::AccumulateTimeDelta(Telemetry::TOTAL_CONTENT_PAGE_LOAD_TIME,
                                      channelCreationTime);
-      nsCOMPtr<nsPILoadGroupInternal> internalLoadGroup =
-          do_QueryInterface(mLoadGroup);
-      if (internalLoadGroup) {
-        internalLoadGroup->OnEndPageLoad(aChannel);
-      }
     }
   }
 
   // Timing is picked up by the window, we don't need it anymore
   mTiming = nullptr;
 
   // clean up reload state for meta charset
   if (eCharsetReloadRequested == mCharsetReloadState) {
--- a/dom/cache/DBSchema.cpp
+++ b/dom/cache/DBSchema.cpp
@@ -1344,17 +1344,17 @@ nsresult QueryCache(mozIStorageConnectio
     return NS_OK;
   }
 
   nsAutoCString query(
       "SELECT id, COUNT(response_headers.name) AS vary_count "
       "FROM entries "
       "LEFT OUTER JOIN response_headers ON "
       "entries.id=response_headers.entry_id "
-      "AND response_headers.name='vary' "
+      "AND response_headers.name='vary' COLLATE NOCASE "
       "WHERE entries.cache_id=:cache_id "
       "AND entries.request_url_no_query_hash=:url_no_query_hash ");
 
   if (!aParams.ignoreSearch()) {
     query.AppendLiteral("AND entries.request_url_query_hash=:url_query_hash ");
   }
 
   query.AppendLiteral("AND entries.request_url_no_query=:url_no_query ");
@@ -1464,17 +1464,18 @@ nsresult MatchByVaryHeader(mozIStorageCo
   MOZ_ASSERT(!NS_IsMainThread());
   MOZ_DIAGNOSTIC_ASSERT(aConn);
 
   *aSuccessOut = false;
 
   nsCOMPtr<mozIStorageStatement> state;
   nsresult rv = aConn->CreateStatement(
       NS_LITERAL_CSTRING("SELECT value FROM response_headers "
-                         "WHERE name='vary' AND entry_id=:entry_id;"),
+                         "WHERE name='vary' COLLATE NOCASE "
+                         "AND entry_id=:entry_id;"),
       getter_AddRefs(state));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   rv = state->BindInt32ByName(NS_LITERAL_CSTRING("entry_id"), entryId);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
--- a/dom/fetch/EmptyBody.cpp
+++ b/dom/fetch/EmptyBody.cpp
@@ -33,19 +33,22 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 EmptyBody::EmptyBody(nsIGlobalObject* aGlobal,
                      mozilla::ipc::PrincipalInfo* aPrincipalInfo,
                      AbortSignalImpl* aAbortSignalImpl,
                      already_AddRefed<nsIInputStream> aBodyStream)
     : FetchBody<EmptyBody>(aGlobal),
-      mPrincipalInfo(aPrincipalInfo),
       mAbortSignalImpl(aAbortSignalImpl),
-      mBodyStream(std::move(aBodyStream)) {}
+      mBodyStream(std::move(aBodyStream)) {
+  if (aPrincipalInfo) {
+    mPrincipalInfo = MakeUnique<mozilla::ipc::PrincipalInfo>(*aPrincipalInfo);
+  }
+}
 
 EmptyBody::~EmptyBody() = default;
 
 /* static */ already_AddRefed<EmptyBody> EmptyBody::Create(
     nsIGlobalObject* aGlobal, mozilla::ipc::PrincipalInfo* aPrincipalInfo,
     AbortSignalImpl* aAbortSignalImpl, const nsACString& aMimeType,
     ErrorResult& aRv) {
   nsCOMPtr<nsIInputStream> bodyStream;
--- a/dom/fetch/FetchDriver.cpp
+++ b/dom/fetch/FetchDriver.cpp
@@ -833,16 +833,25 @@ FetchDriver::OnStartRequest(nsIRequest* 
     }
 
     nsAutoCString statusText;
     rv = httpChannel->GetResponseStatusText(statusText);
     MOZ_ASSERT(NS_SUCCEEDED(rv));
 
     response = new InternalResponse(responseStatus, statusText);
 
+    UniquePtr<mozilla::ipc::PrincipalInfo> principalInfo(
+        new mozilla::ipc::PrincipalInfo());
+    nsresult rv = PrincipalToPrincipalInfo(mPrincipal, principalInfo.get());
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
+
+    response->SetPrincipalInfo(std::move(principalInfo));
+
     response->Headers()->FillResponseHeaders(httpChannel);
 
     // If Content-Encoding or Transfer-Encoding headers are set, then the actual
     // Content-Length (which refer to the decoded data) is obscured behind the
     // encodings.
     ErrorResult result;
     if (response->Headers()->Has(NS_LITERAL_CSTRING("content-encoding"),
                                  result) ||
@@ -1369,30 +1378,42 @@ void FetchDriver::SetController(
     const Maybe<ServiceWorkerDescriptor>& aController) {
   MOZ_ASSERT(!mFetchCalled);
   mController = aController;
 }
 
 void FetchDriver::SetRequestHeaders(nsIHttpChannel* aChannel) const {
   MOZ_ASSERT(aChannel);
 
+  // nsIHttpChannel has a set of pre-configured headers (Accept,
+  // Accept-Languages, ...) and we don't want to merge the Request's headers
+  // with them. This array is used to know if the current header has been aleady
+  // set, if yes, we ask necko to merge it with the previous one, otherwise, we
+  // don't want the merge.
+  nsTArray<nsCString> headersSet;
+
   AutoTArray<InternalHeaders::Entry, 5> headers;
   mRequest->Headers()->GetEntries(headers);
   bool hasAccept = false;
   for (uint32_t i = 0; i < headers.Length(); ++i) {
-    if (!hasAccept && headers[i].mName.EqualsLiteral("accept")) {
+    bool alreadySet = headersSet.Contains(headers[i].mName);
+    if (!alreadySet) {
+      headersSet.AppendElement(headers[i].mName);
+    }
+
+    if (!hasAccept && headers[i].mName.EqualsIgnoreCase("accept")) {
       hasAccept = true;
     }
     if (headers[i].mValue.IsEmpty()) {
       DebugOnly<nsresult> rv =
           aChannel->SetEmptyRequestHeader(headers[i].mName);
       MOZ_ASSERT(NS_SUCCEEDED(rv));
     } else {
       DebugOnly<nsresult> rv = aChannel->SetRequestHeader(
-          headers[i].mName, headers[i].mValue, false /* merge */);
+          headers[i].mName, headers[i].mValue, alreadySet /* merge */);
       MOZ_ASSERT(NS_SUCCEEDED(rv));
     }
   }
 
   if (!hasAccept) {
     DebugOnly<nsresult> rv = aChannel->SetRequestHeader(
         NS_LITERAL_CSTRING("accept"), NS_LITERAL_CSTRING("*/*"),
         false /* merge */);
--- a/dom/fetch/InternalHeaders.cpp
+++ b/dom/fetch/InternalHeaders.cpp
@@ -46,34 +46,37 @@ void InternalHeaders::Append(const nsACS
   ToLowerCase(aName, lowerName);
   nsAutoCString trimValue;
   NS_TrimHTTPWhitespace(aValue, trimValue);
 
   if (IsInvalidMutableHeader(lowerName, trimValue, aRv)) {
     return;
   }
 
+  nsAutoCString name(aName);
+  ReuseExistingNameIfExists(name);
+
   SetListDirty();
 
-  mList.AppendElement(Entry(lowerName, trimValue));
+  mList.AppendElement(Entry(name, trimValue));
 }
 
 void InternalHeaders::Delete(const nsACString& aName, ErrorResult& aRv) {
   nsAutoCString lowerName;
   ToLowerCase(aName, lowerName);
 
   if (IsInvalidMutableHeader(lowerName, aRv)) {
     return;
   }
 
   SetListDirty();
 
   // remove in reverse order to minimize copying
   for (int32_t i = mList.Length() - 1; i >= 0; --i) {
-    if (lowerName == mList[i].mName) {
+    if (mList[i].mName.EqualsIgnoreCase(lowerName.get())) {
       mList.RemoveElementAt(i);
     }
   }
 }
 
 void InternalHeaders::Get(const nsACString& aName, nsACString& aValue,
                           ErrorResult& aRv) const {
   nsAutoCString lowerName;
@@ -82,17 +85,17 @@ void InternalHeaders::Get(const nsACStri
   if (IsInvalidName(lowerName, aRv)) {
     return;
   }
 
   const char* delimiter = ", ";
   bool firstValueFound = false;
 
   for (uint32_t i = 0; i < mList.Length(); ++i) {
-    if (lowerName == mList[i].mName) {
+    if (mList[i].mName.EqualsIgnoreCase(lowerName.get())) {
       if (firstValueFound) {
         aValue += delimiter;
       }
       aValue += mList[i].mValue;
       firstValueFound = true;
     }
   }
 
@@ -107,17 +110,17 @@ void InternalHeaders::GetFirst(const nsA
   nsAutoCString lowerName;
   ToLowerCase(aName, lowerName);
 
   if (IsInvalidName(lowerName, aRv)) {
     return;
   }
 
   for (uint32_t i = 0; i < mList.Length(); ++i) {
-    if (lowerName == mList[i].mName) {
+    if (mList[i].mName.EqualsIgnoreCase(lowerName.get())) {
       aValue = mList[i].mValue;
       return;
     }
   }
 
   // No value found, so return null to content
   aValue.SetIsVoid(true);
 }
@@ -126,17 +129,17 @@ bool InternalHeaders::Has(const nsACStri
   nsAutoCString lowerName;
   ToLowerCase(aName, lowerName);
 
   if (IsInvalidName(lowerName, aRv)) {
     return false;
   }
 
   for (uint32_t i = 0; i < mList.Length(); ++i) {
-    if (lowerName == mList[i].mName) {
+    if (mList[i].mName.EqualsIgnoreCase(lowerName.get())) {
       return true;
     }
   }
   return false;
 }
 
 void InternalHeaders::Set(const nsACString& aName, const nsACString& aValue,
                           ErrorResult& aRv) {
@@ -150,28 +153,28 @@ void InternalHeaders::Set(const nsACStri
   }
 
   SetListDirty();
 
   int32_t firstIndex = INT32_MAX;
 
   // remove in reverse order to minimize copying
   for (int32_t i = mList.Length() - 1; i >= 0; --i) {
-    if (lowerName == mList[i].mName) {
+    if (mList[i].mName.EqualsIgnoreCase(lowerName.get())) {
       firstIndex = std::min(firstIndex, i);
       mList.RemoveElementAt(i);
     }
   }
 
   if (firstIndex < INT32_MAX) {
     Entry* entry = mList.InsertElementAt(firstIndex);
-    entry->mName = lowerName;
+    entry->mName = aName;
     entry->mValue = trimValue;
   } else {
-    mList.AppendElement(Entry(lowerName, trimValue));
+    mList.AppendElement(Entry(aName, trimValue));
   }
 }
 
 void InternalHeaders::Clear() {
   SetListDirty();
   mList.Clear();
 }
 
@@ -179,40 +182,41 @@ void InternalHeaders::SetGuard(HeadersGu
   // The guard is only checked during ::Set() and ::Append() in the spec.  It
   // does not require revalidating headers already set.
   mGuard = aGuard;
 }
 
 InternalHeaders::~InternalHeaders() {}
 
 // static
-bool InternalHeaders::IsSimpleHeader(const nsACString& aName,
+bool InternalHeaders::IsSimpleHeader(const nsCString& aName,
                                      const nsACString& aValue) {
   if (aValue.Length() > 128) {
     return false;
   }
   // Note, we must allow a null content-type value here to support
   // get("content-type"), but the IsInvalidValue() check will prevent null
   // from being set or appended.
-  return (aName.EqualsLiteral("accept") &&
+  return (aName.EqualsIgnoreCase("accept") &&
           nsContentUtils::IsAllowedNonCorsAccept(aValue)) ||
-         (aName.EqualsLiteral("accept-language") &&
+         (aName.EqualsIgnoreCase("accept-language") &&
           nsContentUtils::IsAllowedNonCorsLanguage(aValue)) ||
-         (aName.EqualsLiteral("content-language") &&
+         (aName.EqualsIgnoreCase("content-language") &&
           nsContentUtils::IsAllowedNonCorsLanguage(aValue)) ||
-         (aName.EqualsLiteral("content-type") &&
+         (aName.EqualsIgnoreCase("content-type") &&
           nsContentUtils::IsAllowedNonCorsContentType(aValue));
 }
 
 // static
-bool InternalHeaders::IsRevalidationHeader(const nsACString& aName) {
-  return aName.EqualsLiteral("if-modified-since") ||
-         aName.EqualsLiteral("if-none-match") ||
-         aName.EqualsLiteral("if-unmodified-since") ||
-         aName.EqualsLiteral("if-match") || aName.EqualsLiteral("if-range");
+bool InternalHeaders::IsRevalidationHeader(const nsCString& aName) {
+  return aName.EqualsIgnoreCase("if-modified-since") ||
+         aName.EqualsIgnoreCase("if-none-match") ||
+         aName.EqualsIgnoreCase("if-unmodified-since") ||
+         aName.EqualsIgnoreCase("if-match") ||
+         aName.EqualsIgnoreCase("if-range");
 }
 
 // static
 bool InternalHeaders::IsInvalidName(const nsACString& aName, ErrorResult& aRv) {
   if (!NS_IsValidHTTPToken(aName)) {
     NS_ConvertUTF8toUTF16 label(aName);
     aRv.ThrowTypeError<MSG_INVALID_HEADER_NAME>(label);
     return true;
@@ -235,34 +239,34 @@ bool InternalHeaders::IsInvalidValue(con
 bool InternalHeaders::IsImmutable(ErrorResult& aRv) const {
   if (mGuard == HeadersGuardEnum::Immutable) {
     aRv.ThrowTypeError<MSG_HEADERS_IMMUTABLE>();
     return true;
   }
   return false;
 }
 
-bool InternalHeaders::IsForbiddenRequestHeader(const nsACString& aName) const {
+bool InternalHeaders::IsForbiddenRequestHeader(const nsCString& aName) const {
   return mGuard == HeadersGuardEnum::Request &&
          nsContentUtils::IsForbiddenRequestHeader(aName);
 }
 
 bool InternalHeaders::IsForbiddenRequestNoCorsHeader(
-    const nsACString& aName) const {
+    const nsCString& aName) const {
   return mGuard == HeadersGuardEnum::Request_no_cors &&
          !IsSimpleHeader(aName, EmptyCString());
 }
 
 bool InternalHeaders::IsForbiddenRequestNoCorsHeader(
-    const nsACString& aName, const nsACString& aValue) const {
+    const nsCString& aName, const nsACString& aValue) const {
   return mGuard == HeadersGuardEnum::Request_no_cors &&
          !IsSimpleHeader(aName, aValue);
 }
 
-bool InternalHeaders::IsForbiddenResponseHeader(const nsACString& aName) const {
+bool InternalHeaders::IsForbiddenResponseHeader(const nsCString& aName) const {
   return mGuard == HeadersGuardEnum::Response &&
          nsContentUtils::IsForbiddenResponseHeader(aName);
 }
 
 void InternalHeaders::Fill(const InternalHeaders& aInit, ErrorResult& aRv) {
   const nsTArray<Entry>& list = aInit.mList;
   for (uint32_t i = 0; i < list.Length() && !aRv.Failed(); ++i) {
     const Entry& entry = list[i];
@@ -394,22 +398,22 @@ already_AddRefed<InternalHeaders> Intern
     }
 
     exposeNamesArray.AppendElement(token);
   }
 
   nsCaseInsensitiveCStringArrayComparator comp;
   for (uint32_t i = 0; i < aHeaders->mList.Length(); ++i) {
     const Entry& entry = aHeaders->mList[i];
-    if (entry.mName.EqualsASCII("cache-control") ||
-        entry.mName.EqualsASCII("content-language") ||
-        entry.mName.EqualsASCII("content-type") ||
-        entry.mName.EqualsASCII("expires") ||
-        entry.mName.EqualsASCII("last-modified") ||
-        entry.mName.EqualsASCII("pragma") ||
+    if (entry.mName.EqualsIgnoreCase("cache-control") ||
+        entry.mName.EqualsIgnoreCase("content-language") ||
+        entry.mName.EqualsIgnoreCase("content-type") ||
+        entry.mName.EqualsIgnoreCase("expires") ||
+        entry.mName.EqualsIgnoreCase("last-modified") ||
+        entry.mName.EqualsIgnoreCase("pragma") ||
         exposeNamesArray.Contains(entry.mName, comp)) {
       cors->Append(entry.mName, entry.mValue, result);
       MOZ_ASSERT(!result.Failed());
     }
   }
 
   return cors.forget();
 }
@@ -449,29 +453,40 @@ void InternalHeaders::MaybeSortList() {
   mListDirty = false;
 
   Comparator comparator;
 
   mSortedList.Clear();
   for (const Entry& entry : mList) {
     bool found = false;
     for (Entry& sortedEntry : mSortedList) {
-      if (sortedEntry.mName == entry.mName) {
+      if (sortedEntry.mName.EqualsIgnoreCase(entry.mName.get())) {
         sortedEntry.mValue += ", ";
         sortedEntry.mValue += entry.mValue;
         found = true;
         break;
       }
     }
 
     if (!found) {
-      mSortedList.InsertElementSorted(entry, comparator);
+      Entry newEntry = entry;
+      ToLowerCase(newEntry.mName);
+      mSortedList.InsertElementSorted(newEntry, comparator);
     }
   }
 }
 
 void InternalHeaders::SetListDirty() {
   mSortedList.Clear();
   mListDirty = true;
 }
 
+void InternalHeaders::ReuseExistingNameIfExists(nsCString& aName) const {
+  for (const Entry& entry : mList) {
+    if (entry.mName.EqualsIgnoreCase(aName.get())) {
+      aName = entry.mName;
+      break;
+    }
+  }
+}
+
 }  // namespace dom
 }  // namespace mozilla
--- a/dom/fetch/InternalHeaders.h
+++ b/dom/fetch/InternalHeaders.h
@@ -120,37 +120,41 @@ class InternalHeaders final {
   void GetUnsafeHeaders(nsTArray<nsCString>& aNames) const;
 
  private:
   virtual ~InternalHeaders();
 
   static bool IsInvalidName(const nsACString& aName, ErrorResult& aRv);
   static bool IsInvalidValue(const nsACString& aValue, ErrorResult& aRv);
   bool IsImmutable(ErrorResult& aRv) const;
-  bool IsForbiddenRequestHeader(const nsACString& aName) const;
-  bool IsForbiddenRequestNoCorsHeader(const nsACString& aName) const;
-  bool IsForbiddenRequestNoCorsHeader(const nsACString& aName,
+  bool IsForbiddenRequestHeader(const nsCString& aName) const;
+  bool IsForbiddenRequestNoCorsHeader(const nsCString& aName) const;
+  bool IsForbiddenRequestNoCorsHeader(const nsCString& aName,
                                       const nsACString& aValue) const;
-  bool IsForbiddenResponseHeader(const nsACString& aName) const;
+  bool IsForbiddenResponseHeader(const nsCString& aName) const;
 
-  bool IsInvalidMutableHeader(const nsACString& aName, ErrorResult& aRv) const {
+  bool IsInvalidMutableHeader(const nsCString& aName, ErrorResult& aRv) const {
     return IsInvalidMutableHeader(aName, EmptyCString(), aRv);
   }
 
-  bool IsInvalidMutableHeader(const nsACString& aName, const nsACString& aValue,
+  bool IsInvalidMutableHeader(const nsCString& aName, const nsACString& aValue,
                               ErrorResult& aRv) const {
     return IsInvalidName(aName, aRv) || IsInvalidValue(aValue, aRv) ||
            IsImmutable(aRv) || IsForbiddenRequestHeader(aName) ||
            IsForbiddenRequestNoCorsHeader(aName, aValue) ||
            IsForbiddenResponseHeader(aName);
   }
 
-  static bool IsSimpleHeader(const nsACString& aName, const nsACString& aValue);
+  // This method updates the passed name to match the capitalization of a header
+  // with the same name (ignoring case, per the spec).
+  void ReuseExistingNameIfExists(nsCString& aName) const;
 
-  static bool IsRevalidationHeader(const nsACString& aName);
+  static bool IsSimpleHeader(const nsCString& aName, const nsACString& aValue);
+
+  static bool IsRevalidationHeader(const nsCString& aName);
 
   void MaybeSortList();
   void SetListDirty();
 };
 
 }  // namespace dom
 }  // namespace mozilla
 
--- a/dom/file/MutableBlobStorage.cpp
+++ b/dom/file/MutableBlobStorage.cpp
@@ -503,26 +503,32 @@ bool MutableBlobStorage::ShouldBeTempora
 bool MutableBlobStorage::MaybeCreateTemporaryFile(
     const MutexAutoLock& aProofOfLock) {
   mStorageState = eWaitingForTemporaryFile;
 
   if (!NS_IsMainThread()) {
     RefPtr<MutableBlobStorage> self = this;
     nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
         "MutableBlobStorage::MaybeCreateTemporaryFile",
-        [self]() { self->MaybeCreateTemporaryFileOnMainThread(); });
-    EventTarget()->Dispatch(r.forget(), NS_DISPATCH_SYNC);
-    return !!mActor;
+        [self]() {
+          MutexAutoLock lock(self->mMutex);
+          self->MaybeCreateTemporaryFileOnMainThread(lock);
+          if (!self->mActor) {
+            self->ErrorPropagated(NS_ERROR_FAILURE);
+          }
+        });
+    EventTarget()->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
+    return true;
   }
 
-  MaybeCreateTemporaryFileOnMainThread();
+  MaybeCreateTemporaryFileOnMainThread(aProofOfLock);
   return !!mActor;
 }
 
-void MutableBlobStorage::MaybeCreateTemporaryFileOnMainThread() {
+void MutableBlobStorage::MaybeCreateTemporaryFileOnMainThread(const MutexAutoLock& aProofOfLock) {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(!mActor);
 
   mozilla::ipc::PBackgroundChild* actorChild =
       mozilla::ipc::BackgroundChild::GetOrCreateForCurrentThread();
   if (NS_WARN_IF(!actorChild)) {
     return;
   }
--- a/dom/file/MutableBlobStorage.h
+++ b/dom/file/MutableBlobStorage.h
@@ -81,17 +81,17 @@ class MutableBlobStorage final {
   ~MutableBlobStorage();
 
   bool ExpandBufferSize(const MutexAutoLock& aProofOfLock, uint64_t aSize);
 
   bool ShouldBeTemporaryStorage(const MutexAutoLock& aProofOfLock,
                                 uint64_t aSize) const;
 
   bool MaybeCreateTemporaryFile(const MutexAutoLock& aProofOfLock);
-  void MaybeCreateTemporaryFileOnMainThread();
+  void MaybeCreateTemporaryFileOnMainThread(const MutexAutoLock& aProofOfLock);
 
   MOZ_MUST_USE nsresult
   DispatchToIOThread(already_AddRefed<nsIRunnable> aRunnable);
 
   Mutex mMutex;
 
   // All these variables are touched on the main thread only or in the
   // retargeted thread when used by Append(). They are protected by mMutex.
--- a/dom/svg/nsSVGAnimatedTransformList.cpp
+++ b/dom/svg/nsSVGAnimatedTransformList.cpp
@@ -11,19 +11,20 @@
 #include "mozilla/dom/SVGAnimationElement.h"
 #include "mozilla/Move.h"
 #include "nsCharSeparatedTokenizer.h"
 #include "nsSVGTransform.h"
 #include "nsSMILValue.h"
 #include "SVGContentUtils.h"
 #include "SVGTransformListSMILType.h"
 
-namespace mozilla {
+using namespace mozilla::dom;
+using namespace mozilla::dom::SVGTransform_Binding;
 
-using namespace dom;
+namespace mozilla {
 
 nsresult nsSVGAnimatedTransformList::SetBaseValueString(
     const nsAString& aValue, nsSVGElement* aSVGElement) {
   SVGTransformList newBaseValue;
   nsresult rv = newBaseValue.SetValueFromString(aValue);
   if (NS_FAILED(rv)) {
     return rv;
   }
--- a/dom/tests/mochitest/fetch/common_temporaryFileBlob.js
+++ b/dom/tests/mochitest/fetch/common_temporaryFileBlob.js
@@ -1,39 +1,88 @@
 var data = new Array(256).join("1234567890ABCDEF");
 
-function test_basic() {
-  info("Simple test");
+function test_fetch_basic() {
+  info("Simple fetch test");
 
   fetch("/tests/dom/xhr/tests/temporaryFileBlob.sjs",
         { method: "POST", body: data })
   .then(response => {
     return response.blob();
   }).then(blob => {
     ok(blob instanceof Blob, "We have a blob!");
     is(blob.size, data.length, "Data length matches");
+    if ("SpecialPowers" in self) {
+      is(SpecialPowers.wrap(blob).blobImplType, "StreamBlobImpl", "We have a blob stored into a stream file");
+    }
 
     var fr = new FileReader();
     fr.readAsText(blob);
     fr.onload = function() {
       is(fr.result, data, "Data content matches");
       next();
     }
   });
 }
 
-function test_worker() {
+function test_fetch_worker() {
+  info("fetch in workers");
+  var w = new Worker('worker_temporaryFileBlob.js');
+  w.onmessage = function(e) {
+    if (e.data.type == 'info') {
+      info(e.data.msg);
+    } else if (e.data.type == 'check') {
+      ok(e.data.what, e.data.msg);
+    } else if (e.data.type == 'finish') {
+      next();
+    } else {
+      ok(false, 'Something wrong happened');
+    }
+  }
+
+  w.postMessage('fetch');
+}
+
+function test_xhr_basic() {
+  info("Simple XHR test");
+
+  let xhr = new XMLHttpRequest();
+  xhr.responseType = "blob";
+  xhr.open("POST", "/tests/dom/xhr/tests/temporaryFileBlob.sjs");
+  xhr.send(data);
+
+  xhr.onreadystatechange = function() {
+    if (xhr.readyState == 4) {
+      let blob = xhr.response;
+
+      ok(blob instanceof Blob, "We have a blob!");
+      is(blob.size, data.length, "Data length matches");
+      if ("SpecialPowers" in self) {
+        is(SpecialPowers.wrap(blob).blobImplType, "StreamBlobImpl", "We have a blob stored into a stream file");
+      }
+
+      var fr = new FileReader();
+      fr.readAsText(blob);
+      fr.onload = function() {
+        is(fr.result, data, "Data content matches");
+        next();
+      }
+    }
+  }
+}
+
+function test_xhr_worker() {
   info("XHR in workers");
   var w = new Worker('worker_temporaryFileBlob.js');
   w.onmessage = function(e) {
     if (e.data.type == 'info') {
       info(e.data.msg);
     } else if (e.data.type == 'check') {
       ok(e.data.what, e.data.msg);
     } else if (e.data.type == 'finish') {
       next();
     } else {
       ok(false, 'Something wrong happened');
     }
   }
 
-  w.postMessage(42);
+  w.postMessage('xhr');
 }
--- a/dom/tests/mochitest/fetch/test_temporaryFileBlob.html
+++ b/dom/tests/mochitest/fetch/test_temporaryFileBlob.html
@@ -7,18 +7,20 @@
   <script type="application/javascript" src="common_temporaryFileBlob.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 </head>
 <body>
   <script type="application/javascript">
 
 var tests = [
   // from common_temporaryFileBlob.js:
-  test_basic,
-  test_worker,
+  test_fetch_basic,
+  test_fetch_worker,
+  test_xhr_basic,
+  test_xhr_worker,
 ];
 
 function next() {
   if (!tests.length) {
     SimpleTest.finish();
     return;
   }
 
--- a/dom/tests/mochitest/fetch/worker_temporaryFileBlob.js
+++ b/dom/tests/mochitest/fetch/worker_temporaryFileBlob.js
@@ -12,10 +12,14 @@ function is(a, b, msg) {
   ok(a === b, msg);
 }
 
 function next() {
   postMessage({type: 'finish'});
 }
 
 onmessage = function(e) {
-  test_basic();
+  if (e == 'xhr') {
+    test_xhr_basic();
+  } else {
+    test_fetch_basic();
+  }
 }
--- a/js/src/gc/Verifier.cpp
+++ b/js/src/gc/Verifier.cpp
@@ -732,47 +732,52 @@ JS_FRIEND_API bool js::CheckGrayMarkingS
 
   gcstats::AutoPhase ap(rt->gc.stats(), gcstats::PhaseKind::TRACE_HEAP);
   AutoTraceSession session(rt);
   CheckGrayMarkingTracer tracer(rt);
 
   return tracer.check(session);
 }
 
-static Zone* GetCellZone(Cell* cell) {
+static Zone* GetCellZoneFromAnyThread(Cell* cell) {
   if (cell->is<JSObject>()) {
-    return cell->as<JSObject>()->zone();
+    return cell->as<JSObject>()->zoneFromAnyThread();
   }
 
-  return cell->asTenured().zone();
+  if (cell->is<JSString>()) {
+    return cell->as<JSString>()->zoneFromAnyThread();
+  }
+
+  return cell->asTenured().zoneFromAnyThread();
 }
 
 static JSObject* MaybeGetDelegate(Cell* cell) {
   if (!cell->is<JSObject>()) {
     return nullptr;
   }
 
   JSObject* object = cell->as<JSObject>();
   return js::UncheckedUnwrapWithoutExpose(object);
 }
 
 bool js::gc::CheckWeakMapEntryMarking(const WeakMapBase* map, Cell* key,
                                       Cell* value) {
   DebugOnly<Zone*> zone = map->zone();
+  MOZ_ASSERT(CurrentThreadCanAccessZone(zone));
   MOZ_ASSERT(zone->isGCMarking());
 
   JSObject* object = map->memberOf;
   MOZ_ASSERT_IF(object, object->zone() == zone);
 
   // Debugger weak maps can have keys in different zones.
-  Zone* keyZone = GetCellZone(key);
+  Zone* keyZone = GetCellZoneFromAnyThread(key);
   MOZ_ASSERT_IF(!map->allowKeysInOtherZones(),
                 keyZone == zone || keyZone->isAtomsZone());
 
-  Zone* valueZone = GetCellZone(value);
+  Zone* valueZone = GetCellZoneFromAnyThread(value);
   MOZ_ASSERT(valueZone == zone || valueZone->isAtomsZone());
 
   CellColor mapColor = map->markColor == MarkColor::Black ? CellColor::Black
                                                           : CellColor::Gray;
   MOZ_ASSERT_IF(object, GetCellColor(object) == mapColor);
 
   CellColor keyColor = GetCellColor(key);
   CellColor valueColor =
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/gc/bug-1513991.js
@@ -0,0 +1,9 @@
+// |jit-test| skip-if: helperThreadCount() === 0
+evalInWorker(`
+var sym4 = Symbol.match;
+function test(makeNonArray) {}
+function basicSweeping() {}
+var wm1 = new WeakMap();
+wm1.set(basicSweeping, sym4);
+startgc(100000, 'shrinking');
+`);
--- a/js/src/jit/arm64/vixl/MozSimulator-vixl.cpp
+++ b/js/src/jit/arm64/vixl/MozSimulator-vixl.cpp
@@ -132,20 +132,22 @@ void Simulator::init(Decoder* decoder, F
   byte * tos = stack_ + stack_size_;
   //  - There's a protection region at both ends of the stack.
   tos -= stack_protection_size_;
   //  - The stack pointer must be 16-byte aligned.
   tos = AlignDown(tos, 16);
   set_sp(tos);
 
   // Set the sample period to 10, as the VIXL examples and tests are short.
-  instrumentation_ = js_new<Instrument>("vixl_stats.csv", 10);
-  if (!instrumentation_) {
-    oom_ = true;
-    return;
+  if (getenv("VIXL_STATS")) {
+    instrumentation_ = js_new<Instrument>("vixl_stats.csv", 10);
+    if (!instrumentation_) {
+      oom_ = true;
+      return;
+    }
   }
 
   // Print a warning about exclusive-access instructions, but only the first
   // time they are encountered. This warning can be silenced using
   // SilenceExclusiveAccessWarning().
   print_exclusive_access_warning_ = true;
 }
 
--- a/js/src/jit/arm64/vixl/Simulator-vixl.cpp
+++ b/js/src/jit/arm64/vixl/Simulator-vixl.cpp
@@ -199,16 +199,20 @@ void Simulator::set_trace_parameters(int
     } else {
       decoder_->RemoveVisitor(print_disasm_);
     }
   }
 }
 
 
 void Simulator::set_instruction_stats(bool value) {
+  if (instrumentation_ == nullptr) {
+    return;
+  }
+
   if (value != instruction_stats_) {
     if (value) {
       decoder_->AppendVisitor(instrumentation_);
     } else {
       decoder_->RemoveVisitor(instrumentation_);
     }
     instruction_stats_ = value;
   }
--- a/js/src/old-configure.in
+++ b/js/src/old-configure.in
@@ -514,16 +514,17 @@ esac
 
 dnl ========================================================
 dnl Add optional and non-optional hardening flags from toolchain.configure
 dnl ========================================================
 
 CFLAGS="$CFLAGS $MOZ_HARDENING_CFLAGS_JS"
 CPPFLAGS="$CPPFLAGS $MOZ_HARDENING_CFLAGS_JS"
 CXXFLAGS="$CXXFLAGS $MOZ_HARDENING_CFLAGS_JS"
+LDFLAGS="$LDFLAGS $MOZ_HARDENING_LDFLAGS_JS"
 
 dnl ========================================================
 dnl System overrides of the defaults for target
 dnl ========================================================
 
 case "$target" in
 *-darwin*)
     MOZ_OPTIMIZE_FLAGS="-O3"
--- a/netwerk/base/moz.build
+++ b/netwerk/base/moz.build
@@ -122,17 +122,16 @@ XPIDL_SOURCES += [
     'nsIUDPSocket.idl',
     'nsIUploadChannel.idl',
     'nsIUploadChannel2.idl',
     'nsIURI.idl',
     'nsIURIMutator.idl',
     'nsIURIWithSpecialOrigin.idl',
     'nsIURL.idl',
     'nsIURLParser.idl',
-    'nsPILoadGroupInternal.idl',
     'nsPISocketTransportService.idl',
 ]
 
 if CONFIG['MOZ_TOOLKIT_SEARCH']:
     XPIDL_SOURCES += [
         'nsIBrowserSearchService.idl',
     ]
 
--- a/netwerk/base/nsLoadGroup.cpp
+++ b/netwerk/base/nsLoadGroup.cpp
@@ -78,29 +78,27 @@ static const PLDHashTableOps sRequestHas
     PLDHashTable::HashVoidPtrKeyStub, RequestHashMatchEntry,
     PLDHashTable::MoveEntryStub, RequestHashClearEntry, RequestHashInitEntry};
 
 static void RescheduleRequest(nsIRequest *aRequest, int32_t delta) {
   nsCOMPtr<nsISupportsPriority> p = do_QueryInterface(aRequest);
   if (p) p->AdjustPriority(delta);
 }
 
-nsLoadGroup::nsLoadGroup(nsISupports *outer)
+nsLoadGroup::nsLoadGroup()
     : mForegroundCount(0),
       mLoadFlags(LOAD_NORMAL),
       mDefaultLoadFlags(0),
+      mPriority(PRIORITY_NORMAL),
       mRequests(&sRequestHashOps, sizeof(RequestMapEntry)),
       mStatus(NS_OK),
-      mPriority(PRIORITY_NORMAL),
       mIsCanceling(false),
       mDefaultLoadIsTimed(false),
       mTimedRequests(0),
-      mCachedRequests(0),
-      mTimedNonCachedRequestsUntilOnEndPageLoad(0) {
-  NS_INIT_AGGREGATED(outer);
+      mCachedRequests(0) {
   LOG(("LOADGROUP [%p]: Created.\n", this));
 }
 
 nsLoadGroup::~nsLoadGroup() {
   DebugOnly<nsresult> rv = Cancel(NS_BINDING_ABORTED);
   NS_ASSERTION(NS_SUCCEEDED(rv), "Cancel failed");
 
   mDefaultLoadRequest = nullptr;
@@ -110,25 +108,22 @@ nsLoadGroup::~nsLoadGroup() {
   }
 
   LOG(("LOADGROUP [%p]: Destroyed.\n", this));
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsISupports methods:
 
-NS_IMPL_AGGREGATED(nsLoadGroup)
-NS_INTERFACE_MAP_BEGIN_AGGREGATED(nsLoadGroup)
-  NS_INTERFACE_MAP_ENTRY(nsILoadGroup)
-  NS_INTERFACE_MAP_ENTRY(nsPILoadGroupInternal)
-  NS_INTERFACE_MAP_ENTRY(nsILoadGroupChild)
-  NS_INTERFACE_MAP_ENTRY(nsIRequest)
-  NS_INTERFACE_MAP_ENTRY(nsISupportsPriority)
-  NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
-NS_INTERFACE_MAP_END
+NS_IMPL_ISUPPORTS(nsLoadGroup,
+                  nsILoadGroup,
+                  nsILoadGroupChild,
+                  nsIRequest,
+                  nsISupportsPriority,
+                  nsISupportsWeakReference)
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIRequest methods:
 
 NS_IMETHODIMP
 nsLoadGroup::GetName(nsACString &result) {
   // XXX is this the right "name" for a load group?
 
@@ -533,18 +528,16 @@ nsLoadGroup::RemoveRequest(nsIRequest *r
     nsCOMPtr<nsITimedChannel> timedChannel = do_QueryInterface(request);
     if (timedChannel) {
       // Figure out if this request was served from the cache
       ++mTimedRequests;
       TimeStamp timeStamp;
       rv = timedChannel->GetCacheReadStart(&timeStamp);
       if (NS_SUCCEEDED(rv) && !timeStamp.IsNull()) {
         ++mCachedRequests;
-      } else {
-        mTimedNonCachedRequestsUntilOnEndPageLoad++;
       }
 
       rv = timedChannel->GetAsyncOpen(&timeStamp);
       if (NS_SUCCEEDED(rv) && !timeStamp.IsNull()) {
         Telemetry::AccumulateTimeDelta(
             Telemetry::HTTP_SUBITEM_OPEN_LATENCY_TIME,
             mDefaultRequestCreationTime, timeStamp);
       }
@@ -691,28 +684,16 @@ nsLoadGroup::GetRootLoadGroup(nsILoadGro
   if (ancestor) return ancestor->GetRootLoadGroup(aRootLoadGroup);
 
   // finally just return this
   NS_ADDREF(*aRootLoadGroup = this);
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsPILoadGroupInternal methods:
-
-NS_IMETHODIMP
-nsLoadGroup::OnEndPageLoad(nsIChannel *aDefaultChannel) {
-  LOG(("nsLoadGroup::OnEndPageLoad this=%p default-request=%p", this,
-       aDefaultChannel));
-
-  // for the moment, nothing to do here.
-  return NS_OK;
-}
-
-////////////////////////////////////////////////////////////////////////////////
 // nsISupportsPriority methods:
 
 NS_IMETHODIMP
 nsLoadGroup::GetPriority(int32_t *aValue) {
   *aValue = mPriority;
   return NS_OK;
 }
 
--- a/netwerk/base/nsLoadGroup.h
+++ b/netwerk/base/nsLoadGroup.h
@@ -3,101 +3,95 @@
  * 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/. */
 
 #ifndef nsLoadGroup_h__
 #define nsLoadGroup_h__
 
 #include "nsILoadGroup.h"
 #include "nsILoadGroupChild.h"
-#include "nsPILoadGroupInternal.h"
-#include "nsAgg.h"
 #include "nsCOMPtr.h"
 #include "nsWeakReference.h"
 #include "nsISupportsPriority.h"
 #include "PLDHashTable.h"
 #include "mozilla/TimeStamp.h"
 
 class nsIRequestContext;
 class nsIRequestContextService;
 class nsITimedChannel;
 
 namespace mozilla {
 namespace net {
 
 class nsLoadGroup : public nsILoadGroup,
                     public nsILoadGroupChild,
                     public nsISupportsPriority,
-                    public nsSupportsWeakReference,
-                    public nsPILoadGroupInternal {
+                    public nsSupportsWeakReference {
  public:
-  NS_DECL_AGGREGATED
+  NS_DECL_ISUPPORTS
 
   ////////////////////////////////////////////////////////////////////////////
   // nsIRequest methods:
   NS_DECL_NSIREQUEST
 
   ////////////////////////////////////////////////////////////////////////////
   // nsILoadGroup methods:
   NS_DECL_NSILOADGROUP
-  NS_DECL_NSPILOADGROUPINTERNAL
 
   ////////////////////////////////////////////////////////////////////////////
   // nsILoadGroupChild methods:
   NS_DECL_NSILOADGROUPCHILD
 
   ////////////////////////////////////////////////////////////////////////////
   // nsISupportsPriority methods:
   NS_DECL_NSISUPPORTSPRIORITY
 
   ////////////////////////////////////////////////////////////////////////////
   // nsLoadGroup methods:
 
-  explicit nsLoadGroup(nsISupports* outer);
-  virtual ~nsLoadGroup();
+  nsLoadGroup();
 
   nsresult Init();
 
  protected:
+  virtual ~nsLoadGroup();
+
   nsresult MergeLoadFlags(nsIRequest* aRequest, nsLoadFlags& flags);
   nsresult MergeDefaultLoadFlags(nsIRequest* aRequest, nsLoadFlags& flags);
 
  private:
   void TelemetryReport();
   void TelemetryReportChannel(nsITimedChannel* timedChannel,
                               bool defaultRequest);
 
  protected:
   uint32_t mForegroundCount;
   uint32_t mLoadFlags;
   uint32_t mDefaultLoadFlags;
+  int32_t mPriority;
 
   nsCOMPtr<nsILoadGroup> mLoadGroup;  // load groups can contain load groups
   nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
   nsCOMPtr<nsIRequestContext> mRequestContext;
   nsCOMPtr<nsIRequestContextService> mRequestContextService;
 
   nsCOMPtr<nsIRequest> mDefaultLoadRequest;
   PLDHashTable mRequests;
 
   nsWeakPtr mObserver;
   nsWeakPtr mParentLoadGroup;
 
   nsresult mStatus;
-  int32_t mPriority;
   bool mIsCanceling;
+  bool mDefaultLoadIsTimed;
 
   /* Telemetry */
   mozilla::TimeStamp mDefaultRequestCreationTime;
-  bool mDefaultLoadIsTimed;
   uint32_t mTimedRequests;
   uint32_t mCachedRequests;
 
-  /* For nsPILoadGroupInternal */
-  uint32_t mTimedNonCachedRequestsUntilOnEndPageLoad;
-
   nsCString mUserAgentOverrideCache;
 };
 
 }  // namespace net
 }  // namespace mozilla
 
 #endif  // nsLoadGroup_h__
deleted file mode 100644
--- a/netwerk/base/nsPILoadGroupInternal.idl
+++ /dev/null
@@ -1,28 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* 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/. */
-
-#include "nsISupports.idl"
-
-interface nsIChannel;
-
-/**
- * Dumping ground for load group experimental work.
- * This interface will never be frozen.  If you are
- * using any feature exposed by this interface, be aware that this interface
- * will change and you will be broken.  You have been warned.
- */
-[scriptable, uuid(6ef2f8ac-9584-48f3-957a-0c94fff0c8c7)]
-interface nsPILoadGroupInternal : nsISupports
-{
-
-    /**
-     * Called when the load group has loaded main page and
-     * subresources. (i.e.essentially DOMComplete)
-     *
-     * @param aDefaultChanel
-     *        The request channel for the base apge
-     */
-    void OnEndPageLoad(in nsIChannel aDefaultChannel);
-};
--- a/netwerk/build/nsNetModule.cpp
+++ b/netwerk/build/nsNetModule.cpp
@@ -108,17 +108,17 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(Back
 }  // namespace net
 }  // namespace mozilla
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsAtomicFileOutputStream)
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSafeFileOutputStream)
 
 typedef mozilla::net::nsLoadGroup nsLoadGroup;
-NS_GENERIC_AGGREGATED_CONSTRUCTOR_INIT(nsLoadGroup, Init)
+NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsLoadGroup, Init)
 
 #include "ArrayBufferInputStream.h"
 NS_GENERIC_FACTORY_CONSTRUCTOR(ArrayBufferInputStream)
 
 #include "nsEffectiveTLDService.h"
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsEffectiveTLDService, Init)
 
 #include "nsSerializationHelper.h"
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -1309,30 +1309,55 @@ nsresult EnsureMIMEOfScript(nsIURI *aURI
 
   nsAutoCString contentType;
   aResponseHead->ContentType(contentType);
   NS_ConvertUTF8toUTF16 typeString(contentType);
 
   if (nsContentUtils::IsJavascriptMIMEType(typeString)) {
     // script load has type script
     AccumulateCategorical(
-        Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_2::javaScript);
+        Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::javaScript);
     return NS_OK;
   }
 
+  switch (aLoadInfo->InternalContentPolicyType()) {
+    case nsIContentPolicy::TYPE_SCRIPT:
+    case nsIContentPolicy::TYPE_INTERNAL_SCRIPT:
+    case nsIContentPolicy::TYPE_INTERNAL_SCRIPT_PRELOAD:
+      AccumulateCategorical(
+          Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::script_load);
+      break;
+    case nsIContentPolicy::TYPE_INTERNAL_WORKER:
+    case nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER:
+      AccumulateCategorical(
+          Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::worker_load);
+      break;
+    case nsIContentPolicy::TYPE_INTERNAL_SERVICE_WORKER:
+      AccumulateCategorical(
+          Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::serviceworker_load);
+      break;
+    case nsIContentPolicy::TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS:
+      AccumulateCategorical(
+          Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::importScript_load);
+      break;
+    default:
+      MOZ_ASSERT_UNREACHABLE("unexpected script type");
+      break;
+  }
+
   nsCOMPtr<nsIURI> requestURI;
   aLoadInfo->LoadingPrincipal()->GetURI(getter_AddRefs(requestURI));
 
   nsIScriptSecurityManager *ssm = nsContentUtils::GetSecurityManager();
   bool isPrivateWin = aLoadInfo->GetOriginAttributes().mPrivateBrowsingId > 0;
   nsresult rv = ssm->CheckSameOriginURI(requestURI, aURI, false, isPrivateWin);
   if (NS_SUCCEEDED(rv)) {
     // same origin
     AccumulateCategorical(
-        Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_2::same_origin);
+        Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::same_origin);
   } else {
     bool cors = false;
     nsAutoCString corsOrigin;
     rv = aResponseHead->GetHeader(
         nsHttp::ResolveAtom("Access-Control-Allow-Origin"), corsOrigin);
     if (NS_SUCCEEDED(rv)) {
       if (corsOrigin.Equals("*")) {
         cors = true;
@@ -1348,44 +1373,44 @@ nsresult EnsureMIMEOfScript(nsIURI *aURI
             cors = true;
           }
         }
       }
     }
     if (cors) {
       // cors origin
       AccumulateCategorical(
-          Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_2::CORS_origin);
+          Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::CORS_origin);
     } else {
       // cross origin
       AccumulateCategorical(
-          Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_2::cross_origin);
+          Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::cross_origin);
     }
   }
 
   bool block = false;
   if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("image/"))) {
     // script load has type image
     AccumulateCategorical(
-        Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_2::image);
+        Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::image);
     block = true;
   } else if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("audio/"))) {
     // script load has type audio
     AccumulateCategorical(
-        Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_2::audio);
+        Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::audio);
     block = true;
   } else if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("video/"))) {
     // script load has type video
     AccumulateCategorical(
-        Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_2::video);
+        Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::video);
     block = true;
   } else if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("text/csv"))) {
     // script load has type text/csv
     AccumulateCategorical(
-        Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_2::text_csv);
+        Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_csv);
     block = true;
   }
 
   if (block) {
     // Instead of consulting Preferences::GetBool() all the time we
     // can cache the result to speed things up.
     static bool sCachedBlockScriptWithWrongMime = false;
     static bool sIsInited = false;
@@ -1402,59 +1427,73 @@ nsresult EnsureMIMEOfScript(nsIURI *aURI
 
     ReportTypeBlocking(aURI, aLoadInfo, "BlockScriptWithWrongMimeType");
     return NS_ERROR_CORRUPTED_CONTENT;
   }
 
   if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("text/plain"))) {
     // script load has type text/plain
     AccumulateCategorical(
-        Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_2::text_plain);
+        Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_plain);
     return NS_OK;
   }
 
   if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("text/xml"))) {
     // script load has type text/xml
     AccumulateCategorical(
-        Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_2::text_xml);
+        Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_xml);
     return NS_OK;
   }
 
   if (StringBeginsWith(contentType,
                        NS_LITERAL_CSTRING("application/octet-stream"))) {
     // script load has type application/octet-stream
     AccumulateCategorical(
-        Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_2::app_octet_stream);
+        Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::app_octet_stream);
     return NS_OK;
   }
 
   if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("application/xml"))) {
     // script load has type application/xml
     AccumulateCategorical(
-        Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_2::app_xml);
+        Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::app_xml);
+    return NS_OK;
+  }
+
+  if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("application/json"))) {
+    // script load has type application/json
+    AccumulateCategorical(
+        Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::app_json);
+    return NS_OK;
+  }
+
+  if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("text/json"))) {
+    // script load has type text/json
+    AccumulateCategorical(
+        Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_json);
     return NS_OK;
   }
 
   if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("text/html"))) {
     // script load has type text/html
     AccumulateCategorical(
-        Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_2::text_html);
+        Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_html);
     return NS_OK;
   }
 
   if (contentType.IsEmpty()) {
     // script load has no type
     AccumulateCategorical(
-        Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_2::empty);
+        Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::empty);
     return NS_OK;
   }
 
   // script load has unknown type
   AccumulateCategorical(
-      Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_2::unknown);
+      Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::unknown);
   return NS_OK;
 }
 
 nsresult nsHttpChannel::CallOnStartRequest() {
   LOG(("nsHttpChannel::CallOnStartRequest [this=%p]", this));
 
   MOZ_RELEASE_ASSERT(!mRequireCORSPreflight || mIsCorsPreflightDone,
                      "CORS preflight must have been finished by the time we "
--- a/old-configure.in
+++ b/old-configure.in
@@ -399,16 +399,17 @@ fi
 
 dnl ========================================================
 dnl Add optional and non-optional hardening flags
 dnl ========================================================
 
 CFLAGS="$CFLAGS $MOZ_HARDENING_CFLAGS"
 CPPFLAGS="$CPPFLAGS $MOZ_HARDENING_CFLAGS"
 CXXFLAGS="$CXXFLAGS $MOZ_HARDENING_CFLAGS"
+LDFLAGS="$LDFLAGS $MOZ_HARDENING_LDFLAGS"
 
 dnl ========================================================
 dnl GNU specific defaults
 dnl ========================================================
 if test "$GNU_CC"; then
     MMX_FLAGS="-mmmx"
     SSE_FLAGS="-msse"
     SSE2_FLAGS="-msse2"
deleted file mode 100644
--- a/testing/web-platform/meta/fetch/api/basic/request-headers-case.any.js.ini
+++ /dev/null
@@ -1,15 +0,0 @@
-[request-headers-case.any.html]
-  [Multiple headers with the same name, different case (THIS-is-A-test first)]
-    expected: FAIL
-
-  [Multiple headers with the same name, different case (THIS-IS-A-TEST first)]
-    expected: FAIL
-
-
-[request-headers-case.any.worker.html]
-  [Multiple headers with the same name, different case (THIS-is-A-test first)]
-    expected: FAIL
-
-  [Multiple headers with the same name, different case (THIS-IS-A-TEST first)]
-    expected: FAIL
-
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -7892,24 +7892,24 @@
   },
   "SAFE_MODE_USAGE": {
     "record_in_processes": ["main", "content"],
     "expires_in_version": "never",
     "kind": "enumerated",
     "n_values": 3,
     "description": "Whether the user is in safe mode (No, Yes, Forced)"
   },
-  "SCRIPT_BLOCK_INCORRECT_MIME_2": {
+  "SCRIPT_BLOCK_INCORRECT_MIME_3": {
     "record_in_processes": ["main", "content"],
     "alert_emails": ["ckerschbaumer@mozilla.com"],
-    "bug_numbers": [1288361, 1299267, 1399990],
-    "expires_in_version": "63",
+    "bug_numbers": [1288361, 1299267, 1399990, 1510225],
+    "expires_in_version": "70",
     "kind": "categorical",
-    "labels": ["unknown","javaScript","image", "audio", "video","text_plain","text_csv","text_xml","app_octet_stream","app_xml","text_html","empty","worker_load","importSript_load","script_load","same_origin","CORS_origin","cross_origin"],
-    "description": "Whether the script load has a MIME type of ...?  (unknown, javaScript, image, audio, video, text_plain, text_csv, text_xml, app_octet_stream, app_xml, text_html, empty). Whether the script load is from ...?  (worker_load, importSript_load, script_load). Whether the script load is of ...?  (same_origin, CORS_origin, cross_origin)"
+    "labels": ["unknown","javaScript","image", "audio", "video","text_plain","text_csv","text_xml","app_octet_stream","app_xml","app_json","text_json","text_html","empty","serviceworker_load","worker_load","importScript_load","script_load","same_origin","CORS_origin","cross_origin"],
+    "description": "Whether the script load has a MIME type of ...?  (unknown, javaScript, image, audio, video, text_plain, text_csv, text_xml, app_octet_stream, app_xml, app_json, text_json, text_html, empty). Whether the script load is from ...?  (serviceworker_load, worker_load, importSript_load, script_load). Whether the script load is of ...?  (same_origin, CORS_origin, cross_origin)"
   },
   "NEWTAB_PAGE_ENABLED": {
     "record_in_processes": ["main", "content"],
     "expires_in_version": "default",
     "kind": "boolean",
     "description": "New tab page is enabled."
   },
   "NEWTAB_PAGE_ENHANCED": {