Bug 1211751: Remove nsIChannelEventSink-forwarding from EventSource and FetchDriver. It's never needed. r=smaug
authorJonas Sicking <jonas@sicking.cc>
Thu, 08 Oct 2015 13:41:38 -0700
changeset 288169 571d943ef5fffb60d6e6144e63a178adaf644576
parent 288168 298e7602ddcdd546bea061ccb9afe2f57d641169
child 288170 8c1e280e0bb545391c3ac9c8e29c1504a2593b06
push id8654
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:48:40 +0000
treeherdermozilla-aurora@bc4551debe17 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1211751
milestone44.0a1
Bug 1211751: Remove nsIChannelEventSink-forwarding from EventSource and FetchDriver. It's never needed. r=smaug
dom/base/EventSource.cpp
dom/base/EventSource.h
dom/fetch/FetchDriver.cpp
dom/fetch/FetchDriver.h
--- a/dom/base/EventSource.cpp
+++ b/dom/base/EventSource.cpp
@@ -109,19 +109,17 @@ NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_E
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(EventSource,
                                                DOMEventTargetHelper)
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(EventSource,
                                                   DOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSrc)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNotificationCallbacks)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLoadGroup)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChannelEventSink)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mHttpChannel)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTimer)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mUnicodeDecoder)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(EventSource,
                                                 DOMEventTargetHelper)
   tmp->Close();
@@ -485,58 +483,16 @@ EventSource::OnStopRequest(nsIRequest *a
   NS_ENSURE_STATE(event);
 
   rv = NS_DispatchToMainThread(event);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
-/**
- * Simple helper class that just forwards the redirect callback back
- * to the EventSource.
- */
-class AsyncVerifyRedirectCallbackFwr final : public nsIAsyncVerifyRedirectCallback
-{
-public:
-  explicit AsyncVerifyRedirectCallbackFwr(EventSource* aEventsource)
-    : mEventSource(aEventsource)
-  {
-  }
-
-  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_CLASS(AsyncVerifyRedirectCallbackFwr)
-
-  // nsIAsyncVerifyRedirectCallback implementation
-  NS_IMETHOD OnRedirectVerifyCallback(nsresult aResult) override
-  {
-    nsresult rv = mEventSource->OnRedirectVerifyCallback(aResult);
-    if (NS_FAILED(rv)) {
-      mEventSource->mErrorLoadOnRedirect = true;
-      mEventSource->DispatchFailConnection();
-    }
-
-    return NS_OK;
-  }
-
-private:
-  ~AsyncVerifyRedirectCallbackFwr() {}
-  nsRefPtr<EventSource> mEventSource;
-};
-
-NS_IMPL_CYCLE_COLLECTION(AsyncVerifyRedirectCallbackFwr, mEventSource)
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AsyncVerifyRedirectCallbackFwr)
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-  NS_INTERFACE_MAP_ENTRY(nsIAsyncVerifyRedirectCallback)
-NS_INTERFACE_MAP_END
-
-NS_IMPL_CYCLE_COLLECTING_ADDREF(AsyncVerifyRedirectCallbackFwr)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(AsyncVerifyRedirectCallbackFwr)
-
 //-----------------------------------------------------------------------------
 // EventSource::nsIChannelEventSink
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 EventSource::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
                                     nsIChannel *aNewChannel,
                                     uint32_t    aFlags,
@@ -559,99 +515,48 @@ EventSource::AsyncOnChannelRedirect(nsIC
     (NS_SUCCEEDED(newURI->SchemeIs("https", &isValidScheme)) && isValidScheme);
 
   rv = CheckInnerWindowCorrectness();
   if (NS_FAILED(rv) || !isValidScheme) {
      DispatchFailConnection();
      return NS_ERROR_DOM_SECURITY_ERR;
   }
 
-  // Prepare to receive callback
-  mRedirectFlags = aFlags;
-  mRedirectCallback = aCallback;
-  mNewRedirectChannel = aNewChannel;
-
-  if (mChannelEventSink) {
-    nsRefPtr<AsyncVerifyRedirectCallbackFwr> fwd =
-      new AsyncVerifyRedirectCallbackFwr(this);
-
-    rv = mChannelEventSink->AsyncOnChannelRedirect(aOldChannel,
-                                                   aNewChannel,
-                                                   aFlags, fwd);
-    if (NS_FAILED(rv)) {
-      mRedirectCallback = nullptr;
-      mNewRedirectChannel = nullptr;
-      mErrorLoadOnRedirect = true;
-      DispatchFailConnection();
-    }
-    return rv;
-  }
-  OnRedirectVerifyCallback(NS_OK);
-  return NS_OK;
-}
-
-nsresult
-EventSource::OnRedirectVerifyCallback(nsresult aResult)
-{
-  MOZ_ASSERT(mRedirectCallback, "mRedirectCallback not set in callback");
-  MOZ_ASSERT(mNewRedirectChannel,
-             "mNewRedirectChannel not set in callback");
-
-  NS_ENSURE_SUCCESS(aResult, aResult);
-
   // update our channel
 
-  mHttpChannel = do_QueryInterface(mNewRedirectChannel);
+  mHttpChannel = do_QueryInterface(aNewChannel);
   NS_ENSURE_STATE(mHttpChannel);
 
-  nsresult rv = SetupHttpChannel();
+  rv = SetupHttpChannel();
   NS_ENSURE_SUCCESS(rv, rv);
 
-  if ((mRedirectFlags & nsIChannelEventSink::REDIRECT_PERMANENT) != 0) {
+  if ((aFlags & nsIChannelEventSink::REDIRECT_PERMANENT) != 0) {
     rv = NS_GetFinalChannelURI(mHttpChannel, getter_AddRefs(mSrc));
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
-  mNewRedirectChannel = nullptr;
-
-  mRedirectCallback->OnRedirectVerifyCallback(aResult);
-  mRedirectCallback = nullptr;
+  aCallback->OnRedirectVerifyCallback(NS_OK);
 
   return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 // EventSource::nsIInterfaceRequestor
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 EventSource::GetInterface(const nsIID & aIID,
                           void **aResult)
 {
-  // Make sure to return ourselves for the channel event sink interface,
-  // no matter what.  We can forward these to mNotificationCallbacks
-  // if it wants to get notifications for them.  But we
-  // need to see these notifications for proper functioning.
   if (aIID.Equals(NS_GET_IID(nsIChannelEventSink))) {
-    mChannelEventSink = do_GetInterface(mNotificationCallbacks);
     *aResult = static_cast<nsIChannelEventSink*>(this);
     NS_ADDREF_THIS();
     return NS_OK;
   }
 
-  // Now give mNotificationCallbacks (if non-null) a chance to return the
-  // desired interface.
-  if (mNotificationCallbacks) {
-    nsresult rv = mNotificationCallbacks->GetInterface(aIID, aResult);
-    if (NS_SUCCEEDED(rv)) {
-      NS_ASSERTION(*aResult, "Lying nsIInterfaceRequestor implementation!");
-      return rv;
-    }
-  }
-
   if (aIID.Equals(NS_GET_IID(nsIAuthPrompt)) ||
       aIID.Equals(NS_GET_IID(nsIAuthPrompt2))) {
     nsresult rv = CheckInnerWindowCorrectness();
     NS_ENSURE_SUCCESS(rv, NS_ERROR_UNEXPECTED);
 
     nsCOMPtr<nsIPromptFactory> wwatch =
       do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
     NS_ENSURE_SUCCESS(rv, rv);
@@ -802,22 +707,24 @@ EventSource::InitChannelAndRequestEventS
   NS_ENSURE_SUCCESS(rv, rv);
 
   mHttpChannel = do_QueryInterface(channel);
   NS_ENSURE_TRUE(mHttpChannel, NS_ERROR_NO_INTERFACE);
 
   rv = SetupHttpChannel();
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCOMPtr<nsIInterfaceRequestor> notificationCallbacks;
-  mHttpChannel->GetNotificationCallbacks(getter_AddRefs(notificationCallbacks));
-  if (notificationCallbacks != this) {
-    mNotificationCallbacks = notificationCallbacks;
-    mHttpChannel->SetNotificationCallbacks(this);
+#ifdef DEBUG
+  {
+    nsCOMPtr<nsIInterfaceRequestor> notificationCallbacks;
+    mHttpChannel->GetNotificationCallbacks(getter_AddRefs(notificationCallbacks));
+    MOZ_ASSERT(!notificationCallbacks);
   }
+#endif
+  mHttpChannel->SetNotificationCallbacks(this);
 
   // Start reading from the channel
   rv = mHttpChannel->AsyncOpen2(this);
   if (NS_FAILED(rv)) {
     DispatchFailConnection();
     return rv;
   }
   mWaitingForOnStopRequest = true;
@@ -873,21 +780,17 @@ EventSource::ResetConnection()
   }
 
   if (mUnicodeDecoder) {
     mUnicodeDecoder->Reset();
   }
   mLastConvertionResult = NS_OK;
 
   mHttpChannel = nullptr;
-  mNotificationCallbacks = nullptr;
-  mChannelEventSink = nullptr;
   mStatus = PARSE_STATE_OFF;
-  mRedirectCallback = nullptr;
-  mNewRedirectChannel = nullptr;
 
   mReadyState = CONNECTING;
 
   return NS_OK;
 }
 
 void
 EventSource::ReestablishConnection()
--- a/dom/base/EventSource.h
+++ b/dom/base/EventSource.h
@@ -29,28 +29,25 @@
 class nsPIDOMWindow;
 
 namespace mozilla {
 
 class ErrorResult;
 
 namespace dom {
 
-class AsyncVerifyRedirectCallbackFwr;
 struct EventSourceInit;
 
 class EventSource final : public DOMEventTargetHelper
                         , public nsIObserver
                         , public nsIStreamListener
                         , public nsIChannelEventSink
                         , public nsIInterfaceRequestor
                         , public nsSupportsWeakReference
 {
-friend class AsyncVerifyRedirectCallbackFwr;
-
 public:
   explicit EventSource(nsPIDOMWindow* aOwnerWindow);
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_INHERITED(
     EventSource, DOMEventTargetHelper)
 
   NS_DECL_NSIOBSERVER
   NS_DECL_NSISTREAMLISTENER
@@ -227,37 +224,26 @@ protected:
   // used while reading the input streams
   nsCOMPtr<nsIUnicodeDecoder> mUnicodeDecoder;
   nsresult mLastConvertionResult;
   nsString mLastFieldName;
   nsString mLastFieldValue;
 
   nsCOMPtr<nsILoadGroup> mLoadGroup;
 
-  /**
-   * The notification callbacks the channel had initially.
-   * We want to forward things here as needed.
-   */
-  nsCOMPtr<nsIInterfaceRequestor> mNotificationCallbacks;
-  nsCOMPtr<nsIChannelEventSink>   mChannelEventSink;
-
   nsCOMPtr<nsIHttpChannel> mHttpChannel;
 
   nsCOMPtr<nsITimer> mTimer;
 
   uint16_t mReadyState;
   nsString mOriginalURL;
 
   nsCOMPtr<nsIPrincipal> mPrincipal;
   nsString mOrigin;
 
-  uint32_t mRedirectFlags;
-  nsCOMPtr<nsIAsyncVerifyRedirectCallback> mRedirectCallback;
-  nsCOMPtr<nsIChannel> mNewRedirectChannel;
-
   // Event Source owner information:
   // - the script file name
   // - source code line number and column number where the Event Source object
   //   was constructed.
   // - the ID of the inner window where the script lives. Note that this may not
   //   be the same as the Event Source owner window.
   // These attributes are used for error reporting.
   nsString mScriptFile;
--- a/dom/fetch/FetchDriver.cpp
+++ b/dom/fetch/FetchDriver.cpp
@@ -2,16 +2,17 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 "mozilla/DebugOnly.h"
 #include "mozilla/dom/FetchDriver.h"
 
+#include "nsIAsyncVerifyRedirectCallback.h"
 #include "nsIDocument.h"
 #include "nsIInputStream.h"
 #include "nsIOutputStream.h"
 #include "nsIHttpChannel.h"
 #include "nsIHttpChannelInternal.h"
 #include "nsIHttpHeaderVisitor.h"
 #include "nsIJARChannel.h"
 #include "nsIScriptSecurityManager.h"
@@ -37,17 +38,17 @@
 #include "InternalRequest.h"
 #include "InternalResponse.h"
 
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_ISUPPORTS(FetchDriver,
                   nsIStreamListener, nsIChannelEventSink, nsIInterfaceRequestor,
-                  nsIAsyncVerifyRedirectCallback, nsIThreadRetargetableStreamListener)
+                  nsIThreadRetargetableStreamListener)
 
 FetchDriver::FetchDriver(InternalRequest* aRequest, nsIPrincipal* aPrincipal,
                          nsILoadGroup* aLoadGroup)
   : mPrincipal(aPrincipal)
   , mLoadGroup(aLoadGroup)
   , mRequest(aRequest)
   , mFetchRecursionCount(0)
   , mCORSFlagEverSet(false)
@@ -454,17 +455,23 @@ FetchDriver::HttpFetch(bool aCORSFlag, b
   mLoadGroup = nullptr;
   if (NS_WARN_IF(NS_FAILED(rv))) {
     FailWithNetworkError();
     return rv;
   }
 
   // Insert ourselves into the notification callbacks chain so we can handle
   // cross-origin redirects.
-  chan->GetNotificationCallbacks(getter_AddRefs(mNotificationCallbacks));
+#ifdef DEBUG
+  {
+    nsCOMPtr<nsIInterfaceRequestor> notificationCallbacks;
+    chan->GetNotificationCallbacks(getter_AddRefs(notificationCallbacks));
+    MOZ_ASSERT(!notificationCallbacks);
+  }
+#endif
   chan->SetNotificationCallbacks(this);
 
   // FIXME(nsm): Bug 1120715.
   // Step 3.4 "If request's cache mode is default and request's header list
   // contains a header named `If-Modified-Since`, `If-None-Match`,
   // `If-Unmodified-Since`, `If-Match`, or `If-Range`, set request's cache mode
   // to no-store."
 
@@ -910,18 +917,16 @@ FetchDriver::OnStopRequest(nsIRequest* a
 NS_IMETHODIMP
 FetchDriver::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
                                     nsIChannel* aNewChannel,
                                     uint32_t aFlags,
                                     nsIAsyncVerifyRedirectCallback *aCallback)
 {
   NS_PRECONDITION(aNewChannel, "Redirect without a channel?");
 
-  nsresult rv;
-
   // HTTP Fetch step 5, "redirect status", step 1
   if (NS_WARN_IF(mRequest->GetRedirectMode() == RequestRedirect::Error)) {
     aOldChannel->Cancel(NS_BINDING_FAILED);
     return NS_BINDING_FAILED;
   }
 
   // HTTP Fetch step 5, "redirect status", steps 2 through 6 are automatically
   // handled by necko before calling AsyncOnChannelRedirect() with the new
@@ -965,37 +970,95 @@ FetchDriver::AsyncOnChannelRedirect(nsIC
   // The following steps are from HTTP Fetch step 5, "redirect status", step 11
   // which requires the RequestRedirect to be "follow".
   MOZ_ASSERT(mRequest->GetRedirectMode() == RequestRedirect::Follow);
 
   // HTTP Fetch step 5, "redirect status", steps 11.1 and 11.2 block redirecting
   // to a URL with credentials in CORS mode.  This is implemented in
   // nsCORSListenerProxy.
 
-  mRedirectCallback = aCallback;
-  mOldRedirectChannel = aOldChannel;
-  mNewRedirectChannel = aNewChannel;
+  // On a successful redirect we perform the following substeps of HTTP Fetch,
+  // step 5, "redirect status", step 11.
 
-  nsCOMPtr<nsIChannelEventSink> outer =
-    do_GetInterface(mNotificationCallbacks);
-  if (outer) {
-    // The callee is supposed to call OnRedirectVerifyCallback() on success,
-    // and nobody has to call it on failure, so we can just return after this
-    // block.
-    rv = outer->AsyncOnChannelRedirect(aOldChannel, aNewChannel, aFlags, this);
-    if (NS_FAILED(rv)) {
-      aOldChannel->Cancel(rv);
-      mRedirectCallback = nullptr;
-      mOldRedirectChannel = nullptr;
-      mNewRedirectChannel = nullptr;
-    }
+  // Step 11.5 "Append locationURL to request's url list." so that when we set the
+  // Response's URL from the Request's URL in Main Fetch, step 15, we get the
+  // final value. Note, we still use a single URL value instead of a list.
+  nsCOMPtr<nsIURI> newURI;
+  nsresult rv = NS_GetFinalChannelURI(aNewChannel, getter_AddRefs(newURI));
+  if (NS_FAILED(rv)) {
+    aOldChannel->Cancel(rv);
     return rv;
   }
 
-  (void) OnRedirectVerifyCallback(NS_OK);
+  // We need to update our request's URL.
+  nsAutoCString newUrl;
+  newURI->GetSpec(newUrl);
+  mRequest->SetURL(newUrl);
+
+  // Implement Main Fetch step 8 again on redirect.
+  MainFetchOp nextOp = SetTaintingAndGetNextOp(mCORSFlagEverSet);
+
+  if (nextOp.mType == NETWORK_ERROR) {
+    // Cancel the channel if Main Fetch blocks the redirect from continuing.
+    aOldChannel->Cancel(NS_ERROR_DOM_BAD_URI);
+    return NS_ERROR_DOM_BAD_URI;
+  }
+
+  // Otherwise, we rely on necko and the CORS proxy to do the right thing
+  // as the redirect is followed.  In general this means basic or http
+  // fetch.  If we've ever been CORS, we need to stay CORS.
+  MOZ_ASSERT(nextOp.mType == BASIC_FETCH || nextOp.mType == HTTP_FETCH);
+  MOZ_ASSERT_IF(mCORSFlagEverSet, nextOp.mType == HTTP_FETCH);
+  MOZ_ASSERT_IF(mCORSFlagEverSet, nextOp.mCORSFlag);
+
+  // Examine and possibly set the LOAD_ANONYMOUS flag on the channel.
+  nsLoadFlags flags;
+  rv = aNewChannel->GetLoadFlags(&flags);
+  if (NS_FAILED(rv)) {
+    aOldChannel->Cancel(rv);
+    return rv;
+  }
+
+  if (mRequest->GetCredentialsMode() == RequestCredentials::Same_origin &&
+      mRequest->GetResponseTainting() == InternalRequest::RESPONSETAINT_OPAQUE) {
+    // In the case of a "no-cors" mode request with "same-origin" credentials,
+    // we have to set LOAD_ANONYMOUS manually here in order to avoid sending
+    // credentials on a cross-origin redirect.
+    flags |= nsIRequest::LOAD_ANONYMOUS;
+    rv = aNewChannel->SetLoadFlags(flags);
+    if (NS_FAILED(rv)) {
+      aOldChannel->Cancel(rv);
+      return rv;
+    }
+
+  } else if (mRequest->GetCredentialsMode() == RequestCredentials::Omit) {
+    // Make sure nothing in the redirect chain screws up our credentials
+    // settings.  LOAD_ANONYMOUS must be set if we RequestCredentials is "omit".
+    MOZ_ASSERT(flags & nsIRequest::LOAD_ANONYMOUS);
+
+  } else if (mRequest->GetCredentialsMode() == RequestCredentials::Same_origin &&
+             nextOp.mCORSFlag) {
+    // We also want to verify the LOAD_ANONYMOUS flag is set when we are in
+    // "same-origin" credentials mode and the CORS flag is set.  We can't
+    // unconditionally assert here, however, because the nsCORSListenerProxy
+    // will set the flag later in the redirect callback chain.  Instead,
+    // perform a weaker assertion here by checking if CORS flag was set
+    // before this redirect.  In that case LOAD_ANONYMOUS must still be set.
+    MOZ_ASSERT_IF(mCORSFlagEverSet, flags & nsIRequest::LOAD_ANONYMOUS);
+
+  } else {
+    // Otherwise, we should be sending credentials
+    MOZ_ASSERT(!(flags & nsIRequest::LOAD_ANONYMOUS));
+  }
+
+  // Track the CORSFlag through redirects.
+  mCORSFlagEverSet = mCORSFlagEverSet || nextOp.mCORSFlag;
+
+  aCallback->OnRedirectVerifyCallback(NS_OK);
+
   return NS_OK;
 }
 
 NS_IMETHODIMP
 FetchDriver::CheckListenerChain()
 {
   return NS_OK;
 }
@@ -1031,123 +1094,30 @@ NS_IMETHODIMP
 FetchDriver::GetInterface(const nsIID& aIID, void **aResult)
 {
   if (aIID.Equals(NS_GET_IID(nsIChannelEventSink))) {
     *aResult = static_cast<nsIChannelEventSink*>(this);
     NS_ADDREF_THIS();
     return NS_OK;
   }
 
-  nsresult rv;
-
-  if (mNotificationCallbacks) {
-    rv = mNotificationCallbacks->GetInterface(aIID, aResult);
-    if (NS_SUCCEEDED(rv)) {
-      NS_ASSERTION(*aResult, "Lying nsIInterfaceRequestor implementation!");
-      return rv;
-    }
-  }
-  else if (aIID.Equals(NS_GET_IID(nsIStreamListener))) {
+  if (aIID.Equals(NS_GET_IID(nsIStreamListener))) {
     *aResult = static_cast<nsIStreamListener*>(this);
     NS_ADDREF_THIS();
     return NS_OK;
   }
-  else if (aIID.Equals(NS_GET_IID(nsIRequestObserver))) {
+  if (aIID.Equals(NS_GET_IID(nsIRequestObserver))) {
     *aResult = static_cast<nsIRequestObserver*>(this);
     NS_ADDREF_THIS();
     return NS_OK;
   }
 
   return QueryInterface(aIID, aResult);
 }
 
-NS_IMETHODIMP
-FetchDriver::OnRedirectVerifyCallback(nsresult aResult)
-{
-  // On a successful redirect we perform the following substeps of HTTP Fetch,
-  // step 5, "redirect status", step 11.
-  if (NS_SUCCEEDED(aResult)) {
-    // Step 11.5 "Append locationURL to request's url list." so that when we set the
-    // Response's URL from the Request's URL in Main Fetch, step 15, we get the
-    // final value. Note, we still use a single URL value instead of a list.
-    nsCOMPtr<nsIURI> newURI;
-    nsresult rv = NS_GetFinalChannelURI(mNewRedirectChannel, getter_AddRefs(newURI));
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      aResult = rv;
-    } else {
-      // We need to update our request's URL.
-      nsAutoCString newUrl;
-      newURI->GetSpec(newUrl);
-      mRequest->SetURL(newUrl);
-    }
-  }
-
-  if (NS_FAILED(aResult)) {
-    mOldRedirectChannel->Cancel(aResult);
-  }
-
-  // Implement Main Fetch step 8 again on redirect.
-  MainFetchOp nextOp = SetTaintingAndGetNextOp(mCORSFlagEverSet);
-
-  if (nextOp.mType == NETWORK_ERROR) {
-    // Cancel the channel if Main Fetch blocks the redirect from continuing.
-    aResult = NS_ERROR_DOM_BAD_URI;
-    mOldRedirectChannel->Cancel(aResult);
-  } else {
-    // Otherwise, we rely on necko and the CORS proxy to do the right thing
-    // as the redirect is followed.  In general this means basic or http
-    // fetch.  If we've ever been CORS, we need to stay CORS.
-    MOZ_ASSERT(nextOp.mType == BASIC_FETCH || nextOp.mType == HTTP_FETCH);
-    MOZ_ASSERT_IF(mCORSFlagEverSet, nextOp.mType == HTTP_FETCH);
-    MOZ_ASSERT_IF(mCORSFlagEverSet, nextOp.mCORSFlag);
-
-    // Examine and possibly set the LOAD_ANONYMOUS flag on the channel.
-    nsLoadFlags flags;
-    aResult = mNewRedirectChannel->GetLoadFlags(&flags);
-    if (NS_SUCCEEDED(aResult)) {
-      if (mRequest->GetCredentialsMode() == RequestCredentials::Same_origin &&
-          mRequest->GetResponseTainting() == InternalRequest::RESPONSETAINT_OPAQUE) {
-        // In the case of a "no-cors" mode request with "same-origin" credentials,
-        // we have to set LOAD_ANONYMOUS manually here in order to avoid sending
-        // credentials on a cross-origin redirect.
-        flags |= nsIRequest::LOAD_ANONYMOUS;
-        aResult = mNewRedirectChannel->SetLoadFlags(flags);
-
-      } else if (mRequest->GetCredentialsMode() == RequestCredentials::Omit) {
-        // Make sure nothing in the redirect chain screws up our credentials
-        // settings.  LOAD_ANONYMOUS must be set if we RequestCredentials is "omit".
-        MOZ_ASSERT(flags & nsIRequest::LOAD_ANONYMOUS);
-
-      } else if (mRequest->GetCredentialsMode() == RequestCredentials::Same_origin &&
-                 nextOp.mCORSFlag) {
-        // We also want to verify the LOAD_ANONYMOUS flag is set when we are in
-        // "same-origin" credentials mode and the CORS flag is set.  We can't
-        // unconditionally assert here, however, because the nsCORSListenerProxy
-        // will set the flag later in the redirect callback chain.  Instead,
-        // perform a weaker assertion here by checking if CORS flag was set
-        // before this redirect.  In that case LOAD_ANONYMOUS must still be set.
-        MOZ_ASSERT_IF(mCORSFlagEverSet, flags & nsIRequest::LOAD_ANONYMOUS);
-
-      } else {
-        // Otherwise, we should be sending credentials
-        MOZ_ASSERT(!(flags & nsIRequest::LOAD_ANONYMOUS));
-      }
-    }
-
-    // Track the CORSFlag through redirects.
-    mCORSFlagEverSet = mCORSFlagEverSet || nextOp.mCORSFlag;
-  }
-
-  mOldRedirectChannel = nullptr;
-  mNewRedirectChannel = nullptr;
-  mRedirectCallback->OnRedirectVerifyCallback(aResult);
-  mRedirectCallback = nullptr;
-  return NS_OK;
-}
-
 void
 FetchDriver::SetDocument(nsIDocument* aDocument)
 {
   // Cannot set document after Fetch() has been called.
   MOZ_ASSERT(mFetchRecursionCount == 0);
   mDocument = aDocument;
 }
 
--- a/dom/fetch/FetchDriver.h
+++ b/dom/fetch/FetchDriver.h
@@ -3,17 +3,16 @@
 /* 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/. */
 
 #ifndef mozilla_dom_FetchDriver_h
 #define mozilla_dom_FetchDriver_h
 
 #include "nsAutoPtr.h"
-#include "nsIAsyncVerifyRedirectCallback.h"
 #include "nsIChannelEventSink.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIStreamListener.h"
 #include "nsIThreadRetargetableStreamListener.h"
 #include "mozilla/nsRefPtr.h"
 
 #include "mozilla/DebugOnly.h"
 #include "mozilla/net/ReferrerPolicy.h"
@@ -53,46 +52,40 @@ protected:
 
 private:
   bool mGotResponseAvailable;
 };
 
 class FetchDriver final : public nsIStreamListener,
                           public nsIChannelEventSink,
                           public nsIInterfaceRequestor,
-                          public nsIAsyncVerifyRedirectCallback,
                           public nsIThreadRetargetableStreamListener
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIREQUESTOBSERVER
   NS_DECL_NSISTREAMLISTENER
   NS_DECL_NSICHANNELEVENTSINK
   NS_DECL_NSIINTERFACEREQUESTOR
-  NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK
   NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
 
   explicit FetchDriver(InternalRequest* aRequest, nsIPrincipal* aPrincipal,
                        nsILoadGroup* aLoadGroup);
   NS_IMETHOD Fetch(FetchDriverObserver* aObserver);
 
   void
   SetDocument(nsIDocument* aDocument);
 
 private:
   nsCOMPtr<nsIPrincipal> mPrincipal;
   nsCOMPtr<nsILoadGroup> mLoadGroup;
   nsRefPtr<InternalRequest> mRequest;
   nsRefPtr<InternalResponse> mResponse;
   nsCOMPtr<nsIOutputStream> mPipeOutputStream;
   nsRefPtr<FetchDriverObserver> mObserver;
-  nsCOMPtr<nsIInterfaceRequestor> mNotificationCallbacks;
-  nsCOMPtr<nsIAsyncVerifyRedirectCallback> mRedirectCallback;
-  nsCOMPtr<nsIChannel> mOldRedirectChannel;
-  nsCOMPtr<nsIChannel> mNewRedirectChannel;
   nsCOMPtr<nsIDocument> mDocument;
   uint32_t mFetchRecursionCount;
   bool mCORSFlagEverSet;
 
   DebugOnly<bool> mResponseAvailableCalled;
 
   FetchDriver() = delete;
   FetchDriver(const FetchDriver&) = delete;