Backed out 4 changesets (bug 1525319) for Android failures in dom/base/test/test_progress_events_for_gzip_data.html
authorDorel Luca <dluca@mozilla.com>
Mon, 25 Feb 2019 04:06:11 +0200
changeset 518718 d5643033fdd801efda790a2836a3e196e7ba442e
parent 518717 9bae35dc1471ff97f0efba49083bb165453ebf35
child 518719 aee528adc1f72e0b250ba0e4fe2f781bd1446b1f
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1525319
milestone67.0a1
backs outb73f033efb41e21920b61fb97690fc3499d3f64b
1d318d5c6b9861302b9cba1c107eb5e74d98c600
6d73418988d4f350e0a9e7e9948e2efed035b09b
84ca79bd2dc3f9ac87b63356f7a34880ce4acd1d
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
Backed out 4 changesets (bug 1525319) for Android failures in dom/base/test/test_progress_events_for_gzip_data.html Backed out changeset b73f033efb41 (bug 1525319) Backed out changeset 1d318d5c6b98 (bug 1525319) Backed out changeset 6d73418988d4 (bug 1525319) Backed out changeset 84ca79bd2dc3 (bug 1525319)
browser/base/content/aboutDialog-appUpdater.js
browser/base/content/nsContextMenu.js
browser/extensions/pdfjs/content/PdfStreamConverter.jsm
browser/modules/FaviconLoader.jsm
devtools/client/jsonview/converter-child.js
devtools/client/netmonitor/test/sjs_content-type-test-server.sjs
devtools/server/actors/network-monitor/network-response-listener.js
devtools/shared/webconsole/test/unit/test_throttle.js
devtools/shared/webconsole/throttle.js
docshell/base/nsPingListener.cpp
dom/base/DOMParser.cpp
dom/base/Document.cpp
dom/base/EventSource.cpp
dom/base/Navigator.cpp
dom/base/nsObjectLoadingContent.cpp
dom/base/nsSyncLoadService.cpp
dom/base/test/chrome/test_bug682305.html
dom/base/test/send_gzip_content.sjs
dom/fetch/FetchDriver.cpp
dom/file/MutableBlobStreamListener.cpp
dom/html/HTMLMediaElement.cpp
dom/html/ImageDocument.cpp
dom/html/MediaDocument.cpp
dom/html/PluginDocument.cpp
dom/jsurl/nsJSProtocolHandler.cpp
dom/media/ChannelMediaResource.cpp
dom/media/IdpSandbox.jsm
dom/media/WebVTTListener.cpp
dom/network/TCPSocket.cpp
dom/plugins/base/nsPluginStreamListenerPeer.cpp
dom/presentation/PresentationTCPSessionTransport.cpp
dom/presentation/provider/PresentationControlService.jsm
dom/push/PushServiceHttp2.jsm
dom/security/ContentVerifier.cpp
dom/security/nsCSPContext.cpp
dom/security/test/unit/test_csp_upgrade_insecure_request_header.js
dom/serviceworkers/ServiceWorkerScriptCache.cpp
dom/webbrowserpersist/nsWebBrowserPersist.cpp
dom/workers/ScriptLoader.cpp
dom/xbl/nsXBLService.cpp
dom/xhr/XMLHttpRequestMainThread.cpp
dom/xslt/xslt/txMozillaStylesheetCompiler.cpp
dom/xul/XULDocument.cpp
extensions/pref/autoconfig/src/nsAutoConfig.cpp
gfx/thebes/gfxSVGGlyphs.cpp
image/ImageFactory.cpp
image/SVGDocumentWrapper.cpp
image/VectorImage.cpp
image/decoders/icon/mac/nsIconChannelCocoa.mm
image/decoders/icon/win/nsIconChannel.cpp
image/imgLoader.cpp
image/imgRequest.cpp
image/test/unit/image_load_helpers.js
layout/style/StreamLoader.cpp
layout/style/nsFontFaceLoader.cpp
media/mtransport/ipc/WebrtcProxyChannel.cpp
mobile/android/chrome/content/CastingApps.js
modules/libjar/nsJARChannel.cpp
modules/libjar/test/unit/test_jarchannel.js
modules/libjar/zipwriter/nsDeflateConverter.cpp
modules/libjar/zipwriter/nsZipDataStream.cpp
modules/libjar/zipwriter/nsZipWriter.cpp
modules/libjar/zipwriter/test/unit/test_asyncadd.js
modules/libjar/zipwriter/test/unit/test_asyncbadadd.js
modules/libjar/zipwriter/test/unit/test_asyncbadremove.js
modules/libjar/zipwriter/test/unit/test_asyncremove.js
modules/libjar/zipwriter/test/unit/test_bug399727.js
modules/libjar/zipwriter/test/unit/test_bug717061.js
netwerk/base/BackgroundFileSaver.cpp
netwerk/base/MemoryDownloader.cpp
netwerk/base/NetUtil.jsm
netwerk/base/NetworkConnectivityService.cpp
netwerk/base/Predictor.cpp
netwerk/base/SimpleChannelParent.cpp
netwerk/base/nsAsyncStreamCopier.cpp
netwerk/base/nsBaseChannel.cpp
netwerk/base/nsDownloader.cpp
netwerk/base/nsIRequestObserver.idl
netwerk/base/nsIStreamListener.idl
netwerk/base/nsIncrementalDownload.cpp
netwerk/base/nsIncrementalStreamLoader.cpp
netwerk/base/nsInputStreamPump.cpp
netwerk/base/nsLoadGroup.cpp
netwerk/base/nsRequestObserverProxy.cpp
netwerk/base/nsSimpleStreamListener.cpp
netwerk/base/nsStreamListenerTee.cpp
netwerk/base/nsStreamLoader.cpp
netwerk/base/nsSyncStreamListener.cpp
netwerk/dns/TRR.cpp
netwerk/protocol/about/nsAboutCacheEntry.cpp
netwerk/protocol/data/DataChannelParent.cpp
netwerk/protocol/file/FileChannelParent.cpp
netwerk/protocol/ftp/FTPChannelChild.cpp
netwerk/protocol/ftp/FTPChannelParent.cpp
netwerk/protocol/ftp/nsFtpConnectionThread.cpp
netwerk/protocol/http/AlternateServices.cpp
netwerk/protocol/http/HttpBaseChannel.cpp
netwerk/protocol/http/HttpChannelChild.cpp
netwerk/protocol/http/HttpChannelParent.cpp
netwerk/protocol/http/HttpChannelParentListener.cpp
netwerk/protocol/http/InterceptedHttpChannel.cpp
netwerk/protocol/http/nsCORSListenerProxy.cpp
netwerk/protocol/http/nsHttpChannel.cpp
netwerk/protocol/res/ExtensionProtocolHandler.cpp
netwerk/protocol/viewsource/nsViewSourceChannel.cpp
netwerk/protocol/websocket/WebSocketChannel.cpp
netwerk/protocol/wyciwyg/WyciwygChannelChild.cpp
netwerk/protocol/wyciwyg/WyciwygChannelParent.cpp
netwerk/protocol/wyciwyg/nsWyciwygChannel.cpp
netwerk/streamconv/converters/mozTXTToHTMLConv.cpp
netwerk/streamconv/converters/nsDirIndexParser.cpp
netwerk/streamconv/converters/nsFTPDirListingConv.cpp
netwerk/streamconv/converters/nsHTTPCompressConv.cpp
netwerk/streamconv/converters/nsIndexedToHTML.cpp
netwerk/streamconv/converters/nsMultiMixedConv.cpp
netwerk/streamconv/converters/nsUnknownDecoder.cpp
netwerk/test/browser/browser_cross_process_redirect.js
netwerk/test/browser/browser_nsIFormPOSTActionChannel.js
netwerk/test/httpserver/httpd.js
netwerk/test/httpserver/test/head_utils.js
netwerk/test/httpserver/test/test_async_response_sending.js
netwerk/test/httpserver/test/test_basic_functionality.js
netwerk/test/httpserver/test/test_byte_range.js
netwerk/test/httpserver/test/test_cern_meta.js
netwerk/test/httpserver/test/test_default_index_handler.js
netwerk/test/httpserver/test/test_empty_body.js
netwerk/test/httpserver/test/test_errorhandler_exception.js
netwerk/test/httpserver/test/test_header_array.js
netwerk/test/httpserver/test/test_name_scheme.js
netwerk/test/httpserver/test/test_processasync.js
netwerk/test/httpserver/test/test_qi.js
netwerk/test/httpserver/test/test_registerdirectory.js
netwerk/test/httpserver/test/test_registerfile.js
netwerk/test/httpserver/test/test_response_write.js
netwerk/test/httpserver/test/test_setindexhandler.js
netwerk/test/httpserver/test/test_setstatusline.js
netwerk/test/httpserver/test/test_sjs.js
netwerk/test/httpserver/test/test_sjs_object_state.js
netwerk/test/httpserver/test/test_sjs_state.js
netwerk/test/httpserver/test/test_sjs_throwing_exceptions.js
netwerk/test/unit/head_cache2.js
netwerk/test/unit/head_channels.js
netwerk/test/unit/test_alt-data_stream.js
netwerk/test/unit/test_altsvc.js
netwerk/test/unit/test_anonymous-coalescing.js
netwerk/test/unit/test_auth_dialog_permission.js
netwerk/test/unit/test_auth_proxy.js
netwerk/test/unit/test_authentication.js
netwerk/test/unit/test_backgroundfilesaver.js
netwerk/test/unit/test_bug1218029.js
netwerk/test/unit/test_bug1279246.js
netwerk/test/unit/test_bug1312774_http1.js
netwerk/test/unit/test_bug1312782_http1.js
netwerk/test/unit/test_bug1355539_http1.js
netwerk/test/unit/test_bug1378385_http1.js
netwerk/test/unit/test_bug1411316_http1.js
netwerk/test/unit/test_bug282432.js
netwerk/test/unit/test_bug331825.js
netwerk/test/unit/test_bug365133.js
netwerk/test/unit/test_bug369787.js
netwerk/test/unit/test_bug412945.js
netwerk/test/unit/test_bug455311.js
netwerk/test/unit/test_bug470716.js
netwerk/test/unit/test_bug482601.js
netwerk/test/unit/test_bug484684.js
netwerk/test/unit/test_bug515583.js
netwerk/test/unit/test_bug536324_64bit_content_length.js
netwerk/test/unit/test_bug543805.js
netwerk/test/unit/test_bug561042.js
netwerk/test/unit/test_bug596443.js
netwerk/test/unit/test_bug618835.js
netwerk/test/unit/test_bug633743.js
netwerk/test/unit/test_bug667907.js
netwerk/test/unit/test_bug856978.js
netwerk/test/unit/test_cacheflags.js
netwerk/test/unit/test_content_length_underrun.js
netwerk/test/unit/test_content_sniffer.js
netwerk/test/unit/test_cookie_header.js
netwerk/test/unit/test_crossOriginOpenerPolicy.js
netwerk/test/unit/test_event_sink.js
netwerk/test/unit/test_file_protocol.js
netwerk/test/unit/test_freshconnection.js
netwerk/test/unit/test_getHost.js
netwerk/test/unit/test_http2.js
netwerk/test/unit/test_httpResponseTimeout.js
netwerk/test/unit/test_httpcancel.js
netwerk/test/unit/test_httpsuspend.js
netwerk/test/unit/test_immutable.js
netwerk/test/unit/test_mismatch_last-modified.js
netwerk/test/unit/test_multipart_byteranges.js
netwerk/test/unit/test_multipart_streamconv-byte-by-byte.js
netwerk/test/unit/test_multipart_streamconv.js
netwerk/test/unit/test_multipart_streamconv_missing_boundary_lead_dashes.js
netwerk/test/unit/test_multipart_streamconv_missing_lead_boundary.js
netwerk/test/unit/test_origin.js
netwerk/test/unit/test_plaintext_sniff.js
netwerk/test/unit/test_predictor.js
netwerk/test/unit/test_progress.js
netwerk/test/unit/test_protocolproxyservice.js
netwerk/test/unit/test_proxyconnect.js
netwerk/test/unit/test_range_requests.js
netwerk/test/unit/test_reentrancy.js
netwerk/test/unit/test_reopen.js
netwerk/test/unit/test_resumable_truncate.js
netwerk/test/unit/test_separate_connections.js
netwerk/test/unit/test_streamcopier.js
netwerk/test/unit/test_suspend_channel_before_connect.js
netwerk/test/unit/test_suspend_channel_on_authRetry.js
netwerk/test/unit/test_suspend_channel_on_examine_merged_response.js
netwerk/test/unit/test_tls_flags_separate_connections.js
netwerk/test/unit/test_traceable_channel.js
netwerk/test/unit/test_trackingProtection_annotateChannels.js
parser/html/nsHtml5StreamListener.cpp
parser/html/nsHtml5StreamParser.cpp
parser/html/nsHtml5StreamParser.h
parser/htmlparser/nsParser.cpp
security/manager/ssl/ContentSignatureVerifier.cpp
security/manager/ssl/PSMContentListener.cpp
security/manager/ssl/PSMContentListener.h
services/common/rest.js
services/common/utils.js
testing/specialpowers/content/specialpowersAPI.js
toolkit/components/aboutmemory/content/aboutMemory.js
toolkit/components/downloads/DownloadCore.jsm
toolkit/components/downloads/test/unit/head.js
toolkit/components/extensions/test/xpcshell/test_ext_redirects.js
toolkit/components/extensions/test/xpcshell/test_ext_webRequest_suspend.js
toolkit/components/extensions/test/xpcshell/test_locale_converter.js
toolkit/components/extensions/webrequest/ChannelWrapper.cpp
toolkit/components/extensions/webrequest/StreamFilterParent.cpp
toolkit/components/mediasniffer/test/unit/test_mediasniffer.js
toolkit/components/mediasniffer/test/unit/test_mediasniffer_ext.js
toolkit/components/passwordmgr/test/browser/browser_hasInsecureLoginForms_streamConverter.js
toolkit/components/passwordmgr/test/mochitest/test_prompt_promptAuth_proxy.html
toolkit/components/places/FaviconHelpers.cpp
toolkit/components/places/PageIconProtocolHandler.jsm
toolkit/components/places/nsAnnoProtocolHandler.cpp
toolkit/components/places/tests/favicons/test_moz-anno_favicon_mime_type.js
toolkit/components/reputationservice/ApplicationReputation.cpp
toolkit/components/search/SearchService.jsm
toolkit/components/telemetry/app/TelemetrySend.jsm
toolkit/components/telemetry/tests/unit/head.js
toolkit/components/url-classifier/UrlClassifierHashCompleter.jsm
toolkit/components/url-classifier/nsUrlClassifierDBService.cpp
toolkit/components/url-classifier/nsUrlClassifierStreamUpdater.cpp
toolkit/components/utils/SimpleServices.jsm
toolkit/content/contentAreaUtils.js
toolkit/modules/secondscreen/RokuApp.jsm
toolkit/mozapps/extensions/internal/XPIInstall.jsm
toolkit/mozapps/update/UpdateService.jsm
toolkit/mozapps/update/content/updates.js
toolkit/mozapps/update/tests/chrome/test_0085_error_patchApplyFailure_partial_complete_staging.xul
toolkit/mozapps/update/tests/data/xpcshellUtilsAUS.js
uriloader/base/nsDocLoader.cpp
uriloader/base/nsURILoader.cpp
uriloader/exthandler/ExternalHelperAppChild.cpp
uriloader/exthandler/ExternalHelperAppParent.cpp
uriloader/exthandler/nsExternalHelperAppService.cpp
uriloader/exthandler/nsExternalProtocolHandler.cpp
uriloader/prefetch/nsOfflineCacheUpdate.cpp
uriloader/prefetch/nsPrefetchService.cpp
widget/android/WebExecutorSupport.cpp
widget/windows/nsDataObj.cpp
--- a/browser/base/content/aboutDialog-appUpdater.js
+++ b/browser/base/content/aboutDialog-appUpdater.js
@@ -320,23 +320,23 @@ appUpdater.prototype =
     if (this.aus) {
       this.aus.removeDownloadListener(this);
     }
   },
 
   /**
    * See nsIRequestObserver.idl
    */
-  onStartRequest(aRequest) {
+  onStartRequest(aRequest, aContext) {
   },
 
   /**
    * See nsIRequestObserver.idl
    */
-  onStopRequest(aRequest, aStatusCode) {
+  onStopRequest(aRequest, aContext, aStatusCode) {
     switch (aStatusCode) {
     case Cr.NS_ERROR_UNEXPECTED:
       if (this.update.selectedPatch.state == "download-failed" &&
           (this.update.isCompleteUpdate || this.update.patchCount != 2)) {
         // Verification error of complete patch, informational text is held in
         // the update object.
         this.removeDownloadListener();
         this.selectPanel("downloadFailed");
--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -1097,17 +1097,17 @@ nsContextMenu.prototype = {
     // an object to proxy the data through to
     // nsIExternalHelperAppService.doContent, which will wait for the
     // appropriate MIME-type headers and then prompt the user with a
     // file picker
     function saveAsListener() {}
     saveAsListener.prototype = {
       extListener: null,
 
-      onStartRequest: function saveLinkAs_onStartRequest(aRequest) {
+      onStartRequest: function saveLinkAs_onStartRequest(aRequest, aContext) {
         // if the timer fired, the error status will have been caused by that,
         // and we'll be restarting in onStopRequest, so no reason to notify
         // the user
         if (aRequest.status == NS_ERROR_SAVE_LINK_AS_TIMEOUT)
           return;
 
         timer.cancel();
 
@@ -1128,35 +1128,35 @@ nsContextMenu.prototype = {
 
         let extHelperAppSvc =
           Cc["@mozilla.org/uriloader/external-helper-app-service;1"].
           getService(Ci.nsIExternalHelperAppService);
         let channel = aRequest.QueryInterface(Ci.nsIChannel);
         this.extListener =
           extHelperAppSvc.doContent(channel.contentType, aRequest,
                                     null, true, window);
-        this.extListener.onStartRequest(aRequest);
+        this.extListener.onStartRequest(aRequest, aContext);
       },
 
-      onStopRequest: function saveLinkAs_onStopRequest(aRequest,
+      onStopRequest: function saveLinkAs_onStopRequest(aRequest, aContext,
                                                        aStatusCode) {
         if (aStatusCode == NS_ERROR_SAVE_LINK_AS_TIMEOUT) {
           // do it the old fashioned way, which will pick the best filename
           // it can without waiting.
           saveURL(linkURL, linkText, dialogTitle, bypassCache, false, docURI,
                   doc, isContentWindowPrivate);
         }
         if (this.extListener)
-          this.extListener.onStopRequest(aRequest, aStatusCode);
+          this.extListener.onStopRequest(aRequest, aContext, aStatusCode);
       },
 
-      onDataAvailable: function saveLinkAs_onDataAvailable(aRequest,
+      onDataAvailable: function saveLinkAs_onDataAvailable(aRequest, aContext,
                                                            aInputStream,
                                                            aOffset, aCount) {
-        this.extListener.onDataAvailable(aRequest, aInputStream,
+        this.extListener.onDataAvailable(aRequest, aContext, aInputStream,
                                          aOffset, aCount);
       },
     };
 
     function callbacks() {}
     callbacks.prototype = {
       getInterface: function sLA_callbacks_getInterface(aIID) {
         if (aIID.equals(Ci.nsIAuthPrompt) || aIID.equals(Ci.nsIAuthPrompt2)) {
--- a/browser/extensions/pdfjs/content/PdfStreamConverter.jsm
+++ b/browser/extensions/pdfjs/content/PdfStreamConverter.jsm
@@ -272,36 +272,36 @@ class ChromeActions {
       channel.contentStream = aInputStream;
       if ("nsIPrivateBrowsingChannel" in Ci &&
           channel instanceof Ci.nsIPrivateBrowsingChannel) {
         channel.setPrivate(docIsPrivate);
       }
 
       var listener = {
         extListener: null,
-        onStartRequest(aRequest) {
+        onStartRequest(aRequest, aContext) {
           var loadContext = self.domWindow.docShell
                                 .QueryInterface(Ci.nsILoadContext);
           this.extListener = extHelperAppSvc.doContent(
             (data.isAttachment ? "application/octet-stream" :
                                  "application/pdf"),
             aRequest, loadContext, false);
-          this.extListener.onStartRequest(aRequest);
+          this.extListener.onStartRequest(aRequest, aContext);
         },
-        onStopRequest(aRequest, aStatusCode) {
+        onStopRequest(aRequest, aContext, aStatusCode) {
           if (this.extListener) {
-            this.extListener.onStopRequest(aRequest, aStatusCode);
+            this.extListener.onStopRequest(aRequest, aContext, aStatusCode);
           }
           // Notify the content code we're done downloading.
           if (sendResponse) {
             sendResponse(false);
           }
         },
-        onDataAvailable(aRequest, aDataInputStream, aOffset, aCount) {
-          this.extListener.onDataAvailable(aRequest, aDataInputStream,
+        onDataAvailable(aRequest, aContext, aDataInputStream, aOffset, aCount) {
+          this.extListener.onDataAvailable(aRequest, aContext, aDataInputStream,
                                            aOffset, aCount);
         },
       };
 
       channel.asyncOpen(listener);
     });
   }
 
@@ -842,30 +842,30 @@ PdfStreamConverter.prototype = {
 
   // nsIStreamConverter::asyncConvertData
   asyncConvertData(aFromType, aToType, aListener, aCtxt) {
     // Store the listener passed to us
     this.listener = aListener;
   },
 
   // nsIStreamListener::onDataAvailable
-  onDataAvailable(aRequest, aInputStream, aOffset, aCount) {
+  onDataAvailable(aRequest, aContext, aInputStream, aOffset, aCount) {
     if (!this.dataListener) {
       return;
     }
 
     var binaryStream = this.binaryStream;
     binaryStream.setInputStream(aInputStream);
     let chunk = new ArrayBuffer(aCount);
     binaryStream.readArrayBuffer(aCount, chunk);
     this.dataListener.append(new Uint8Array(chunk));
   },
 
   // nsIRequestObserver::onStartRequest
-  onStartRequest(aRequest) {
+  onStartRequest(aRequest, aContext) {
     // Setup the request so we can use it below.
     var isHttpRequest = false;
     try {
       aRequest.QueryInterface(Ci.nsIHttpChannel);
       isHttpRequest = true;
     } catch (e) {}
 
     var rangeRequest = false;
@@ -934,29 +934,29 @@ PdfStreamConverter.prototype = {
 
     var listener = this.listener;
     var dataListener = this.dataListener;
     // Proxy all the request observer calls, when it gets to onStopRequest
     // we can get the dom window.  We also intentionally pass on the original
     // request(aRequest) below so we don't overwrite the original channel and
     // trigger an assertion.
     var proxy = {
-      onStartRequest(request) {
-        listener.onStartRequest(aRequest);
+      onStartRequest(request, context) {
+        listener.onStartRequest(aRequest, aContext);
       },
-      onDataAvailable(request, inputStream, offset, count) {
-        listener.onDataAvailable(aRequest, inputStream,
+      onDataAvailable(request, context, inputStream, offset, count) {
+        listener.onDataAvailable(aRequest, aContext, inputStream,
                                  offset, count);
       },
-      onStopRequest(request, statusCode) {
+      onStopRequest(request, context, statusCode) {
         var domWindow = getDOMWindow(channel, resourcePrincipal);
         if (!Components.isSuccessCode(statusCode) || !domWindow) {
           // The request may have been aborted and the document may have been
           // replaced with something that is not PDF.js, abort attaching.
-          listener.onStopRequest(aRequest, statusCode);
+          listener.onStopRequest(aRequest, context, statusCode);
           return;
         }
         var actions;
         if (rangeRequest || streamRequest) {
           actions = new RangedChromeActions(
             domWindow, contentDispositionFilename, aRequest,
             rangeRequest, streamRequest, dataListener);
         } else {
@@ -966,17 +966,17 @@ PdfStreamConverter.prototype = {
         var requestListener = new RequestListener(actions);
         domWindow.document.addEventListener(PDFJS_EVENT_ID, function(event) {
           requestListener.receive(event);
         }, false, true);
         if (actions.supportsIntegratedFind()) {
           var findEventManager = new FindEventManager(domWindow);
           findEventManager.bind();
         }
-        listener.onStopRequest(aRequest, statusCode);
+        listener.onStopRequest(aRequest, aContext, statusCode);
 
         if (domWindow.frameElement) {
           var isObjectEmbed = domWindow.frameElement.tagName !== "IFRAME" ||
             domWindow.frameElement.className === "previewPluginContentFrame";
           PdfJsTelemetry.onEmbed(isObjectEmbed);
         }
       },
     };
@@ -994,17 +994,17 @@ PdfStreamConverter.prototype = {
       Services.scriptSecurityManager.createCodebasePrincipal(uri,
         aRequest.loadInfo.originAttributes);
     aRequest.owner = resourcePrincipal;
 
     channel.asyncOpen(proxy);
   },
 
   // nsIRequestObserver::onStopRequest
-  onStopRequest(aRequest, aStatusCode) {
+  onStopRequest(aRequest, aContext, aStatusCode) {
     if (!this.dataListener) {
       // Do nothing
       return;
     }
 
     if (Components.isSuccessCode(aStatusCode)) {
       this.dataListener.finish();
     } else {
--- a/browser/modules/FaviconLoader.jsm
+++ b/browser/modules/FaviconLoader.jsm
@@ -155,32 +155,32 @@ class FaviconLoad {
   cancel() {
     if (!this.channel) {
       return;
     }
 
     this.channel.cancel(Cr.NS_BINDING_ABORTED);
   }
 
-  onStartRequest(request) {
+  onStartRequest(request, context) {
   }
 
-  onDataAvailable(request, inputStream, offset, count) {
+  onDataAvailable(request, context, inputStream, offset, count) {
     this.stream.writeFrom(inputStream, count);
   }
 
   asyncOnChannelRedirect(oldChannel, newChannel, flags, callback) {
     if (oldChannel == this.channel) {
       this.channel = newChannel;
     }
 
     callback.onRedirectVerifyCallback(Cr.NS_OK);
   }
 
-  async onStopRequest(request, statusCode) {
+  async onStopRequest(request, context, statusCode) {
     if (request != this.channel) {
       // Indicates that a redirect has occurred. We don't care about the result
       // of the original channel.
       return;
     }
 
     this.stream.close();
     this.stream = null;
--- a/devtools/client/jsonview/converter-child.js
+++ b/devtools/client/jsonview/converter-child.js
@@ -63,24 +63,24 @@ Converter.prototype = {
   convert: function(fromStream, fromType, toType, ctx) {
     return fromStream;
   },
 
   asyncConvertData: function(fromType, toType, listener, ctx) {
     this.listener = listener;
   },
 
-  onDataAvailable: function(request, inputStream, offset, count) {
+  onDataAvailable: function(request, context, inputStream, offset, count) {
     // Decode and insert data.
     const buffer = new ArrayBuffer(count);
     new BinaryInput(inputStream).readArrayBuffer(count, buffer);
     this.decodeAndInsertBuffer(buffer);
   },
 
-  onStartRequest: function(request) {
+  onStartRequest: function(request, context) {
     // Set the content type to HTML in order to parse the doctype, styles
     // and scripts. The JSON will be manually inserted as text.
     request.QueryInterface(Ci.nsIChannel);
     request.contentType = "text/html";
 
     const headers = getHttpHeaders(request);
 
     // Enforce strict CSP:
@@ -100,37 +100,37 @@ Converter.prototype = {
     fixSave(request);
 
     // Because content might still have a reference to this window,
     // force setting it to a null principal to avoid it being same-
     // origin with (other) content.
     request.loadInfo.resetPrincipalToInheritToNullPrincipal();
 
     // Start the request.
-    this.listener.onStartRequest(request);
+    this.listener.onStartRequest(request, context);
 
     // Initialize stuff.
     const win = NetworkHelper.getWindowForRequest(request);
     this.data = exportData(win, headers);
     insertJsonData(win, this.data.json);
     win.addEventListener("contentMessage", onContentMessage, false, true);
     keepThemeUpdated(win);
 
     // Send the initial HTML code.
     const buffer = new TextEncoder().encode(initialHTML(win.document)).buffer;
     const stream = new BufferStream(buffer, 0, buffer.byteLength);
-    this.listener.onDataAvailable(request, stream, 0, stream.available());
+    this.listener.onDataAvailable(request, context, stream, 0, stream.available());
   },
 
-  onStopRequest: function(request, statusCode) {
+  onStopRequest: function(request, context, statusCode) {
     // Flush data.
     this.decodeAndInsertBuffer(new ArrayBuffer(0), true);
 
     // Stop the request.
-    this.listener.onStopRequest(request, statusCode);
+    this.listener.onStopRequest(request, context, statusCode);
     this.listener = null;
     this.decoder = null;
     this.data = null;
   },
 
   // Decodes an ArrayBuffer into a string and inserts it into the page.
   decodeAndInsertBuffer: function(buffer, flush = false) {
     // Decode the buffer into a string.
--- a/devtools/client/netmonitor/test/sjs_content-type-test-server.sjs
+++ b/devtools/client/netmonitor/test/sjs_content-type-test-server.sjs
@@ -10,19 +10,19 @@ function gzipCompressString(string, obs)
   let listener = Cc["@mozilla.org/network/stream-loader;1"]
                 .createInstance(Ci.nsIStreamLoader);
   listener.init(obs);
   let converter = scs.asyncConvertData("uncompressed", "gzip",
                                         listener, null);
   let stringStream = Cc["@mozilla.org/io/string-input-stream;1"]
                     .createInstance(Ci.nsIStringInputStream);
   stringStream.data = string;
-  converter.onStartRequest(null);
-  converter.onDataAvailable(null, stringStream, 0, string.length);
-  converter.onStopRequest(null, null);
+  converter.onStartRequest(null, null);
+  converter.onDataAvailable(null, null, stringStream, 0, string.length);
+  converter.onStopRequest(null, null, null);
 }
 
 function doubleGzipCompressString(string, observer) {
   let observer2 = {
     onStreamComplete: function(loader, context, status, length, result) {
       let buffer = String.fromCharCode.apply(this, result);
       gzipCompressString(buffer, observer);
     }
--- a/devtools/server/actors/network-monitor/network-response-listener.js
+++ b/devtools/server/actors/network-monitor/network-response-listener.js
@@ -168,17 +168,17 @@ NetworkResponseListener.prototype = {
    * https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIStreamListener
    *
    * @param nsIRequest request
    * @param nsISupports context
    * @param nsIInputStream inputStream
    * @param unsigned long offset
    * @param unsigned long count
    */
-  onDataAvailable: function(request, inputStream, offset, count) {
+  onDataAvailable: function(request, context, inputStream, offset, count) {
     this._findOpenResponse();
     const data = NetUtil.readInputStreamToString(inputStream, count);
 
     this.bodySize += count;
 
     if (!this.httpActivity.discardResponseBody) {
       const limit = Services.prefs.getIntPref("devtools.netmonitor.responseBodyLimit");
       if (this.receivedData.length <= limit || limit == 0) {
@@ -485,20 +485,20 @@ NetworkResponseListener.prototype = {
       available = stream.available();
     } catch (ex) {
       // Ignore.
     }
 
     if (available != -1) {
       if (available != 0) {
         if (this.converter) {
-          this.converter.onDataAvailable(this.request, stream,
+          this.converter.onDataAvailable(this.request, null, stream,
                                          this.offset, available);
         } else {
-          this.onDataAvailable(this.request, stream, this.offset,
+          this.onDataAvailable(this.request, null, stream, this.offset,
                                available);
         }
       }
       this.offset += available;
       this.setAsyncListener(stream, this);
     } else {
       this.onStreamClose();
       this.offset = 0;
--- a/devtools/shared/webconsole/test/unit/test_throttle.js
+++ b/devtools/shared/webconsole/test/unit/test_throttle.js
@@ -18,17 +18,17 @@ TestStreamListener.prototype = {
   onStartRequest: function() {
     this.setState("start");
   },
 
   onStopRequest: function() {
     this.setState("stop");
   },
 
-  onDataAvailable: function(request, inputStream, offset, count) {
+  onDataAvailable: function(request, context, inputStream, offset, count) {
     const sin = Cc["@mozilla.org/scriptableinputstream;1"]
           .createInstance(nsIScriptableInputStream);
     sin.init(inputStream);
     this.data = sin.read(count);
     this.setState("data");
   },
 
   setState: function(state) {
@@ -93,17 +93,17 @@ add_task(async function() {
 
   const listener = throttler.manage(downloadChannel);
   equal(downloadChannel.state, "listener",
      "NetworkThrottleManager called setNewListener");
 
   equal(testListener.state, "initial", "test listener in initial state");
 
   // This method must be passed through immediately.
-  listener.onStartRequest(null);
+  listener.onStartRequest(null, null);
   equal(testListener.state, "start", "test listener started");
 
   const TEST_INPUT = "hi bob";
 
   const testStream = Cc["@mozilla.org/storagestream;1"]
       .createInstance(Ci.nsIStorageStream);
   testStream.init(512, 512);
   const out = testStream.getOutputStream(0);
@@ -120,24 +120,24 @@ add_task(async function() {
       activitySeen = true;
     },
     null, null, null,
     activityDistributor.ACTIVITY_SUBTYPE_RESPONSE_COMPLETE,
     null, TEST_INPUT.length, null
   );
 
   // onDataAvailable is required to immediately read the data.
-  listener.onDataAvailable(null, testInputStream, 0, 6);
+  listener.onDataAvailable(null, null, testInputStream, 0, 6);
   equal(testInputStream.available(), 0, "no more data should be available");
   equal(testListener.state, "start",
      "test listener should not have received data");
   equal(activitySeen, false, "activity not distributed yet");
 
   let newState = await testListener.onStateChanged();
   equal(newState, "data", "test listener received data");
   equal(testListener.data, TEST_INPUT, "test listener received all the data");
   equal(activitySeen, true, "activity has been distributed");
 
   const onChange = testListener.onStateChanged();
-  listener.onStopRequest(null, null);
+  listener.onStopRequest(null, null, null);
   newState = await onChange;
   equal(newState, "stop", "onStateChanged reported");
 });
--- a/devtools/shared/webconsole/throttle.js
+++ b/devtools/shared/webconsole/throttle.js
@@ -54,45 +54,45 @@ NetworkThrottleListener.prototype = {
    */
   setOriginalListener: function(originalListener) {
     this.originalListener = originalListener;
   },
 
   /**
    * @see nsIStreamListener.onStartRequest.
    */
-  onStartRequest: function(request) {
-    this.originalListener.onStartRequest(request);
+  onStartRequest: function(request, context) {
+    this.originalListener.onStartRequest(request, context);
     this.queue.start(this);
   },
 
   /**
    * @see nsIStreamListener.onStopRequest.
    */
-  onStopRequest: function(request, statusCode) {
-    this.pendingData.push({request, statusCode});
+  onStopRequest: function(request, context, statusCode) {
+    this.pendingData.push({request, context, statusCode});
     this.queue.dataAvailable(this);
   },
 
   /**
    * @see nsIStreamListener.onDataAvailable.
    */
-  onDataAvailable: function(request, inputStream, offset, count) {
+  onDataAvailable: function(request, context, inputStream, offset, count) {
     if (this.pendingException) {
       throw this.pendingException;
     }
 
     const bin = new BinaryInputStream(inputStream);
     const bytes = new ArrayBuffer(count);
     bin.readArrayBuffer(count, bytes);
 
     const stream = new ArrayBufferInputStream();
     stream.setData(bytes, 0, count);
 
-    this.pendingData.push({request, stream, count});
+    this.pendingData.push({request, context, stream, count});
     this.queue.dataAvailable(this);
   },
 
   /**
    * Allow some buffered data from this object to be forwarded to this
    * object's originalListener.
    *
    * @param {Number} bytesPermitted The maximum number of bytes
@@ -105,30 +105,30 @@ NetworkThrottleListener.prototype = {
    *         all available data has been sent.)
    */
   sendSomeData: function(bytesPermitted) {
     if (this.pendingData.length === 0) {
       // Shouldn't happen.
       return {length: 0, done: true};
     }
 
-    const {request, stream, count, statusCode} = this.pendingData[0];
+    const {request, context, stream, count, statusCode} = this.pendingData[0];
 
     if (statusCode !== undefined) {
       this.pendingData.shift();
-      this.originalListener.onStopRequest(request, statusCode);
+      this.originalListener.onStopRequest(request, context, statusCode);
       return {length: 0, done: true};
     }
 
     if (bytesPermitted > count) {
       bytesPermitted = count;
     }
 
     try {
-      this.originalListener.onDataAvailable(request, stream,
+      this.originalListener.onDataAvailable(request, context, stream,
                                             this.offset, bytesPermitted);
     } catch (e) {
       this.pendingException = e;
     }
 
     let done = false;
     if (bytesPermitted === count) {
       this.pendingData.shift();
--- a/docshell/base/nsPingListener.cpp
+++ b/docshell/base/nsPingListener.cpp
@@ -323,30 +323,30 @@ nsresult nsPingListener::StartTimeout(Do
 
   return NS_NewTimerWithFuncCallback(
       getter_AddRefs(mTimer), OnPingTimeout, mLoadGroup, PING_TIMEOUT,
       nsITimer::TYPE_ONE_SHOT, "nsPingListener::StartTimeout",
       aDocGroup->EventTargetFor(TaskCategory::Network));
 }
 
 NS_IMETHODIMP
-nsPingListener::OnStartRequest(nsIRequest* aRequest) {
+nsPingListener::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext) {
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsPingListener::OnDataAvailable(nsIRequest* aRequest,
+nsPingListener::OnDataAvailable(nsIRequest* aRequest, nsISupports* aContext,
                                 nsIInputStream* aStream, uint64_t aOffset,
                                 uint32_t aCount) {
   uint32_t result;
   return aStream->ReadSegments(NS_DiscardSegment, nullptr, aCount, &result);
 }
 
 NS_IMETHODIMP
-nsPingListener::OnStopRequest(nsIRequest* aRequest,
+nsPingListener::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
                               nsresult aStatus) {
   mLoadGroup = nullptr;
 
   if (mTimer) {
     mTimer->Cancel();
     mTimer = nullptr;
   }
 
--- a/dom/base/DOMParser.cpp
+++ b/dom/base/DOMParser.cpp
@@ -192,28 +192,28 @@ already_AddRefed<Document> DOMParser::Pa
   if (NS_FAILED(rv) || !listener) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   // Now start pumping data to the listener
   nsresult status;
 
-  rv = listener->OnStartRequest(parserChannel);
+  rv = listener->OnStartRequest(parserChannel, nullptr);
   if (NS_FAILED(rv)) parserChannel->Cancel(rv);
   parserChannel->GetStatus(&status);
 
   if (NS_SUCCEEDED(rv) && NS_SUCCEEDED(status)) {
-    rv = listener->OnDataAvailable(parserChannel, stream, 0,
+    rv = listener->OnDataAvailable(parserChannel, nullptr, stream, 0,
                                    aContentLength);
     if (NS_FAILED(rv)) parserChannel->Cancel(rv);
     parserChannel->GetStatus(&status);
   }
 
-  rv = listener->OnStopRequest(parserChannel, status);
+  rv = listener->OnStopRequest(parserChannel, nullptr, status);
   // Failure returned from OnStopRequest does not affect the final status of
   // the channel, so we do not need to call Cancel(rv) as we do above.
 
   if (NS_FAILED(rv)) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
--- a/dom/base/Document.cpp
+++ b/dom/base/Document.cpp
@@ -871,17 +871,18 @@ nsresult ExternalResourceMap::AddExterna
 
   return rv;
 }
 
 NS_IMPL_ISUPPORTS(ExternalResourceMap::PendingLoad, nsIStreamListener,
                   nsIRequestObserver)
 
 NS_IMETHODIMP
-ExternalResourceMap::PendingLoad::OnStartRequest(nsIRequest* aRequest) {
+ExternalResourceMap::PendingLoad::OnStartRequest(nsIRequest* aRequest,
+                                                 nsISupports* aContext) {
   ExternalResourceMap& map = mDisplayDocument->ExternalResourceMap();
   if (map.HaveShutDown()) {
     return NS_BINDING_ABORTED;
   }
 
   nsCOMPtr<nsIContentViewer> viewer;
   nsCOMPtr<nsILoadGroup> loadGroup;
   nsresult rv =
@@ -893,17 +894,17 @@ ExternalResourceMap::PendingLoad::OnStar
   if (NS_FAILED(rv)) {
     return rv;
   }
   if (NS_FAILED(rv2)) {
     mTargetListener = nullptr;
     return rv2;
   }
 
-  return mTargetListener->OnStartRequest(aRequest);
+  return mTargetListener->OnStartRequest(aRequest, aContext);
 }
 
 nsresult ExternalResourceMap::PendingLoad::SetupViewer(
     nsIRequest* aRequest, nsIContentViewer** aViewer,
     nsILoadGroup** aLoadGroup) {
   MOZ_ASSERT(!mTargetListener, "Unexpected call to OnStartRequest");
   *aViewer = nullptr;
   *aLoadGroup = nullptr;
@@ -976,36 +977,38 @@ nsresult ExternalResourceMap::PendingLoa
   listener.swap(mTargetListener);
   viewer.forget(aViewer);
   newLoadGroup.forget(aLoadGroup);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 ExternalResourceMap::PendingLoad::OnDataAvailable(nsIRequest* aRequest,
+                                                  nsISupports* aContext,
                                                   nsIInputStream* aStream,
                                                   uint64_t aOffset,
                                                   uint32_t aCount) {
   // mTargetListener might be null if SetupViewer or AddExternalResource failed.
   NS_ENSURE_TRUE(mTargetListener, NS_ERROR_FAILURE);
   if (mDisplayDocument->ExternalResourceMap().HaveShutDown()) {
     return NS_BINDING_ABORTED;
   }
-  return mTargetListener->OnDataAvailable(aRequest, aStream, aOffset,
+  return mTargetListener->OnDataAvailable(aRequest, aContext, aStream, aOffset,
                                           aCount);
 }
 
 NS_IMETHODIMP
 ExternalResourceMap::PendingLoad::OnStopRequest(nsIRequest* aRequest,
+                                                nsISupports* aContext,
                                                 nsresult aStatus) {
   // mTargetListener might be null if SetupViewer or AddExternalResource failed
   if (mTargetListener) {
     nsCOMPtr<nsIStreamListener> listener;
     mTargetListener.swap(listener);
-    return listener->OnStopRequest(aRequest, aStatus);
+    return listener->OnStopRequest(aRequest, aContext, aStatus);
   }
 
   return NS_OK;
 }
 
 nsresult ExternalResourceMap::PendingLoad::StartLoad(nsIURI* aURI,
                                                      nsIURI* aReferrer,
                                                      uint32_t aReferrerPolicy,
--- a/dom/base/EventSource.cpp
+++ b/dom/base/EventSource.cpp
@@ -596,17 +596,17 @@ EventSourceImpl::Observe(nsISupports* aS
   return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 // EventSourceImpl::nsIStreamListener
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
-EventSourceImpl::OnStartRequest(nsIRequest* aRequest) {
+EventSourceImpl::OnStartRequest(nsIRequest* aRequest, nsISupports* aCtxt) {
   AssertIsOnMainThread();
   if (IsClosed()) {
     return NS_ERROR_ABORT;
   }
   nsresult rv = CheckHealthOfRequestCallback(aRequest);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aRequest, &rv);
@@ -702,17 +702,17 @@ void EventSourceImpl::ParseSegment(const
     if (result == kInputEmpty) {
       return;
     }
     src = src.From(read);
   }
 }
 
 NS_IMETHODIMP
-EventSourceImpl::OnDataAvailable(nsIRequest* aRequest,
+EventSourceImpl::OnDataAvailable(nsIRequest* aRequest, nsISupports* aContext,
                                  nsIInputStream* aInputStream, uint64_t aOffset,
                                  uint32_t aCount) {
   AssertIsOnTargetThread();
   NS_ENSURE_ARG_POINTER(aInputStream);
   if (IsClosed()) {
     return NS_ERROR_ABORT;
   }
 
@@ -720,17 +720,17 @@ EventSourceImpl::OnDataAvailable(nsIRequ
   NS_ENSURE_SUCCESS(rv, rv);
 
   uint32_t totalRead;
   return aInputStream->ReadSegments(EventSourceImpl::StreamReaderFunc, this,
                                     aCount, &totalRead);
 }
 
 NS_IMETHODIMP
-EventSourceImpl::OnStopRequest(nsIRequest* aRequest,
+EventSourceImpl::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
                                nsresult aStatusCode) {
   AssertIsOnMainThread();
 
   if (IsClosed()) {
     return NS_ERROR_ABORT;
   }
   MOZ_ASSERT(mSrc);
   // "Network errors that prevents the connection from being established in the
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -1035,32 +1035,33 @@ class BeaconStreamListener final : publi
 
  private:
   nsCOMPtr<nsILoadGroup> mLoadGroup;
 };
 
 NS_IMPL_ISUPPORTS(BeaconStreamListener, nsIStreamListener, nsIRequestObserver)
 
 NS_IMETHODIMP
-BeaconStreamListener::OnStartRequest(nsIRequest* aRequest) {
+BeaconStreamListener::OnStartRequest(nsIRequest* aRequest,
+                                     nsISupports* aContext) {
   // release the loadgroup first
   mLoadGroup = nullptr;
 
   aRequest->Cancel(NS_ERROR_NET_INTERRUPT);
   return NS_BINDING_ABORTED;
 }
 
 NS_IMETHODIMP
-BeaconStreamListener::OnStopRequest(nsIRequest* aRequest,
+BeaconStreamListener::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
                                     nsresult aStatus) {
   return NS_OK;
 }
 
 NS_IMETHODIMP
-BeaconStreamListener::OnDataAvailable(nsIRequest* aRequest,
+BeaconStreamListener::OnDataAvailable(nsIRequest* aRequest, nsISupports* ctxt,
                                       nsIInputStream* inStr,
                                       uint64_t sourceOffset, uint32_t count) {
   MOZ_ASSERT(false);
   return NS_OK;
 }
 
 bool Navigator::SendBeacon(const nsAString& aUrl,
                            const Nullable<fetch::BodyInit>& aData,
--- a/dom/base/nsObjectLoadingContent.cpp
+++ b/dom/base/nsObjectLoadingContent.cpp
@@ -925,17 +925,18 @@ void nsObjectLoadingContent::NotifyOwner
   // moved into an active document before returning to the event loop.
   if (mInstanceOwner || mInstantiating) {
     QueueCheckPluginStopEvent();
   }
 }
 
 // nsIRequestObserver
 NS_IMETHODIMP
-nsObjectLoadingContent::OnStartRequest(nsIRequest* aRequest) {
+nsObjectLoadingContent::OnStartRequest(nsIRequest* aRequest,
+                                       nsISupports* aContext) {
   AUTO_PROFILER_LABEL("nsObjectLoadingContent::OnStartRequest", NETWORK);
 
   LOG(("OBJLC [%p]: Channel OnStartRequest", this));
 
   if (aRequest != mChannel || !aRequest) {
     // happens when a new load starts before the previous one got here
     return NS_BINDING_ABORTED;
   }
@@ -946,17 +947,17 @@ nsObjectLoadingContent::OnStartRequest(n
     if (!mInstanceOwner) {
       // We drop mChannel when stopping plugins, so something is wrong
       MOZ_ASSERT_UNREACHABLE(
           "Opened a channel in plugin mode, but don't have "
           "a plugin");
       return NS_BINDING_ABORTED;
     }
     if (MakePluginListener()) {
-      return mFinalListener->OnStartRequest(aRequest);
+      return mFinalListener->OnStartRequest(aRequest, nullptr);
     }
     MOZ_ASSERT_UNREACHABLE(
         "Failed to create PluginStreamListener, aborting "
         "channel");
     return NS_BINDING_ABORTED;
   }
 
   // Otherwise we should be state loading, and call LoadObject with the channel
@@ -1007,16 +1008,17 @@ nsObjectLoadingContent::OnStartRequest(n
     return NS_ERROR_FAILURE;
   }
 
   return LoadObject(true, false, aRequest);
 }
 
 NS_IMETHODIMP
 nsObjectLoadingContent::OnStopRequest(nsIRequest* aRequest,
+                                      nsISupports* aContext,
                                       nsresult aStatusCode) {
   AUTO_PROFILER_LABEL("nsObjectLoadingContent::OnStopRequest", NETWORK);
 
   // Handle object not loading error because source was a tracking URL (or
   // fingerprinting, cryptomining, etc.).
   // We make a note of this object node by including it in a dedicated
   // array of blocked tracking nodes under its parent document.
   if (UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aStatusCode)) {
@@ -1032,36 +1034,37 @@ nsObjectLoadingContent::OnStopRequest(ns
   }
 
   mChannel = nullptr;
 
   if (mFinalListener) {
     // This may re-enter in the case of plugin listeners
     nsCOMPtr<nsIStreamListener> listenerGrip(mFinalListener);
     mFinalListener = nullptr;
-    listenerGrip->OnStopRequest(aRequest, aStatusCode);
+    listenerGrip->OnStopRequest(aRequest, aContext, aStatusCode);
   }
 
   // Return value doesn't matter
   return NS_OK;
 }
 
 // nsIStreamListener
 NS_IMETHODIMP
 nsObjectLoadingContent::OnDataAvailable(nsIRequest* aRequest,
+                                        nsISupports* aContext,
                                         nsIInputStream* aInputStream,
                                         uint64_t aOffset, uint32_t aCount) {
   if (aRequest != mChannel) {
     return NS_BINDING_ABORTED;
   }
 
   if (mFinalListener) {
     // This may re-enter in the case of plugin listeners
     nsCOMPtr<nsIStreamListener> listenerGrip(mFinalListener);
-    return listenerGrip->OnDataAvailable(aRequest, aInputStream,
+    return listenerGrip->OnDataAvailable(aRequest, aContext, aInputStream,
                                          aOffset, aCount);
   }
 
   // We shouldn't have a connected channel with no final listener
   MOZ_ASSERT_UNREACHABLE(
       "Got data for channel with no connected final "
       "listener");
   mChannel = nullptr;
@@ -2211,30 +2214,30 @@ nsresult nsObjectLoadingContent::LoadObj
   rv = NS_OK;
   if (doSpawnPlugin) {
     rv = InstantiatePluginInstance(true);
     NS_ENSURE_TRUE(mIsLoading, NS_OK);
     // Create the final listener if we're loading with a channel. We can't do
     // this in the loading block above as it requires an instance.
     if (aLoadingChannel && NS_SUCCEEDED(rv)) {
       if (NS_SUCCEEDED(rv) && MakePluginListener()) {
-        rv = mFinalListener->OnStartRequest(mChannel);
+        rv = mFinalListener->OnStartRequest(mChannel, nullptr);
         if (NS_FAILED(rv)) {
           // Plugins can reject their initial stream, but continue to run.
           CloseChannel();
           NS_ENSURE_TRUE(mIsLoading, NS_OK);
           rv = NS_OK;
         }
       }
     }
   } else if (finalListener) {
     NS_ASSERTION(mType != eType_Null && mType != eType_Loading,
                  "We should not have a final listener with a non-loaded type");
     mFinalListener = finalListener;
-    rv = finalListener->OnStartRequest(mChannel);
+    rv = finalListener->OnStartRequest(mChannel, nullptr);
   }
 
   if (NS_FAILED(rv) && mIsLoading) {
     // Since we've already notified of our transition, we can just Unload and
     // call LoadFallback (which will notify again)
     mType = eType_Null;
     UnloadObject(false);
     NS_ENSURE_TRUE(mIsLoading, NS_OK);
@@ -2254,17 +2257,17 @@ nsresult nsObjectLoadingContent::CloseCh
     nsCOMPtr<nsIChannel> channelGrip(mChannel);
     nsCOMPtr<nsIStreamListener> listenerGrip(mFinalListener);
     mChannel = nullptr;
     mFinalListener = nullptr;
     channelGrip->Cancel(NS_BINDING_ABORTED);
     if (listenerGrip) {
       // mFinalListener is only set by LoadObject after OnStartRequest, or
       // by OnStartRequest in the case of late-opened plugin streams
-      listenerGrip->OnStopRequest(channelGrip, NS_BINDING_ABORTED);
+      listenerGrip->OnStopRequest(channelGrip, nullptr, NS_BINDING_ABORTED);
     }
   }
   return NS_OK;
 }
 
 nsresult nsObjectLoadingContent::OpenChannel() {
   nsCOMPtr<nsIContent> thisContent =
       do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
--- a/dom/base/nsSyncLoadService.cpp
+++ b/dom/base/nsSyncLoadService.cpp
@@ -84,31 +84,32 @@ class nsForceXMLListener : public nsIStr
 nsForceXMLListener::nsForceXMLListener(nsIStreamListener *aListener)
     : mListener(aListener) {}
 
 nsForceXMLListener::~nsForceXMLListener() {}
 
 NS_IMPL_ISUPPORTS(nsForceXMLListener, nsIStreamListener, nsIRequestObserver)
 
 NS_IMETHODIMP
-nsForceXMLListener::OnStartRequest(nsIRequest *aRequest) {
+nsForceXMLListener::OnStartRequest(nsIRequest *aRequest,
+                                   nsISupports *aContext) {
   nsresult status;
   aRequest->GetStatus(&status);
   nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
   if (channel && NS_SUCCEEDED(status)) {
     channel->SetContentType(NS_LITERAL_CSTRING("text/xml"));
   }
 
-  return mListener->OnStartRequest(aRequest);
+  return mListener->OnStartRequest(aRequest, aContext);
 }
 
 NS_IMETHODIMP
-nsForceXMLListener::OnStopRequest(nsIRequest *aRequest,
+nsForceXMLListener::OnStopRequest(nsIRequest *aRequest, nsISupports *aContext,
                                   nsresult aStatusCode) {
-  return mListener->OnStopRequest(aRequest, aStatusCode);
+  return mListener->OnStopRequest(aRequest, aContext, aStatusCode);
 }
 
 nsSyncLoader::~nsSyncLoader() {
   if (mLoading && mChannel) {
     mChannel->Cancel(NS_BINDING_ABORTED);
   }
 }
 
@@ -234,27 +235,27 @@ nsresult nsSyncLoader::PushSyncStream(ns
   rv = nsSyncLoadService::PushSyncStreamToListener(in.forget(), aListener,
                                                    mChannel);
   mLoading = false;
 
   return rv;
 }
 
 NS_IMETHODIMP
-nsSyncLoader::OnStartRequest(nsIRequest *aRequest) {
-  return mListener->OnStartRequest(aRequest);
+nsSyncLoader::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext) {
+  return mListener->OnStartRequest(aRequest, aContext);
 }
 
 NS_IMETHODIMP
-nsSyncLoader::OnStopRequest(nsIRequest *aRequest,
+nsSyncLoader::OnStopRequest(nsIRequest *aRequest, nsISupports *aContext,
                             nsresult aStatusCode) {
   if (NS_SUCCEEDED(mAsyncLoadStatus) && NS_FAILED(aStatusCode)) {
     mAsyncLoadStatus = aStatusCode;
   }
-  nsresult rv = mListener->OnStopRequest(aRequest, aStatusCode);
+  nsresult rv = mListener->OnStopRequest(aRequest, aContext, aStatusCode);
   if (NS_SUCCEEDED(mAsyncLoadStatus) && NS_FAILED(rv)) {
     mAsyncLoadStatus = rv;
   }
   mLoading = false;
 
   return rv;
 }
 
@@ -323,41 +324,41 @@ nsresult nsSyncLoadService::PushSyncStre
     rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream), in.forget(),
                                    chunkSize);
     NS_ENSURE_SUCCESS(rv, rv);
 
     in = bufferedStream;
   }
 
   // Load
-  rv = aListener->OnStartRequest(aChannel);
+  rv = aListener->OnStartRequest(aChannel, nullptr);
   if (NS_SUCCEEDED(rv)) {
     uint64_t sourceOffset = 0;
     while (1) {
       uint64_t readCount = 0;
       rv = in->Available(&readCount);
       if (NS_FAILED(rv) || !readCount) {
         if (rv == NS_BASE_STREAM_CLOSED) {
           // End of file, but not an error
           rv = NS_OK;
         }
         break;
       }
 
       if (readCount > UINT32_MAX) readCount = UINT32_MAX;
 
       rv = aListener->OnDataAvailable(
-          aChannel, in,
+          aChannel, nullptr, in,
           (uint32_t)std::min(sourceOffset, (uint64_t)UINT32_MAX),
           (uint32_t)readCount);
       if (NS_FAILED(rv)) {
         break;
       }
       sourceOffset += readCount;
     }
   }
   if (NS_FAILED(rv)) {
     aChannel->Cancel(rv);
   }
-  aListener->OnStopRequest(aChannel, rv);
+  aListener->OnStopRequest(aChannel, nullptr, rv);
 
   return rv;
 }
--- a/dom/base/test/chrome/test_bug682305.html
+++ b/dom/base/test/chrome/test_bug682305.html
@@ -51,24 +51,25 @@ CustomChannel.prototype = {
   loadFlags: 0,
   loadGroup: null,
   name: null,
   status: Cr.NS_OK,
   asyncOpen(listener) {
     // throws an error if security checks fail
     var outListener = contentSecManager.performSecurityCheck(this, listener);
     let stream = this.open();
+    let context = null;
     try {
-      outListener.onStartRequest(this);
+      outListener.onStartRequest(this, context);
     } catch (e) {}
     try {
-      outListener.onDataAvailable(this, stream, 0, stream.available());
+      outListener.onDataAvailable(this, context, stream, 0, stream.available());
     } catch (e) {}
     try {
-      outListener.onStopRequest(this, Cr.NS_OK);
+      outListener.onStopRequest(this, context, Cr.NS_OK);
     } catch (e) {}
   },
   open() {
     // throws an error if security checks fail
     contentSecManager.performSecurityCheck(this, null);
 
     let data = "bar";
     let stream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(Ci.nsIStringInputStream);
--- a/dom/base/test/send_gzip_content.sjs
+++ b/dom/base/test/send_gzip_content.sjs
@@ -6,17 +6,17 @@ function gzipCompressString(string, obs)
                 .createInstance(Ci.nsIStreamLoader);
   listener.init(obs);
   let converter = scs.asyncConvertData("uncompressed", "gzip",
                                         listener, null);
   let stringStream = Cc["@mozilla.org/io/string-input-stream;1"]
                     .createInstance(Ci.nsIStringInputStream);
   stringStream.data = string;
   converter.onStartRequest(null, null);
-  converter.onDataAvailable(null, stringStream, 0, string.length);
+  converter.onDataAvailable(null, null, stringStream, 0, string.length);
   converter.onStopRequest(null, null, null);
 }
 
 function produceData() {
   var chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()_+";
   var result = '';
   for (var i = 0; i < 100000; ++i) {
     result += chars;
--- a/dom/fetch/FetchDriver.cpp
+++ b/dom/fetch/FetchDriver.cpp
@@ -198,17 +198,18 @@ AlternativeDataStreamListener::GetAltern
 
 already_AddRefed<nsICacheInfoChannel>
 AlternativeDataStreamListener::GetCacheInfoChannel() {
   nsCOMPtr<nsICacheInfoChannel> channel = mCacheInfoChannel;
   return channel.forget();
 }
 
 NS_IMETHODIMP
-AlternativeDataStreamListener::OnStartRequest(nsIRequest* aRequest) {
+AlternativeDataStreamListener::OnStartRequest(nsIRequest* aRequest,
+                                              nsISupports* aContext) {
   AssertIsOnMainThread();
   MOZ_ASSERT(!mAlternativeDataType.IsEmpty());
   // Checking the alternative data type is the same between we asked and the
   // saved in the channel.
   nsAutoCString alternativeDataType;
   nsCOMPtr<nsICacheInfoChannel> cic = do_QueryInterface(aRequest);
   mStatus = AlternativeDataStreamListener::LOADING;
   if (cic && NS_SUCCEEDED(cic->GetAlternativeDataType(alternativeDataType)) &&
@@ -241,57 +242,59 @@ AlternativeDataStreamListener::OnStartRe
     // then call FetchDriver::OnStartRequest to continue the work. Unfortunately
     // can't change the stream listener to mFetchDriver, need to keep
     // AlternativeDataStreamListener alive to redirect OnDataAvailable and
     // OnStopRequest to mFetchDriver.
     MOZ_ASSERT(alternativeDataType.IsEmpty());
     mStatus = AlternativeDataStreamListener::FALLBACK;
     mAlternativeDataCacheEntryId = 0;
     MOZ_ASSERT(mFetchDriver);
-    return mFetchDriver->OnStartRequest(aRequest);
+    return mFetchDriver->OnStartRequest(aRequest, aContext);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 AlternativeDataStreamListener::OnDataAvailable(nsIRequest* aRequest,
+                                               nsISupports* aContext,
                                                nsIInputStream* aInputStream,
                                                uint64_t aOffset,
                                                uint32_t aCount) {
   if (mStatus == AlternativeDataStreamListener::LOADING) {
     MOZ_ASSERT(mPipeAlternativeOutputStream);
     uint32_t read;
     return aInputStream->ReadSegments(
         NS_CopySegmentToStream, mPipeAlternativeOutputStream, aCount, &read);
   }
   if (mStatus == AlternativeDataStreamListener::FALLBACK) {
     MOZ_ASSERT(mFetchDriver);
-    return mFetchDriver->OnDataAvailable(aRequest, aInputStream,
+    return mFetchDriver->OnDataAvailable(aRequest, aContext, aInputStream,
                                          aOffset, aCount);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 AlternativeDataStreamListener::OnStopRequest(nsIRequest* aRequest,
+                                             nsISupports* aContext,
                                              nsresult aStatusCode) {
   AssertIsOnMainThread();
 
   // Alternative data loading is going to finish, breaking the reference cycle
   // here by taking the ownership to a loacl variable.
   RefPtr<FetchDriver> fetchDriver = mFetchDriver.forget();
 
   if (mStatus == AlternativeDataStreamListener::CANCELED) {
     // do nothing
     return NS_OK;
   }
 
   if (mStatus == AlternativeDataStreamListener::FALLBACK) {
     MOZ_ASSERT(fetchDriver);
-    return fetchDriver->OnStopRequest(aRequest, aStatusCode);
+    return fetchDriver->OnStopRequest(aRequest, aContext, aStatusCode);
   }
 
   MOZ_DIAGNOSTIC_ASSERT(mStatus == AlternativeDataStreamListener::LOADING);
 
   MOZ_ASSERT(!mAlternativeDataType.IsEmpty() && mPipeAlternativeOutputStream &&
              mPipeAlternativeInputStream);
 
   mPipeAlternativeOutputStream->Close();
@@ -776,17 +779,17 @@ void FetchDriver::FailWithNetworkError(n
     mObserver->OnResponseEnd(FetchDriverObserver::eByNetworking);
     mObserver = nullptr;
   }
 
   mChannel = nullptr;
 }
 
 NS_IMETHODIMP
-FetchDriver::OnStartRequest(nsIRequest* aRequest) {
+FetchDriver::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext) {
   AssertIsOnMainThread();
 
   // Note, this can be called multiple times if we are doing an opaqueredirect.
   // In that case we will get a simulated OnStartRequest() and then the real
   // channel will call in with an errored OnStartRequest().
 
   if (!mChannel) {
     MOZ_ASSERT(!mObserver);
@@ -1124,17 +1127,17 @@ nsresult CopySegmentToStreamAndSRI(nsIIn
     *aCountWritten += n;
   }
   return NS_OK;
 }
 
 }  // anonymous namespace
 
 NS_IMETHODIMP
-FetchDriver::OnDataAvailable(nsIRequest* aRequest,
+FetchDriver::OnDataAvailable(nsIRequest* aRequest, nsISupports* aContext,
                              nsIInputStream* aInputStream, uint64_t aOffset,
                              uint32_t aCount) {
   // NB: This can be called on any thread!  But we're guaranteed that it is
   // called between OnStartRequest and OnStopRequest, so we don't need to worry
   // about races.
 
   if (mNeedToObserveOnDataAvailable) {
     mNeedToObserveOnDataAvailable = false;
@@ -1181,17 +1184,17 @@ FetchDriver::OnDataAvailable(nsIRequest*
   // So we must just assume the pipe is broken.
   if (aRead == 0 && aCount != 0) {
     return NS_BASE_STREAM_CLOSED;
   }
   return rv;
 }
 
 NS_IMETHODIMP
-FetchDriver::OnStopRequest(nsIRequest* aRequest,
+FetchDriver::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
                            nsresult aStatusCode) {
   AssertIsOnMainThread();
 
   MOZ_DIAGNOSTIC_ASSERT(!mOnStopRequestCalled);
   mOnStopRequestCalled = true;
 
   // main data loading is going to finish, breaking the reference cycle.
   RefPtr<AlternativeDataStreamListener> altDataListener =
--- a/dom/file/MutableBlobStreamListener.cpp
+++ b/dom/file/MutableBlobStreamListener.cpp
@@ -34,27 +34,29 @@ MutableBlobStreamListener::MutableBlobSt
 MutableBlobStreamListener::~MutableBlobStreamListener() {
   MOZ_ASSERT(NS_IsMainThread());
 }
 
 NS_IMPL_ISUPPORTS(MutableBlobStreamListener, nsIStreamListener,
                   nsIThreadRetargetableStreamListener, nsIRequestObserver)
 
 NS_IMETHODIMP
-MutableBlobStreamListener::OnStartRequest(nsIRequest* aRequest) {
+MutableBlobStreamListener::OnStartRequest(nsIRequest* aRequest,
+                                          nsISupports* aContext) {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(!mStorage);
   MOZ_ASSERT(mEventTarget);
 
   mStorage = new MutableBlobStorage(mStorageType, mEventTarget);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 MutableBlobStreamListener::OnStopRequest(nsIRequest* aRequest,
+                                         nsISupports* aContext,
                                          nsresult aStatus) {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(mStorage);
 
   // Resetting mStorage to nullptr.
   RefPtr<MutableBlobStorage> storage;
   storage.swap(mStorage);
 
@@ -65,16 +67,17 @@ MutableBlobStreamListener::OnStopRequest
   }
 
   storage->GetBlobWhenReady(mParent, mContentType, mCallback);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 MutableBlobStreamListener::OnDataAvailable(nsIRequest* aRequest,
+                                           nsISupports* aContext,
                                            nsIInputStream* aStream,
                                            uint64_t aSourceOffset,
                                            uint32_t aCount) {
   // This method could be called on any thread.
   MOZ_ASSERT(mStorage);
 
   uint32_t countRead;
   return aStream->ReadSegments(WriteSegmentFun, this, aCount, &countRead);
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -598,17 +598,18 @@ HTMLMediaElement::MediaLoadListener::Obs
   nsContentUtils::UnregisterShutdownObserver(this);
 
   // Clear mElement to break cycle so we don't leak on shutdown
   mElement = nullptr;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-HTMLMediaElement::MediaLoadListener::OnStartRequest(nsIRequest* aRequest) {
+HTMLMediaElement::MediaLoadListener::OnStartRequest(nsIRequest* aRequest,
+                                                    nsISupports* aContext) {
   nsContentUtils::UnregisterShutdownObserver(this);
 
   if (!mElement) {
     // We've been notified by the shutdown observer, and are shutting down.
     return NS_BINDING_ABORTED;
   }
 
   // Media element playback is not currently supported when recording or
@@ -675,17 +676,17 @@ HTMLMediaElement::MediaLoadListener::OnS
     return NS_BINDING_ABORTED;
   }
 
   nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
   if (channel &&
       NS_SUCCEEDED(rv = element->InitializeDecoderForChannel(
                        channel, getter_AddRefs(mNextListener))) &&
       mNextListener) {
-    rv = mNextListener->OnStartRequest(aRequest);
+    rv = mNextListener->OnStartRequest(aRequest, aContext);
   } else {
     // If InitializeDecoderForChannel() returned an error, fire a network error.
     if (NS_FAILED(rv) && !mNextListener) {
       // Load failed, attempt to load the next candidate resource. If there
       // are none, this will trigger a MEDIA_ERR_SRC_NOT_SUPPORTED error.
       element->NotifyLoadError(NS_LITERAL_CSTRING("Failed to init decoder"));
     }
     // If InitializeDecoderForChannel did not return a listener (but may
@@ -694,35 +695,37 @@ HTMLMediaElement::MediaLoadListener::OnS
     rv = NS_BINDING_ABORTED;
   }
 
   return rv;
 }
 
 NS_IMETHODIMP
 HTMLMediaElement::MediaLoadListener::OnStopRequest(nsIRequest* aRequest,
+                                                   nsISupports* aContext,
                                                    nsresult aStatus) {
   if (mNextListener) {
-    return mNextListener->OnStopRequest(aRequest, aStatus);
+    return mNextListener->OnStopRequest(aRequest, aContext, aStatus);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HTMLMediaElement::MediaLoadListener::OnDataAvailable(nsIRequest* aRequest,
+                                                     nsISupports* aContext,
                                                      nsIInputStream* aStream,
                                                      uint64_t aOffset,
                                                      uint32_t aCount) {
   if (!mNextListener) {
     NS_ERROR(
         "Must have a chained listener; OnStartRequest should have "
         "canceled this request");
     return NS_BINDING_ABORTED;
   }
-  return mNextListener->OnDataAvailable(aRequest, aStream, aOffset,
+  return mNextListener->OnDataAvailable(aRequest, aContext, aStream, aOffset,
                                         aCount);
 }
 
 NS_IMETHODIMP
 HTMLMediaElement::MediaLoadListener::AsyncOnChannelRedirect(
     nsIChannel* aOldChannel, nsIChannel* aNewChannel, uint32_t aFlags,
     nsIAsyncVerifyRedirectCallback* cb) {
   // TODO is this really correct?? See bug #579329.
--- a/dom/html/ImageDocument.cpp
+++ b/dom/html/ImageDocument.cpp
@@ -63,17 +63,17 @@ class ImageListener : public MediaDocume
 };
 
 ImageListener::ImageListener(ImageDocument* aDocument)
     : MediaDocumentStreamListener(aDocument) {}
 
 ImageListener::~ImageListener() {}
 
 NS_IMETHODIMP
-ImageListener::OnStartRequest(nsIRequest* request) {
+ImageListener::OnStartRequest(nsIRequest* request, nsISupports* ctxt) {
   NS_ENSURE_TRUE(mDocument, NS_ERROR_FAILURE);
 
   ImageDocument* imgDoc = static_cast<ImageDocument*>(mDocument.get());
   nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
   if (!channel) {
     return NS_ERROR_FAILURE;
   }
 
@@ -119,27 +119,27 @@ ImageListener::OnStartRequest(nsIRequest
         do_QueryInterface(imgDoc->mImageContent);
     NS_ENSURE_TRUE(imageLoader, NS_ERROR_UNEXPECTED);
 
     imageLoader->AddNativeObserver(imgDoc);
     imgDoc->mObservingImageLoader = true;
     imageLoader->LoadImageWithChannel(channel, getter_AddRefs(mNextStream));
   }
 
-  return MediaDocumentStreamListener::OnStartRequest(request);
+  return MediaDocumentStreamListener::OnStartRequest(request, ctxt);
 }
 
 NS_IMETHODIMP
-ImageListener::OnStopRequest(nsIRequest* aRequest,
+ImageListener::OnStopRequest(nsIRequest* aRequest, nsISupports* aCtxt,
                              nsresult aStatus) {
   ImageDocument* imgDoc = static_cast<ImageDocument*>(mDocument.get());
   nsContentUtils::DispatchChromeEvent(imgDoc, ToSupports(imgDoc),
                                       NS_LITERAL_STRING("ImageContentLoaded"),
                                       CanBubble::eYes, Cancelable::eYes);
-  return MediaDocumentStreamListener::OnStopRequest(aRequest, aStatus);
+  return MediaDocumentStreamListener::OnStopRequest(aRequest, aCtxt, aStatus);
 }
 
 ImageDocument::ImageDocument()
     : MediaDocument(),
       mVisibleWidth(0.0),
       mVisibleHeight(0.0),
       mImageWidth(0),
       mImageHeight(0),
--- a/dom/html/MediaDocument.cpp
+++ b/dom/html/MediaDocument.cpp
@@ -44,34 +44,35 @@ NS_IMPL_ISUPPORTS(MediaDocumentStreamLis
                   nsIStreamListener, nsIThreadRetargetableStreamListener)
 
 void MediaDocumentStreamListener::SetStreamListener(
     nsIStreamListener* aListener) {
   mNextStream = aListener;
 }
 
 NS_IMETHODIMP
-MediaDocumentStreamListener::OnStartRequest(nsIRequest* request) {
+MediaDocumentStreamListener::OnStartRequest(nsIRequest* request,
+                                            nsISupports* ctxt) {
   NS_ENSURE_TRUE(mDocument, NS_ERROR_FAILURE);
 
   mDocument->StartLayout();
 
   if (mNextStream) {
-    return mNextStream->OnStartRequest(request);
+    return mNextStream->OnStartRequest(request, ctxt);
   }
 
   return NS_ERROR_PARSED_DATA_CACHED;
 }
 
 NS_IMETHODIMP
 MediaDocumentStreamListener::OnStopRequest(nsIRequest* request,
-                                           nsresult status) {
+                                           nsISupports* ctxt, nsresult status) {
   nsresult rv = NS_OK;
   if (mNextStream) {
-    rv = mNextStream->OnStopRequest(request, status);
+    rv = mNextStream->OnStopRequest(request, ctxt, status);
   }
 
   // Don't release mDocument here if we're in the middle of a multipart
   // response.
   bool lastPart = true;
   nsCOMPtr<nsIMultiPartChannel> mpchan(do_QueryInterface(request));
   if (mpchan) {
     mpchan->GetIsLastPart(&lastPart);
@@ -80,21 +81,22 @@ MediaDocumentStreamListener::OnStopReque
   if (lastPart) {
     mDocument = nullptr;
   }
   return rv;
 }
 
 NS_IMETHODIMP
 MediaDocumentStreamListener::OnDataAvailable(nsIRequest* request,
+                                             nsISupports* ctxt,
                                              nsIInputStream* inStr,
                                              uint64_t sourceOffset,
                                              uint32_t count) {
   if (mNextStream) {
-    return mNextStream->OnDataAvailable(request, inStr, sourceOffset,
+    return mNextStream->OnDataAvailable(request, ctxt, inStr, sourceOffset,
                                         count);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 MediaDocumentStreamListener::CheckListenerChain() {
--- a/dom/html/PluginDocument.cpp
+++ b/dom/html/PluginDocument.cpp
@@ -66,24 +66,24 @@ class PluginDocument final : public Medi
   RefPtr<MediaDocumentStreamListener> mStreamListener;
   nsCString mMimeType;
 };
 
 class PluginStreamListener : public MediaDocumentStreamListener {
  public:
   explicit PluginStreamListener(PluginDocument* aDoc)
       : MediaDocumentStreamListener(aDoc), mPluginDoc(aDoc) {}
-  NS_IMETHOD OnStartRequest(nsIRequest* request) override;
+  NS_IMETHOD OnStartRequest(nsIRequest* request, nsISupports* ctxt) override;
 
  private:
   RefPtr<PluginDocument> mPluginDoc;
 };
 
 NS_IMETHODIMP
-PluginStreamListener::OnStartRequest(nsIRequest* request) {
+PluginStreamListener::OnStartRequest(nsIRequest* request, nsISupports* ctxt) {
   AUTO_PROFILER_LABEL("PluginStreamListener::OnStartRequest", NETWORK);
 
   nsCOMPtr<nsIContent> embed = mPluginDoc->GetPluginContent();
   nsCOMPtr<nsIObjectLoadingContent> objlc = do_QueryInterface(embed);
   nsCOMPtr<nsIStreamListener> objListener = do_QueryInterface(objlc);
 
   if (!objListener) {
     MOZ_ASSERT_UNREACHABLE(
@@ -99,17 +99,17 @@ PluginStreamListener::OnStartRequest(nsI
   nsresult rv = objlc->InitializeFromChannel(request);
   if (NS_FAILED(rv)) {
     MOZ_ASSERT_UNREACHABLE("InitializeFromChannel failed");
     return rv;
   }
 
   // Note that because we're now hooked up to a plugin listener, this will
   // likely spawn a plugin, which may re-enter.
-  return MediaDocumentStreamListener::OnStartRequest(request);
+  return MediaDocumentStreamListener::OnStartRequest(request, ctxt);
 }
 
 PluginDocument::PluginDocument() {}
 
 PluginDocument::~PluginDocument() = default;
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED(PluginDocument, MediaDocument,
                                    mPluginContent)
--- a/dom/jsurl/nsJSProtocolHandler.cpp
+++ b/dom/jsurl/nsJSProtocolHandler.cpp
@@ -731,18 +731,18 @@ void nsJSChannel::EvaluateScript() {
     }
 
   } else if (mIsAsync) {
     NotifyListener();
   }
 }
 
 void nsJSChannel::NotifyListener() {
-  mListener->OnStartRequest(this);
-  mListener->OnStopRequest(this, mStatus);
+  mListener->OnStartRequest(this, nullptr);
+  mListener->OnStopRequest(this, nullptr, mStatus);
 
   CleanupStrongRefs();
 }
 
 void nsJSChannel::CleanupStrongRefs() {
   mListener = nullptr;
   mOriginalInnerWindow = nullptr;
   if (mDocumentOnloadBlockedOn) {
@@ -931,47 +931,47 @@ nsJSChannel::GetContentLength(int64_t* a
 }
 
 NS_IMETHODIMP
 nsJSChannel::SetContentLength(int64_t aContentLength) {
   return mStreamChannel->SetContentLength(aContentLength);
 }
 
 NS_IMETHODIMP
-nsJSChannel::OnStartRequest(nsIRequest* aRequest) {
+nsJSChannel::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext) {
   NS_ENSURE_TRUE(aRequest == mStreamChannel, NS_ERROR_UNEXPECTED);
 
-  return mListener->OnStartRequest(this);
+  return mListener->OnStartRequest(this, aContext);
 }
 
 NS_IMETHODIMP
-nsJSChannel::OnDataAvailable(nsIRequest* aRequest,
+nsJSChannel::OnDataAvailable(nsIRequest* aRequest, nsISupports* aContext,
                              nsIInputStream* aInputStream, uint64_t aOffset,
                              uint32_t aCount) {
   NS_ENSURE_TRUE(aRequest == mStreamChannel, NS_ERROR_UNEXPECTED);
 
-  return mListener->OnDataAvailable(this, aInputStream, aOffset,
+  return mListener->OnDataAvailable(this, aContext, aInputStream, aOffset,
                                     aCount);
 }
 
 NS_IMETHODIMP
-nsJSChannel::OnStopRequest(nsIRequest* aRequest,
+nsJSChannel::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
                            nsresult aStatus) {
   NS_ENSURE_TRUE(aRequest == mStreamChannel, NS_ERROR_UNEXPECTED);
 
   nsCOMPtr<nsIStreamListener> listener = mListener;
 
   CleanupStrongRefs();
 
   // Make sure aStatus matches what GetStatus() returns
   if (NS_FAILED(mStatus)) {
     aStatus = mStatus;
   }
 
-  nsresult rv = listener->OnStopRequest(this, aStatus);
+  nsresult rv = listener->OnStopRequest(this, aContext, aStatus);
 
   nsCOMPtr<nsILoadGroup> loadGroup;
   mStreamChannel->GetLoadGroup(getter_AddRefs(loadGroup));
   if (loadGroup) {
     loadGroup->RemoveRequest(this, nullptr, mStatus);
   }
 
   mIsActive = false;
--- a/dom/media/ChannelMediaResource.cpp
+++ b/dom/media/ChannelMediaResource.cpp
@@ -48,31 +48,33 @@ ChannelMediaResource::~ChannelMediaResou
 // listener objects so that when we open a new stream for a seek we can
 // disconnect the old listener from the ChannelMediaResource and hook up
 // a new listener, so notifications from the old channel are discarded
 // and don't confuse us.
 NS_IMPL_ISUPPORTS(ChannelMediaResource::Listener, nsIRequestObserver,
                   nsIStreamListener, nsIChannelEventSink, nsIInterfaceRequestor,
                   nsIThreadRetargetableStreamListener)
 
-nsresult ChannelMediaResource::Listener::OnStartRequest(nsIRequest* aRequest) {
+nsresult ChannelMediaResource::Listener::OnStartRequest(nsIRequest* aRequest,
+                                                        nsISupports* aContext) {
   MOZ_ASSERT(NS_IsMainThread());
   if (!mResource) return NS_OK;
   return mResource->OnStartRequest(aRequest, mOffset);
 }
 
 nsresult ChannelMediaResource::Listener::OnStopRequest(nsIRequest* aRequest,
+                                                       nsISupports* aContext,
                                                        nsresult aStatus) {
   MOZ_ASSERT(NS_IsMainThread());
   if (!mResource) return NS_OK;
   return mResource->OnStopRequest(aRequest, aStatus);
 }
 
 nsresult ChannelMediaResource::Listener::OnDataAvailable(
-    nsIRequest* aRequest, nsIInputStream* aStream,
+    nsIRequest* aRequest, nsISupports* aContext, nsIInputStream* aStream,
     uint64_t aOffset, uint32_t aCount) {
   // This might happen off the main thread.
   RefPtr<ChannelMediaResource> res;
   {
     MutexAutoLock lock(mMutex);
     res = mResource;
   }
   // Note Rekove() might happen at the same time to reset mResource. We check
--- a/dom/media/IdpSandbox.jsm
+++ b/dom/media/IdpSandbox.jsm
@@ -46,26 +46,26 @@ ResourceLoader.load = function(uri, doc)
 
     ioChannel.loadGroup = doc.documentLoadGroup.QueryInterface(Ci.nsILoadGroup);
     ioChannel.notificationCallbacks = new RedirectHttpsOnly();
     ioChannel.asyncOpen(listener);
   });
 };
 
 ResourceLoader.prototype = {
-  onDataAvailable(request, input, offset, count) {
+  onDataAvailable(request, context, input, offset, count) {
     let stream = Cc["@mozilla.org/scriptableinputstream;1"]
       .createInstance(Ci.nsIScriptableInputStream);
     stream.init(input);
     this.data += stream.read(count);
   },
 
-  onStartRequest(request) {},
+  onStartRequest(request, context) {},
 
-  onStopRequest(request, status) {
+  onStopRequest(request, context, status) {
     if (Components.isSuccessCode(status)) {
       var statusCode = request.QueryInterface(Ci.nsIHttpChannel).responseStatus;
       if (statusCode === 200) {
         this.resolve({ request, data: this.data });
       } else {
         this.reject(new Error("Non-200 response from server: " + statusCode));
       }
     } else {
--- a/dom/media/WebVTTListener.cpp
+++ b/dom/media/WebVTTListener.cpp
@@ -73,23 +73,23 @@ WebVTTListener::AsyncOnChannelRedirect(n
   if (mElement) {
     mElement->OnChannelRedirect(aOldChannel, aNewChannel, aFlags);
   }
   cb->OnRedirectVerifyCallback(NS_OK);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-WebVTTListener::OnStartRequest(nsIRequest* aRequest) {
+WebVTTListener::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext) {
   VTT_LOG("WebVTTListener::OnStartRequest\n");
   return NS_OK;
 }
 
 NS_IMETHODIMP
-WebVTTListener::OnStopRequest(nsIRequest* aRequest,
+WebVTTListener::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
                               nsresult aStatus) {
   VTT_LOG("WebVTTListener::OnStopRequest\n");
   if (NS_FAILED(aStatus)) {
     mElement->SetReadyState(TextTrackReadyState::FailedToLoad);
   }
   // Attempt to parse any final data the parser might still have.
   mParserWrapper->Flush();
   if (mElement->ReadyState() != TextTrackReadyState::FailedToLoad) {
@@ -114,17 +114,17 @@ nsresult WebVTTListener::ParseChunk(nsII
     return NS_ERROR_FAILURE;
   }
 
   *aWriteCount = aCount;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-WebVTTListener::OnDataAvailable(nsIRequest* aRequest,
+WebVTTListener::OnDataAvailable(nsIRequest* aRequest, nsISupports* aContext,
                                 nsIInputStream* aStream, uint64_t aOffset,
                                 uint32_t aCount) {
   VTT_LOG("WebVTTListener::OnDataAvailable\n");
   uint32_t count = aCount;
   while (count > 0) {
     uint32_t read;
     nsresult rv = aStream->ReadSegments(ParseChunk, this, count, &read);
     NS_ENSURE_SUCCESS(rv, rv);
--- a/dom/network/TCPSocket.cpp
+++ b/dom/network/TCPSocket.cpp
@@ -314,22 +314,22 @@ class CopierCallbacks final : public nsI
   NS_DECL_NSIREQUESTOBSERVER
  private:
   ~CopierCallbacks() {}
 };
 
 NS_IMPL_ISUPPORTS(CopierCallbacks, nsIRequestObserver)
 
 NS_IMETHODIMP
-CopierCallbacks::OnStartRequest(nsIRequest* aRequest) {
+CopierCallbacks::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext) {
   return NS_OK;
 }
 
 NS_IMETHODIMP
-CopierCallbacks::OnStopRequest(nsIRequest* aRequest,
+CopierCallbacks::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
                                nsresult aStatus) {
   mOwner->NotifyCopyComplete(aStatus);
   mOwner = nullptr;
   return NS_OK;
 }
 }  // unnamed namespace
 
 nsresult TCPSocket::EnsureCopying() {
@@ -927,22 +927,22 @@ TCPSocket::OnInputStreamReady(nsIAsyncIn
   nsresult rv = aStream->Available(&dummy);
   if (NS_FAILED(rv)) {
     MaybeReportErrorAndCloseIfOpen(NS_ERROR_CONNECTION_REFUSED);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
-TCPSocket::OnStartRequest(nsIRequest* aRequest) {
+TCPSocket::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext) {
   return NS_OK;
 }
 
 NS_IMETHODIMP
-TCPSocket::OnDataAvailable(nsIRequest* aRequest,
+TCPSocket::OnDataAvailable(nsIRequest* aRequest, nsISupports* aContext,
                            nsIInputStream* aStream, uint64_t aOffset,
                            uint32_t aCount) {
   if (mUseArrayBuffers) {
     nsTArray<uint8_t> buffer;
     buffer.SetCapacity(aCount);
     uint32_t actual;
     nsresult rv = aStream->Read(reinterpret_cast<char*>(buffer.Elements()),
                                 aCount, &actual);
@@ -989,17 +989,17 @@ TCPSocket::OnDataAvailable(nsIRequest* a
     return NS_ERROR_FAILURE;
   }
   FireDataEvent(cx, NS_LITERAL_STRING("data"), value);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-TCPSocket::OnStopRequest(nsIRequest* aRequest,
+TCPSocket::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
                          nsresult aStatus) {
   mInputStreamPump = nullptr;
 
   if (mAsyncCopierActive && NS_SUCCEEDED(aStatus)) {
     // If we have some buffered output still, and status is not an
     // error, the other side has done a half-close, but we don't
     // want to be in the close state until we are done sending
     // everything that was buffered. We also don't want to call onclose
--- a/dom/plugins/base/nsPluginStreamListenerPeer.cpp
+++ b/dom/plugins/base/nsPluginStreamListenerPeer.cpp
@@ -100,17 +100,18 @@ nsresult nsPluginStreamListenerPeer::Ini
   }
 
   mPendingRequests = 1;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsPluginStreamListenerPeer::OnStartRequest(nsIRequest* request) {
+nsPluginStreamListenerPeer::OnStartRequest(nsIRequest* request,
+                                           nsISupports* aContext) {
   nsresult rv = NS_OK;
   AUTO_PROFILER_LABEL("nsPluginStreamListenerPeer::OnStartRequest", OTHER);
 
   if (mRequests.IndexOfObject(request) == -1) {
     NS_ASSERTION(mRequests.Count() == 0,
                  "Only our initial stream should be unknown!");
     TrackRequest(request);
   }
@@ -275,35 +276,35 @@ class PluginContextProxy final : public 
 
   PluginContextProxy(nsIStreamListener* aListener, nsISupports* aContext)
       : mListener(aListener), mContext(aContext) {
     MOZ_ASSERT(aListener);
     MOZ_ASSERT(aContext);
   }
 
   NS_IMETHOD
-  OnDataAvailable(nsIRequest* aRequest,
+  OnDataAvailable(nsIRequest* aRequest, nsISupports* aContext,
                   nsIInputStream* aIStream, uint64_t aSourceOffset,
                   uint32_t aLength) override {
     // Proxy OnDataAvailable using the internal context
-    return mListener->OnDataAvailable(aRequest, aIStream,
+    return mListener->OnDataAvailable(aRequest, mContext, aIStream,
                                       aSourceOffset, aLength);
   }
 
   NS_IMETHOD
-  OnStartRequest(nsIRequest* aRequest) override {
+  OnStartRequest(nsIRequest* aRequest, nsISupports* aContext) override {
     // Proxy OnStartRequest using the internal context
-    return mListener->OnStartRequest(aRequest);
+    return mListener->OnStartRequest(aRequest, mContext);
   }
 
   NS_IMETHOD
-  OnStopRequest(nsIRequest* aRequest,
+  OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
                 nsresult aStatusCode) override {
     // Proxy OnStopRequest using the inernal context
-    return mListener->OnStopRequest(aRequest, aStatusCode);
+    return mListener->OnStopRequest(aRequest, mContext, aStatusCode);
   }
 
  private:
   ~PluginContextProxy() {}
   nsCOMPtr<nsIStreamListener> mListener;
   nsCOMPtr<nsISupports> mContext;
 };
 
@@ -315,17 +316,17 @@ nsresult nsPluginStreamListenerPeer::Get
 }
 
 nsresult nsPluginStreamListenerPeer::SetStreamOffset(int32_t value) {
   mStreamOffset = value;
   return NS_OK;
 }
 
 NS_IMETHODIMP nsPluginStreamListenerPeer::OnDataAvailable(
-    nsIRequest* request, nsIInputStream* aIStream,
+    nsIRequest* request, nsISupports* aContext, nsIInputStream* aIStream,
     uint64_t sourceOffset, uint32_t aLength) {
   if (mRequests.IndexOfObject(request) == -1) {
     MOZ_ASSERT(false, "Received OnDataAvailable for untracked request.");
     return NS_ERROR_UNEXPECTED;
   }
 
   if (mRequestFailed) return NS_ERROR_FAILURE;
 
@@ -349,16 +350,17 @@ NS_IMETHODIMP nsPluginStreamListenerPeer
   if (NS_FAILED(rv)) {
     request->Cancel(rv);
   }
 
   return rv;
 }
 
 NS_IMETHODIMP nsPluginStreamListenerPeer::OnStopRequest(nsIRequest* request,
+                                                        nsISupports* aContext,
                                                         nsresult aStatus) {
   nsresult rv = NS_OK;
 
   nsCOMPtr<nsIMultiPartChannel> mp = do_QueryInterface(request);
   if (!mp) {
     bool found = mRequests.RemoveObject(request);
     if (!found) {
       NS_ERROR("Received OnStopRequest for untracked request.");
--- a/dom/presentation/PresentationTCPSessionTransport.cpp
+++ b/dom/presentation/PresentationTCPSessionTransport.cpp
@@ -39,22 +39,22 @@ class CopierCallbacks final : public nsI
   ~CopierCallbacks() {}
 
   RefPtr<PresentationTCPSessionTransport> mOwner;
 };
 
 NS_IMPL_ISUPPORTS(CopierCallbacks, nsIRequestObserver)
 
 NS_IMETHODIMP
-CopierCallbacks::OnStartRequest(nsIRequest* aRequest) {
+CopierCallbacks::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext) {
   return NS_OK;
 }
 
 NS_IMETHODIMP
-CopierCallbacks::OnStopRequest(nsIRequest* aRequest,
+CopierCallbacks::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
                                nsresult aStatus) {
   mOwner->NotifyCopyComplete(aStatus);
   return NS_OK;
 }
 
 NS_IMPL_CYCLE_COLLECTION(PresentationTCPSessionTransport, mTransport,
                          mSocketInputStream, mSocketOutputStream,
                          mInputStreamPump, mInputStreamScriptable, mCallback)
@@ -498,23 +498,25 @@ PresentationTCPSessionTransport::OnInput
     }
   }
 
   return NS_OK;
 }
 
 // nsIRequestObserver
 NS_IMETHODIMP
-PresentationTCPSessionTransport::OnStartRequest(nsIRequest* aRequest) {
+PresentationTCPSessionTransport::OnStartRequest(nsIRequest* aRequest,
+                                                nsISupports* aContext) {
   // Do nothing.
   return NS_OK;
 }
 
 NS_IMETHODIMP
 PresentationTCPSessionTransport::OnStopRequest(nsIRequest* aRequest,
+                                               nsISupports* aContext,
                                                nsresult aStatusCode) {
   PRES_DEBUG("%s:aStatusCode[%" PRIx32 "]\n", __func__,
              static_cast<uint32_t>(aStatusCode));
 
   MOZ_ASSERT(NS_IsMainThread());
 
   mInputStreamPump = nullptr;
 
@@ -532,16 +534,17 @@ PresentationTCPSessionTransport::OnStopR
     SetReadyState(ReadyState::CLOSED);
   }
   return NS_OK;
 }
 
 // nsIStreamListener
 NS_IMETHODIMP
 PresentationTCPSessionTransport::OnDataAvailable(nsIRequest* aRequest,
+                                                 nsISupports* aContext,
                                                  nsIInputStream* aStream,
                                                  uint64_t aOffset,
                                                  uint32_t aCount) {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (NS_WARN_IF(!mCallback)) {
     return NS_ERROR_NOT_AVAILABLE;
   }
--- a/dom/presentation/provider/PresentationControlService.jsm
+++ b/dom/presentation/provider/PresentationControlService.jsm
@@ -617,17 +617,17 @@ TCPControlChannel.prototype = {
   // nsIRequestObserver (Triggered by nsIInputStreamPump.asyncRead)
   onStopRequest(aRequest, aContext, aStatus) {
     DEBUG && log("TCPControlChannel - onStopRequest: " + aStatus +
                  " with role: " + this._direction); // jshint ignore:line
     this._stateMachine.onChannelClosed(aStatus, true);
   },
 
   // nsIStreamListener (Triggered by nsIInputStreamPump.asyncRead)
-  onDataAvailable(aRequest, aInputStream) {
+  onDataAvailable(aRequest, aContext, aInputStream) {
     let data = NetUtil.readInputStreamToString(aInputStream,
                                                aInputStream.available());
     DEBUG && log("TCPControlChannel - onDataAvailable: " + data); // jshint ignore:line
 
     // Parser of line delimited JSON. Please see |_send| for more informaiton.
     let jsonArray = data.split("\n");
     jsonArray.pop();
     for (let json of jsonArray) {
--- a/dom/push/PushServiceHttp2.jsm
+++ b/dom/push/PushServiceHttp2.jsm
@@ -51,37 +51,37 @@ PushSubscriptionListener.prototype = {
 
   QueryInterface: ChromeUtils.generateQI(["nsIHttpPushListener",
                                          "nsIStreamListener"]),
 
   getInterface: function(aIID) {
     return this.QueryInterface(aIID);
   },
 
-  onStartRequest: function(aRequest) {
+  onStartRequest: function(aRequest, aContext) {
     console.debug("PushSubscriptionListener: onStartRequest()");
     // We do not do anything here.
   },
 
-  onDataAvailable: function(aRequest, aStream, aOffset, aCount) {
+  onDataAvailable: function(aRequest, aContext, aStream, aOffset, aCount) {
     console.debug("PushSubscriptionListener: onDataAvailable()");
     // Nobody should send data, but just to be sure, otherwise necko will
     // complain.
     if (aCount === 0) {
       return;
     }
 
     let inputStream = Cc["@mozilla.org/scriptableinputstream;1"]
                         .createInstance(Ci.nsIScriptableInputStream);
 
     inputStream.init(aStream);
     var data = inputStream.read(aCount);
   },
 
-  onStopRequest: function(aRequest, aStatusCode) {
+  onStopRequest: function(aRequest, aContext, aStatusCode) {
     console.debug("PushSubscriptionListener: onStopRequest()");
     if (!this._pushService) {
         return;
     }
 
     this._pushService.connOnStop(aRequest,
                                  Components.isSuccessCode(aStatusCode),
                                  this.uri);
@@ -106,37 +106,37 @@ var PushChannelListener = function(pushS
   console.debug("PushChannelListener()");
   this._mainListener = pushSubscriptionListener;
   this._message = [];
   this._ackUri = null;
 };
 
 PushChannelListener.prototype = {
 
-  onStartRequest: function(aRequest) {
+  onStartRequest: function(aRequest, aContext) {
     this._ackUri = aRequest.URI.spec;
   },
 
-  onDataAvailable: function(aRequest, aStream, aOffset, aCount) {
+  onDataAvailable: function(aRequest, aContext, aStream, aOffset, aCount) {
     console.debug("PushChannelListener: onDataAvailable()");
 
     if (aCount === 0) {
       return;
     }
 
     let inputStream = Cc["@mozilla.org/binaryinputstream;1"]
                         .createInstance(Ci.nsIBinaryInputStream);
 
     inputStream.setInputStream(aStream);
     let chunk = new ArrayBuffer(aCount);
     inputStream.readArrayBuffer(aCount, chunk);
     this._message.push(chunk);
   },
 
-  onStopRequest: function(aRequest, aStatusCode) {
+  onStopRequest: function(aRequest, aContext, aStatusCode) {
     console.debug("PushChannelListener: onStopRequest()", "status code",
       aStatusCode);
     if (Components.isSuccessCode(aStatusCode) &&
         this._mainListener &&
         this._mainListener._pushService) {
       let headers = {
         encryption_key: getHeaderField(aRequest, "Encryption-Key"),
         crypto_key: getHeaderField(aRequest, "Crypto-Key"),
@@ -164,33 +164,33 @@ function getHeaderField(aRequest, name) 
 
 var PushServiceDelete = function(resolve, reject) {
   this._resolve = resolve;
   this._reject = reject;
 };
 
 PushServiceDelete.prototype = {
 
-  onStartRequest: function(aRequest) {},
+  onStartRequest: function(aRequest, aContext) {},
 
-  onDataAvailable: function(aRequest, aStream, aOffset, aCount) {
+  onDataAvailable: function(aRequest, aContext, aStream, aOffset, aCount) {
     // Nobody should send data, but just to be sure, otherwise necko will
     // complain.
     if (aCount === 0) {
       return;
     }
 
     let inputStream = Cc["@mozilla.org/scriptableinputstream;1"]
                         .createInstance(Ci.nsIScriptableInputStream);
 
     inputStream.init(aStream);
     var data = inputStream.read(aCount);
   },
 
-  onStopRequest: function(aRequest, aStatusCode) {
+  onStopRequest: function(aRequest, aContext, aStatusCode) {
 
     if (Components.isSuccessCode(aStatusCode)) {
        this._resolve();
     } else {
        this._reject(new Error("Error removing subscription: " + aStatusCode));
     }
   }
 };
@@ -205,35 +205,35 @@ var SubscriptionListener = function(aSub
   this._serverURI = aServerURI;
   this._service = aPushServiceHttp2;
   this._ctime = Date.now();
   this._retryTimeoutID = null;
 };
 
 SubscriptionListener.prototype = {
 
-  onStartRequest: function(aRequest) {},
+  onStartRequest: function(aRequest, aContext) {},
 
-  onDataAvailable: function(aRequest, aStream, aOffset, aCount) {
+  onDataAvailable: function(aRequest, aContext, aStream, aOffset, aCount) {
     console.debug("SubscriptionListener: onDataAvailable()");
 
     // We do not expect any data, but necko will complain if we do not consume
     // it.
     if (aCount === 0) {
       return;
     }
 
     let inputStream = Cc["@mozilla.org/scriptableinputstream;1"]
                         .createInstance(Ci.nsIScriptableInputStream);
 
     inputStream.init(aStream);
     this._data.concat(inputStream.read(aCount));
   },
 
-  onStopRequest: function(aRequest, aStatus) {
+  onStopRequest: function(aRequest, aContext, aStatus) {
     console.debug("SubscriptionListener: onStopRequest()");
 
     // Check if pushService is still active.
     if (!this._service.hasmainPushService()) {
       this._reject(new Error("Push service unavailable"));
       return;
     }
 
--- a/dom/security/ContentVerifier.cpp
+++ b/dom/security/ContentVerifier.cpp
@@ -81,79 +81,79 @@ void ContentVerifier::FinishSignature() 
   bool verified = false;
   nsresult rv = NS_OK;
 
   // If the content signature check fails, stop the load
   // and return a signature error. NSS resources are freed by the
   // ContentSignatureVerifier on destruction.
   if (NS_FAILED(mVerifier->End(&verified)) || !verified) {
     CSV_LOG(("failed to verify content\n"));
-    (void)nextListener->OnStopRequest(mContentRequest,
+    (void)nextListener->OnStopRequest(mContentRequest, mContentContext,
                                       NS_ERROR_INVALID_SIGNATURE);
     return;
   }
   CSV_LOG(("Successfully verified content signature.\n"));
 
   // We emptied the input stream so we have to create a new one from mContent
   // to hand it to the consuming listener.
   uint64_t offset = 0;
   for (uint32_t i = 0; i < mContent.Length(); ++i) {
     nsCOMPtr<nsIInputStream> oInStr;
     rv = NS_NewCStringInputStream(getter_AddRefs(oInStr), mContent[i]);
     if (NS_FAILED(rv)) {
       break;
     }
     // let the next listener know that there is data in oInStr
-    rv = nextListener->OnDataAvailable(mContentRequest, oInStr,
+    rv = nextListener->OnDataAvailable(mContentRequest, mContentContext, oInStr,
                                        offset, mContent[i].Length());
     offset += mContent[i].Length();
     if (NS_FAILED(rv)) {
       break;
     }
   }
 
   // propagate OnStopRequest and return
-  nextListener->OnStopRequest(mContentRequest, rv);
+  nextListener->OnStopRequest(mContentRequest, mContentContext, rv);
 }
 
 NS_IMETHODIMP
-ContentVerifier::OnStartRequest(nsIRequest* aRequest) {
+ContentVerifier::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext) {
   MOZ_CRASH("This OnStartRequest should've never been called!");
   return NS_OK;
 }
 
 NS_IMETHODIMP
-ContentVerifier::OnStopRequest(nsIRequest* aRequest,
+ContentVerifier::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
                                nsresult aStatus) {
   // If we don't have a next listener, we handed off this request already.
   // Return, there's nothing to do here.
   if (!mNextListener) {
     return NS_OK;
   }
 
   if (NS_FAILED(aStatus)) {
     CSV_LOG(("Stream failed\n"));
     nsCOMPtr<nsIStreamListener> nextListener;
     nextListener.swap(mNextListener);
-    return nextListener->OnStopRequest(aRequest, aStatus);
+    return nextListener->OnStopRequest(aRequest, aContext, aStatus);
   }
 
   mContentRead = true;
 
   // If the ContentSignatureVerifier is initialised, finish the verification.
   if (mContextCreated) {
     FinishSignature();
     return aStatus;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-ContentVerifier::OnDataAvailable(nsIRequest* aRequest,
+ContentVerifier::OnDataAvailable(nsIRequest* aRequest, nsISupports* aContext,
                                  nsIInputStream* aInputStream, uint64_t aOffset,
                                  uint32_t aCount) {
   // buffer the entire stream
   uint32_t read;
   nsresult rv =
       aInputStream->ReadSegments(AppendNextSegment, &mContent, aCount, &read);
   if (NS_FAILED(rv)) {
     return rv;
@@ -184,17 +184,17 @@ ContentVerifier::ContextCreated(bool suc
     // Make sure that OnStartRequest was called and we have a request.
     MOZ_ASSERT(mContentRequest);
 
     // In this case something went wrong with the cert. Let's stop this load.
     CSV_LOG(("failed to get a valid cert chain\n"));
     if (mContentRequest && nextListener) {
       mContentRequest->Cancel(NS_ERROR_INVALID_SIGNATURE);
       nsresult rv = nextListener->OnStopRequest(
-          mContentRequest, NS_ERROR_INVALID_SIGNATURE);
+          mContentRequest, mContentContext, NS_ERROR_INVALID_SIGNATURE);
       mContentRequest = nullptr;
       mContentContext = nullptr;
       return rv;
     }
 
     // We should never get here!
     MOZ_ASSERT_UNREACHABLE(
         "ContentVerifier was used without getting OnStartRequest!");
--- a/dom/security/nsCSPContext.cpp
+++ b/dom/security/nsCSPContext.cpp
@@ -1590,32 +1590,35 @@ nsresult AppendSegmentToString(nsIInputS
   nsCString* decodedData = static_cast<nsCString*>(aClosure);
   decodedData->Append(aRawSegment, aCount);
   *outWrittenCount = aCount;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 CSPViolationReportListener::OnDataAvailable(nsIRequest* aRequest,
+                                            nsISupports* aContext,
                                             nsIInputStream* aInputStream,
                                             uint64_t aOffset, uint32_t aCount) {
   uint32_t read;
   nsCString decodedData;
   return aInputStream->ReadSegments(AppendSegmentToString, &decodedData, aCount,
                                     &read);
 }
 
 NS_IMETHODIMP
 CSPViolationReportListener::OnStopRequest(nsIRequest* aRequest,
+                                          nsISupports* aContext,
                                           nsresult aStatus) {
   return NS_OK;
 }
 
 NS_IMETHODIMP
-CSPViolationReportListener::OnStartRequest(nsIRequest* aRequest) {
+CSPViolationReportListener::OnStartRequest(nsIRequest* aRequest,
+                                           nsISupports* aContext) {
   return NS_OK;
 }
 
 /* ========== CSPReportRedirectSink implementation ========== */
 
 NS_IMPL_ISUPPORTS(CSPReportRedirectSink, nsIChannelEventSink,
                   nsIInterfaceRequestor);
 
--- a/dom/security/test/unit/test_csp_upgrade_insecure_request_header.js
+++ b/dom/security/test/unit/test_csp_upgrade_insecure_request_header.js
@@ -40,21 +40,21 @@ var tests = [
     contentType: Ci.nsIContentPolicy.TYPE_IMAGE,
   },
 ];
 
 function ChannelListener() {
 }
 
 ChannelListener.prototype = {
-  onStartRequest(request) { },
-  onDataAvailable(request, stream, offset, count) {
+  onStartRequest(request, context) { },
+  onDataAvailable(request, context, stream, offset, count) {
     do_throw("Should not get any data!");
   },
-  onStopRequest(request, status) {
+  onStopRequest(request, context, status) {
     var upgrade_insecure_header = false;
     try {
       if (request.getRequestHeader("Upgrade-Insecure-Requests")) {
         upgrade_insecure_header = true;
       }
     } catch (e) {
       // exception is thrown if header is not available on the request
     }
--- a/dom/serviceworkers/ServiceWorkerScriptCache.cpp
+++ b/dom/serviceworkers/ServiceWorkerScriptCache.cpp
@@ -784,17 +784,17 @@ void CompareNetwork::Abort() {
     if (mCC) {
       mCC->Abort();
       mCC = nullptr;
     }
   }
 }
 
 NS_IMETHODIMP
-CompareNetwork::OnStartRequest(nsIRequest* aRequest) {
+CompareNetwork::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext) {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (mState == Finished) {
     return NS_OK;
   }
 
   nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
   MOZ_ASSERT_IF(mIsMainScript, channel == mChannel);
@@ -838,17 +838,17 @@ nsresult CompareNetwork::SetPrincipalInf
     return rv;
   }
 
   mPrincipalInfo = std::move(principalInfo);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-CompareNetwork::OnStopRequest(nsIRequest* aRequest,
+CompareNetwork::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
                               nsresult aStatusCode) {
   // Nothing to do here!
   return NS_OK;
 }
 
 NS_IMETHODIMP
 CompareNetwork::OnStreamComplete(nsIStreamLoader* aLoader,
                                  nsISupports* aContext, nsresult aStatus,
--- a/dom/webbrowserpersist/nsWebBrowserPersist.cpp
+++ b/dom/webbrowserpersist/nsWebBrowserPersist.cpp
@@ -729,17 +729,18 @@ nsWebBrowserPersist::OnWrite::OnFinish(n
                         &nsWebBrowserPersist::SerializeNextFile));
   return NS_OK;
 }
 
 //*****************************************************************************
 // nsWebBrowserPersist::nsIRequestObserver
 //*****************************************************************************
 
-NS_IMETHODIMP nsWebBrowserPersist::OnStartRequest(nsIRequest *request) {
+NS_IMETHODIMP nsWebBrowserPersist::OnStartRequest(nsIRequest *request,
+                                                  nsISupports *ctxt) {
   if (mProgressListener) {
     uint32_t stateFlags = nsIWebProgressListener::STATE_START |
                           nsIWebProgressListener::STATE_IS_REQUEST;
     if (!mSavingDocument) {
       stateFlags |= nsIWebProgressListener::STATE_IS_NETWORK;
     }
     mProgressListener->OnStateChange(nullptr, request, stateFlags, NS_OK);
   }
@@ -824,16 +825,17 @@ NS_IMETHODIMP nsWebBrowserPersist::OnSta
       request->Cancel(NS_BINDING_ABORTED);
     }
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP nsWebBrowserPersist::OnStopRequest(nsIRequest *request,
+                                                 nsISupports *ctxt,
                                                  nsresult status) {
   nsCOMPtr<nsISupports> keyPtr = do_QueryInterface(request);
   OutputData *data = mOutputMap.Get(keyPtr);
   if (data) {
     if (NS_SUCCEEDED(mPersistResult) && NS_FAILED(status)) {
       SendErrorStatusChange(true, status, request, data->mFile);
     }
 
@@ -862,17 +864,17 @@ NS_IMETHODIMP nsWebBrowserPersist::OnSto
   return NS_OK;
 }
 
 //*****************************************************************************
 // nsWebBrowserPersist::nsIStreamListener
 //*****************************************************************************
 
 NS_IMETHODIMP
-nsWebBrowserPersist::OnDataAvailable(nsIRequest *request,
+nsWebBrowserPersist::OnDataAvailable(nsIRequest *request, nsISupports *aContext,
                                      nsIInputStream *aIStream, uint64_t aOffset,
                                      uint32_t aLength) {
   bool cancel = mCancel;
   if (!cancel) {
     nsresult rv = NS_OK;
     uint32_t bytesRemaining = aLength;
 
     nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
--- a/dom/workers/ScriptLoader.cpp
+++ b/dom/workers/ScriptLoader.cpp
@@ -527,20 +527,20 @@ class LoaderListener final : public nsIS
   }
 
   NS_IMETHOD
   OnStreamComplete(nsIStreamLoader* aLoader, nsISupports* aContext,
                    nsresult aStatus, uint32_t aStringLen,
                    const uint8_t* aString) override;
 
   NS_IMETHOD
-  OnStartRequest(nsIRequest* aRequest) override;
+  OnStartRequest(nsIRequest* aRequest, nsISupports* aContext) override;
 
   NS_IMETHOD
-  OnStopRequest(nsIRequest* aRequest,
+  OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
                 nsresult aStatusCode) override {
     // Nothing to do here!
     return NS_OK;
   }
 
  private:
   ~LoaderListener() {}
 
@@ -1395,17 +1395,17 @@ NS_IMETHODIMP
 LoaderListener::OnStreamComplete(nsIStreamLoader* aLoader,
                                  nsISupports* aContext, nsresult aStatus,
                                  uint32_t aStringLen, const uint8_t* aString) {
   return mRunnable->OnStreamComplete(aLoader, mIndex, aStatus, aStringLen,
                                      aString);
 }
 
 NS_IMETHODIMP
-LoaderListener::OnStartRequest(nsIRequest* aRequest) {
+LoaderListener::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext) {
   return mRunnable->OnStartRequest(aRequest, mIndex);
 }
 
 void CachePromiseHandler::ResolvedCallback(JSContext* aCx,
                                            JS::Handle<JS::Value> aValue) {
   AssertIsOnMainThread();
   // May already have been canceled by CacheScriptLoader::Fail from
   // CancelMainThread.
--- a/dom/xbl/nsXBLService.cpp
+++ b/dom/xbl/nsXBLService.cpp
@@ -171,27 +171,27 @@ nsXBLStreamListener::nsXBLStreamListener
 nsXBLStreamListener::~nsXBLStreamListener() {
   for (uint32_t i = 0; i < mBindingRequests.Length(); i++) {
     nsXBLBindingRequest* req = mBindingRequests.ElementAt(i);
     delete req;
   }
 }
 
 NS_IMETHODIMP
-nsXBLStreamListener::OnDataAvailable(nsIRequest* request,
+nsXBLStreamListener::OnDataAvailable(nsIRequest* request, nsISupports* aCtxt,
                                      nsIInputStream* aInStr,
                                      uint64_t aSourceOffset, uint32_t aCount) {
   if (mInner)
-    return mInner->OnDataAvailable(request, aInStr, aSourceOffset,
+    return mInner->OnDataAvailable(request, aCtxt, aInStr, aSourceOffset,
                                    aCount);
   return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
-nsXBLStreamListener::OnStartRequest(nsIRequest* request) {
+nsXBLStreamListener::OnStartRequest(nsIRequest* request, nsISupports* aCtxt) {
   // Make sure we don't hold on to the sink and binding document past this point
   nsCOMPtr<nsIXMLContentSink> sink;
   mSink.swap(sink);
   nsCOMPtr<Document> doc;
   mBindingDocument.swap(doc);
 
   nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
   NS_ENSURE_TRUE(channel, NS_ERROR_UNEXPECTED);
@@ -203,25 +203,25 @@ nsXBLStreamListener::OnStartRequest(nsIR
       doc->StartDocumentLoad("loadAsInteractiveData", channel, group, nullptr,
                              getter_AddRefs(mInner), true, sink);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Make sure to add ourselves as a listener after StartDocumentLoad,
   // since that resets the event listners on the document.
   doc->AddEventListener(NS_LITERAL_STRING("load"), this, false);
 
-  return mInner->OnStartRequest(request);
+  return mInner->OnStartRequest(request, aCtxt);
 }
 
 NS_IMETHODIMP
-nsXBLStreamListener::OnStopRequest(nsIRequest* request,
+nsXBLStreamListener::OnStopRequest(nsIRequest* request, nsISupports* aCtxt,
                                    nsresult aStatus) {
   nsresult rv = NS_OK;
   if (mInner) {
-    rv = mInner->OnStopRequest(request, aStatus);
+    rv = mInner->OnStopRequest(request, aCtxt, aStatus);
   }
 
   // Don't hold onto the inner listener; holding onto it can create a cycle
   // with the document
   mInner = nullptr;
 
   return rv;
 }
--- a/dom/xhr/XMLHttpRequestMainThread.cpp
+++ b/dom/xhr/XMLHttpRequestMainThread.cpp
@@ -1544,17 +1544,17 @@ nsresult XMLHttpRequestMainThread::Strea
     nsCOMPtr<nsIInputStream> copyStream;
     rv = NS_NewByteInputStream(getter_AddRefs(copyStream), fromRawSegment,
                                count);
 
     if (NS_SUCCEEDED(rv) && xmlHttpRequest->mXMLParserStreamListener) {
       NS_ASSERTION(copyStream, "NS_NewByteInputStream lied");
       nsresult parsingResult =
           xmlHttpRequest->mXMLParserStreamListener->OnDataAvailable(
-              xmlHttpRequest->mChannel, copyStream,
+              xmlHttpRequest->mChannel, xmlHttpRequest->mContext, copyStream,
               toOffset, count);
 
       // No use to continue parsing if we failed here, but we
       // should still finish reading the stream
       if (NS_FAILED(parsingResult)) {
         xmlHttpRequest->mFlagParseBody = false;
       }
     }
@@ -1674,21 +1674,25 @@ void XMLHttpRequestMainThread::LocalFile
   mBlobStorage = nullptr;
   NS_ASSERTION(mResponseBody.IsEmpty(), "mResponseBody should be empty");
 
   ChangeStateToDone();
 }
 
 NS_IMETHODIMP
 XMLHttpRequestMainThread::OnDataAvailable(nsIRequest* request,
+                                          nsISupports* ctxt,
                                           nsIInputStream* inStr,
                                           uint64_t sourceOffset,
                                           uint32_t count) {
   NS_ENSURE_ARG_POINTER(inStr);
 
+  MOZ_ASSERT(mContext.get() == ctxt,
+             "start context different from OnDataAvailable context");
+
   mProgressSinceLastProgressEvent = true;
   XMLHttpRequest_Binding::ClearCachedResponseTextValue(this);
 
   nsresult rv;
 
   if (mResponseType == XMLHttpRequestResponseType::Blob) {
     nsCOMPtr<nsIFile> localFile;
     nsCOMPtr<nsIURI> blobURI;
@@ -1749,23 +1753,24 @@ XMLHttpRequestMainThread::OnDataAvailabl
   if (!mFlagSynchronous && !mProgressTimerIsActive) {
     StartProgressEventTimer();
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-XMLHttpRequestMainThread::OnStartRequest(nsIRequest* request) {
+XMLHttpRequestMainThread::OnStartRequest(nsIRequest* request,
+                                         nsISupports* ctxt) {
   AUTO_PROFILER_LABEL("XMLHttpRequestMainThread::OnStartRequest", NETWORK);
 
   nsresult rv = NS_OK;
   if (!mFirstStartRequestSeen && mRequestObserver) {
     mFirstStartRequestSeen = true;
-    mRequestObserver->OnStartRequest(request);
+    mRequestObserver->OnStartRequest(request, ctxt);
   }
 
   if (request != mChannel) {
     // Can this still happen?
     return NS_OK;
   }
 
   // Don't do anything if we have been aborted
@@ -1808,16 +1813,17 @@ XMLHttpRequestMainThread::OnStartRequest
       mProgressSinceLastProgressEvent = false;
     }
 
     mUploadComplete = true;
     DispatchProgressEvent(mUpload, ProgressEventType::load, mUploadTotal,
                           mUploadTotal);
   }
 
+  mContext = ctxt;
   mFlagParseBody = true;
   ChangeState(XMLHttpRequest_Binding::HEADERS_RECEIVED);
 
   ResetResponse();
 
   if (!mOverrideMimeType.IsEmpty()) {
     channel->SetContentType(NS_ConvertUTF16toUTF8(mOverrideMimeType));
   }
@@ -1999,30 +2005,30 @@ XMLHttpRequestMainThread::OnStartRequest
                                          nullptr, getter_AddRefs(listener),
                                          !isCrossSite);
     NS_ENSURE_SUCCESS(rv, rv);
 
     // the spec requires the response document.referrer to be the empty string
     mResponseXML->SetReferrer(NS_LITERAL_CSTRING(""));
 
     mXMLParserStreamListener = listener;
-    rv = mXMLParserStreamListener->OnStartRequest(request);
+    rv = mXMLParserStreamListener->OnStartRequest(request, ctxt);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   // Download phase beginning; start the progress event timer if necessary.
   if (NS_SUCCEEDED(rv) && HasListenersFor(nsGkAtoms::onprogress)) {
     StartProgressEventTimer();
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-XMLHttpRequestMainThread::OnStopRequest(nsIRequest* request,
+XMLHttpRequestMainThread::OnStopRequest(nsIRequest* request, nsISupports* ctxt,
                                         nsresult status) {
   AUTO_PROFILER_LABEL("XMLHttpRequestMainThread::OnStopRequest", NETWORK);
 
   if (request != mChannel) {
     // Can this still happen?
     return NS_OK;
   }
 
@@ -2035,31 +2041,31 @@ XMLHttpRequestMainThread::OnStopRequest(
     AppendToResponseText(Span<const uint8_t>(), true);
   }
 
   mWaitingForOnStopRequest = false;
 
   if (mRequestObserver) {
     NS_ASSERTION(mFirstStartRequestSeen, "Inconsistent state!");
     mFirstStartRequestSeen = false;
-    mRequestObserver->OnStopRequest(request, status);
+    mRequestObserver->OnStopRequest(request, ctxt, status);
   }
 
   // make sure to notify the listener if we were aborted
   // XXX in fact, why don't we do the cleanup below in this case??
   // UNSENT is for abort calls.  See OnStartRequest above.
   if (mState == XMLHttpRequest_Binding::UNSENT || mFlagTimedOut) {
     if (mXMLParserStreamListener)
-      (void)mXMLParserStreamListener->OnStopRequest(request, status);
+      (void)mXMLParserStreamListener->OnStopRequest(request, ctxt, status);
     return NS_OK;
   }
 
   // Is this good enough here?
   if (mXMLParserStreamListener && mFlagParseBody) {
-    mXMLParserStreamListener->OnStopRequest(request, status);
+    mXMLParserStreamListener->OnStopRequest(request, ctxt, status);
   }
 
   mXMLParserStreamListener = nullptr;
   mContext = nullptr;
 
   // If window.stop() or other aborts were issued, handle as an abort
   if (status == NS_BINDING_ABORTED) {
     mFlagParseBody = false;
--- a/dom/xslt/xslt/txMozillaStylesheetCompiler.cpp
+++ b/dom/xslt/xslt/txMozillaStylesheetCompiler.cpp
@@ -192,17 +192,17 @@ txStylesheetSink::ReportError(const char
 }
 
 NS_IMETHODIMP
 txStylesheetSink::DidBuildModel(bool aTerminated) {
   return mCompiler->doneLoading();
 }
 
 NS_IMETHODIMP
-txStylesheetSink::OnDataAvailable(nsIRequest* aRequest,
+txStylesheetSink::OnDataAvailable(nsIRequest* aRequest, nsISupports* aContext,
                                   nsIInputStream* aInputStream,
                                   uint64_t aOffset, uint32_t aCount) {
   if (!mCheckedForXML) {
     nsCOMPtr<nsIDTD> dtd;
     mParser->GetDTD(getter_AddRefs(dtd));
     if (dtd) {
       mCheckedForXML = true;
       if (!(dtd->GetType() & NS_IPARSER_FLAG_XML)) {
@@ -211,22 +211,22 @@ txStylesheetSink::OnDataAvailable(nsIReq
         getSpec(channel, spec);
         mCompiler->cancel(NS_ERROR_XSLT_WRONG_MIME_TYPE, nullptr, spec.get());
 
         return NS_ERROR_XSLT_WRONG_MIME_TYPE;
       }
     }
   }
 
-  return mListener->OnDataAvailable(aRequest, aInputStream, aOffset,
+  return mListener->OnDataAvailable(aRequest, mParser, aInputStream, aOffset,
                                     aCount);
 }
 
 NS_IMETHODIMP
-txStylesheetSink::OnStartRequest(nsIRequest* aRequest) {
+txStylesheetSink::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext) {
   int32_t charsetSource = kCharsetFromDocTypeDefault;
 
   nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
 
   // check channel's charset...
   const Encoding* encoding = nullptr;
   nsAutoCString charsetVal;
   if (NS_SUCCEEDED(channel->GetContentCharset(charsetVal))) {
@@ -260,21 +260,21 @@ txStylesheetSink::OnStartRequest(nsIRequ
       rv = serv->AsyncConvertData(UNKNOWN_CONTENT_TYPE, "*/*", mListener,
                                   mParser, getter_AddRefs(converter));
       if (NS_SUCCEEDED(rv)) {
         mListener = converter;
       }
     }
   }
 
-  return mListener->OnStartRequest(aRequest);
+  return mListener->OnStartRequest(aRequest, mParser);
 }
 
 NS_IMETHODIMP
-txStylesheetSink::OnStopRequest(nsIRequest* aRequest,
+txStylesheetSink::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
                                 nsresult aStatusCode) {
   bool success = true;
 
   nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aRequest);
   if (httpChannel) {
     Unused << httpChannel->GetRequestSucceeded(&success);
   }
 
@@ -294,17 +294,17 @@ txStylesheetSink::OnStopRequest(nsIReque
 
   if (NS_FAILED(result)) {
     nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
     nsAutoString spec;
     getSpec(channel, spec);
     mCompiler->cancel(result, nullptr, spec.get());
   }
 
-  nsresult rv = mListener->OnStopRequest(aRequest, aStatusCode);
+  nsresult rv = mListener->OnStopRequest(aRequest, mParser, aStatusCode);
   mListener = nullptr;
   mParser = nullptr;
   return rv;
 }
 
 NS_IMETHODIMP
 txStylesheetSink::GetInterface(const nsIID& aIID, void** aResult) {
   if (aIID.Equals(NS_GET_IID(nsIAuthPrompt))) {
--- a/dom/xul/XULDocument.cpp
+++ b/dom/xul/XULDocument.cpp
@@ -1368,30 +1368,33 @@ XULDocument::CachedChromeStreamListener:
     : mDocument(aDocument), mProtoLoaded(aProtoLoaded) {}
 
 XULDocument::CachedChromeStreamListener::~CachedChromeStreamListener() {}
 
 NS_IMPL_ISUPPORTS(XULDocument::CachedChromeStreamListener, nsIRequestObserver,
                   nsIStreamListener)
 
 NS_IMETHODIMP
-XULDocument::CachedChromeStreamListener::OnStartRequest(nsIRequest* request) {
+XULDocument::CachedChromeStreamListener::OnStartRequest(nsIRequest* request,
+                                                        nsISupports* acontext) {
   return NS_ERROR_PARSED_DATA_CACHED;
 }
 
 NS_IMETHODIMP
 XULDocument::CachedChromeStreamListener::OnStopRequest(nsIRequest* request,
+                                                       nsISupports* aContext,
                                                        nsresult aStatus) {
   if (!mProtoLoaded) return NS_OK;
 
   return mDocument->OnPrototypeLoadDone(true);
 }
 
 NS_IMETHODIMP
 XULDocument::CachedChromeStreamListener::OnDataAvailable(nsIRequest* request,
+                                                         nsISupports* aContext,
                                                          nsIInputStream* aInStr,
                                                          uint64_t aSourceOffset,
                                                          uint32_t aCount) {
   MOZ_ASSERT_UNREACHABLE("CachedChromeStream doesn't receive data");
   return NS_ERROR_UNEXPECTED;
 }
 
 bool XULDocument::IsDocumentRightToLeft() {
--- a/extensions/pref/autoconfig/src/nsAutoConfig.cpp
+++ b/extensions/pref/autoconfig/src/nsAutoConfig.cpp
@@ -57,22 +57,22 @@ nsresult nsAutoConfig::Init() {
 
 nsAutoConfig::~nsAutoConfig() {}
 
 void nsAutoConfig::SetConfigURL(const char *aConfigURL) {
   mConfigURL.Assign(aConfigURL);
 }
 
 NS_IMETHODIMP
-nsAutoConfig::OnStartRequest(nsIRequest *request) {
+nsAutoConfig::OnStartRequest(nsIRequest *request, nsISupports *context) {
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsAutoConfig::OnDataAvailable(nsIRequest *request,
+nsAutoConfig::OnDataAvailable(nsIRequest *request, nsISupports *context,
                               nsIInputStream *aIStream, uint64_t aSourceOffset,
                               uint32_t aLength) {
   uint32_t amt, size;
   nsresult rv;
   char buf[1024];
 
   while (aLength) {
     size = std::min<size_t>(aLength, sizeof(buf));
@@ -80,17 +80,17 @@ nsAutoConfig::OnDataAvailable(nsIRequest
     if (NS_FAILED(rv)) return rv;
     mBuf.Append(buf, amt);
     aLength -= amt;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsAutoConfig::OnStopRequest(nsIRequest *request,
+nsAutoConfig::OnStopRequest(nsIRequest *request, nsISupports *context,
                             nsresult aStatus) {
   nsresult rv;
 
   // If the request is failed, go read the failover.jsc file
   if (NS_FAILED(aStatus)) {
     MOZ_LOG(MCD, LogLevel::Debug,
             ("mcd request failed with status %" PRIx32 "\n",
              static_cast<uint32_t>(aStatus)));
--- a/gfx/thebes/gfxSVGGlyphs.cpp
+++ b/gfx/thebes/gfxSVGGlyphs.cpp
@@ -357,33 +357,33 @@ nsresult gfxSVGGlyphsDocument::ParseDocu
   rv = document->StartDocumentLoad("external-resource", channel,
                                    nullptr,  // aLoadGroup
                                    nullptr,  // aContainer
                                    getter_AddRefs(listener), true /* aReset */);
   if (NS_FAILED(rv) || !listener) {
     return NS_ERROR_FAILURE;
   }
 
-  rv = listener->OnStartRequest(channel);
+  rv = listener->OnStartRequest(channel, nullptr /* aContext */);
   if (NS_FAILED(rv)) {
     channel->Cancel(rv);
   }
 
   nsresult status;
   channel->GetStatus(&status);
   if (NS_SUCCEEDED(rv) && NS_SUCCEEDED(status)) {
-    rv = listener->OnDataAvailable(channel, stream, 0,
+    rv = listener->OnDataAvailable(channel, nullptr /* aContext */, stream, 0,
                                    aBufLen);
     if (NS_FAILED(rv)) {
       channel->Cancel(rv);
     }
     channel->GetStatus(&status);
   }
 
-  rv = listener->OnStopRequest(channel, status);
+  rv = listener->OnStopRequest(channel, nullptr /* aContext */, status);
   NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
 
   document.swap(mDocument);
 
   return NS_OK;
 }
 
 void gfxSVGGlyphsDocument::InsertGlyphId(Element *aGlyphElement) {
--- a/image/ImageFactory.cpp
+++ b/image/ImageFactory.cpp
@@ -259,17 +259,17 @@ uint32_t GetContentSize(nsIRequest* aReq
 
   rv = newImage->Init(aMimeType.get(), aImageFlags);
   if (NS_FAILED(rv)) {
     return BadImage("VectorImage::Init failed", newImage);
   }
 
   newImage->SetInnerWindowID(aInnerWindowId);
 
-  rv = newImage->OnStartRequest(aRequest);
+  rv = newImage->OnStartRequest(aRequest, nullptr);
   if (NS_FAILED(rv)) {
     return BadImage("VectorImage::OnStartRequest failed", newImage);
   }
 
   return newImage.forget();
 }
 
 }  // namespace image
--- a/image/SVGDocumentWrapper.cpp
+++ b/image/SVGDocumentWrapper.cpp
@@ -183,47 +183,47 @@ void SVGDocumentWrapper::TickRefreshDriv
       presContext->RefreshDriver()->DoTick();
     }
   }
 }
 
 /** nsIStreamListener methods **/
 
 NS_IMETHODIMP
-SVGDocumentWrapper::OnDataAvailable(nsIRequest* aRequest,
+SVGDocumentWrapper::OnDataAvailable(nsIRequest* aRequest, nsISupports* ctxt,
                                     nsIInputStream* inStr,
                                     uint64_t sourceOffset, uint32_t count) {
-  return mListener->OnDataAvailable(aRequest, inStr, sourceOffset, count);
+  return mListener->OnDataAvailable(aRequest, ctxt, inStr, sourceOffset, count);
 }
 
 /** nsIRequestObserver methods **/
 
 NS_IMETHODIMP
-SVGDocumentWrapper::OnStartRequest(nsIRequest* aRequest) {
+SVGDocumentWrapper::OnStartRequest(nsIRequest* aRequest, nsISupports* ctxt) {
   nsresult rv = SetupViewer(aRequest, getter_AddRefs(mViewer),
                             getter_AddRefs(mLoadGroup));
 
   if (NS_SUCCEEDED(rv) &&
-      NS_SUCCEEDED(mListener->OnStartRequest(aRequest))) {
+      NS_SUCCEEDED(mListener->OnStartRequest(aRequest, nullptr))) {
     mViewer->GetDocument()->SetIsBeingUsedAsImage();
     StopAnimation();  // otherwise animations start automatically in helper doc
 
     rv = mViewer->Init(nullptr, nsIntRect(0, 0, 0, 0));
     if (NS_SUCCEEDED(rv)) {
       rv = mViewer->Open(nullptr, nullptr);
     }
   }
   return rv;
 }
 
 NS_IMETHODIMP
-SVGDocumentWrapper::OnStopRequest(nsIRequest* aRequest,
+SVGDocumentWrapper::OnStopRequest(nsIRequest* aRequest, nsISupports* ctxt,
                                   nsresult status) {
   if (mListener) {
-    mListener->OnStopRequest(aRequest, status);
+    mListener->OnStopRequest(aRequest, ctxt, status);
     mListener = nullptr;
   }
 
   return NS_OK;
 }
 
 /** nsIObserver Methods **/
 NS_IMETHODIMP
--- a/image/VectorImage.cpp
+++ b/image/VectorImage.cpp
@@ -420,17 +420,17 @@ void VectorImage::CollectSizeOfSurfaces(
   SurfaceCache::CollectSizeOfSurfaces(ImageKey(this), aCounters, aMallocSizeOf);
 }
 
 nsresult VectorImage::OnImageDataComplete(nsIRequest* aRequest,
                                           nsISupports* aContext,
                                           nsresult aStatus, bool aLastPart) {
   // Call our internal OnStopRequest method, which only talks to our embedded
   // SVG document. This won't have any effect on our ProgressTracker.
-  nsresult finalStatus = OnStopRequest(aRequest, aStatus);
+  nsresult finalStatus = OnStopRequest(aRequest, aContext, aStatus);
 
   // Give precedence to Necko failure codes.
   if (NS_FAILED(aStatus)) {
     finalStatus = aStatus;
   }
 
   Progress loadProgress = LoadCompleteProgress(aLastPart, mError, finalStatus);
 
@@ -446,17 +446,17 @@ nsresult VectorImage::OnImageDataComplet
   return finalStatus;
 }
 
 nsresult VectorImage::OnImageDataAvailable(nsIRequest* aRequest,
                                            nsISupports* aContext,
                                            nsIInputStream* aInStr,
                                            uint64_t aSourceOffset,
                                            uint32_t aCount) {
-  return OnDataAvailable(aRequest, aInStr, aSourceOffset, aCount);
+  return OnDataAvailable(aRequest, aContext, aInStr, aSourceOffset, aCount);
 }
 
 nsresult VectorImage::StartAnimation() {
   if (mError) {
     return NS_ERROR_FAILURE;
   }
 
   MOZ_ASSERT(ShouldAnimate(), "Should not animate!");
@@ -1335,22 +1335,22 @@ VectorImage::GetFrameIndex(uint32_t aWhi
              : mSVGDocumentWrapper->GetCurrentTimeAsFloat();
 }
 
 //------------------------------------------------------------------------------
 // nsIRequestObserver methods
 
 //******************************************************************************
 NS_IMETHODIMP
-VectorImage::OnStartRequest(nsIRequest* aRequest) {
+VectorImage::OnStartRequest(nsIRequest* aRequest, nsISupports* aCtxt) {
   MOZ_ASSERT(!mSVGDocumentWrapper,
              "Repeated call to OnStartRequest -- can this happen?");
 
   mSVGDocumentWrapper = new SVGDocumentWrapper();
-  nsresult rv = mSVGDocumentWrapper->OnStartRequest(aRequest);
+  nsresult rv = mSVGDocumentWrapper->OnStartRequest(aRequest, aCtxt);
   if (NS_FAILED(rv)) {
     mSVGDocumentWrapper = nullptr;
     mError = true;
     return rv;
   }
 
   // Create a listener to wait until the SVG document is fully loaded, which
   // will signal that this image is ready to render. Certain error conditions
@@ -1362,23 +1362,23 @@ VectorImage::OnStartRequest(nsIRequest* 
   mLoadEventListener = new SVGLoadEventListener(document, this);
   mParseCompleteListener = new SVGParseCompleteListener(document, this);
 
   return NS_OK;
 }
 
 //******************************************************************************
 NS_IMETHODIMP
-VectorImage::OnStopRequest(nsIRequest* aRequest,
+VectorImage::OnStopRequest(nsIRequest* aRequest, nsISupports* aCtxt,
                            nsresult aStatus) {
   if (mError) {
     return NS_ERROR_FAILURE;
   }
 
-  return mSVGDocumentWrapper->OnStopRequest(aRequest, aStatus);
+  return mSVGDocumentWrapper->OnStopRequest(aRequest, aCtxt, aStatus);
 }
 
 void VectorImage::OnSVGDocumentParsed() {
   MOZ_ASSERT(mParseCompleteListener, "Should have the parse complete listener");
   MOZ_ASSERT(mLoadEventListener, "Should have the load event listener");
 
   if (!mSVGDocumentWrapper->GetRootSVGElem()) {
     // This is an invalid SVG document. It may have failed to parse, or it may
@@ -1463,24 +1463,24 @@ void VectorImage::OnSVGDocumentError() {
   }
 }
 
 //------------------------------------------------------------------------------
 // nsIStreamListener method
 
 //******************************************************************************
 NS_IMETHODIMP
-VectorImage::OnDataAvailable(nsIRequest* aRequest,
+VectorImage::OnDataAvailable(nsIRequest* aRequest, nsISupports* aCtxt,
                              nsIInputStream* aInStr, uint64_t aSourceOffset,
                              uint32_t aCount) {
   if (mError) {
     return NS_ERROR_FAILURE;
   }
 
-  return mSVGDocumentWrapper->OnDataAvailable(aRequest, aInStr,
+  return mSVGDocumentWrapper->OnDataAvailable(aRequest, aCtxt, aInStr,
                                               aSourceOffset, aCount);
 }
 
 // --------------------------
 // Invalidation helper method
 
 void VectorImage::InvalidateObserversOnNextRefreshDriverTick() {
   if (mHasPendingInvalidation) {
--- a/image/decoders/icon/mac/nsIconChannelCocoa.mm
+++ b/image/decoders/icon/mac/nsIconChannelCocoa.mm
@@ -69,44 +69,44 @@ nsIconChannel::Cancel(nsresult status) {
 NS_IMETHODIMP
 nsIconChannel::Suspend(void) { return mPump->Suspend(); }
 
 NS_IMETHODIMP
 nsIconChannel::Resume(void) { return mPump->Resume(); }
 
 // nsIRequestObserver methods
 NS_IMETHODIMP
-nsIconChannel::OnStartRequest(nsIRequest* aRequest) {
+nsIconChannel::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext) {
   if (mListener) {
-    return mListener->OnStartRequest(this);
+    return mListener->OnStartRequest(this, aContext);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsIconChannel::OnStopRequest(nsIRequest* aRequest, nsresult aStatus) {
+nsIconChannel::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext, nsresult aStatus) {
   if (mListener) {
-    mListener->OnStopRequest(this, aStatus);
+    mListener->OnStopRequest(this, aContext, aStatus);
     mListener = nullptr;
   }
 
   // Remove from load group
   if (mLoadGroup) {
     mLoadGroup->RemoveRequest(this, nullptr, aStatus);
   }
 
   return NS_OK;
 }
 
 // nsIStreamListener methods
 NS_IMETHODIMP
-nsIconChannel::OnDataAvailable(nsIRequest* aRequest, nsIInputStream* aStream,
+nsIconChannel::OnDataAvailable(nsIRequest* aRequest, nsISupports* aContext, nsIInputStream* aStream,
                                uint64_t aOffset, uint32_t aCount) {
   if (mListener) {
-    return mListener->OnDataAvailable(this, aStream, aOffset, aCount);
+    return mListener->OnDataAvailable(this, aContext, aStream, aOffset, aCount);
   }
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIChannel methods:
 
 NS_IMETHODIMP
--- a/image/decoders/icon/win/nsIconChannel.cpp
+++ b/image/decoders/icon/win/nsIconChannel.cpp
@@ -701,44 +701,45 @@ nsIconChannel::SetNotificationCallbacks(
 
 NS_IMETHODIMP
 nsIconChannel::GetSecurityInfo(nsISupports** aSecurityInfo) {
   *aSecurityInfo = nullptr;
   return NS_OK;
 }
 
 // nsIRequestObserver methods
-NS_IMETHODIMP nsIconChannel::OnStartRequest(nsIRequest* aRequest) {
+NS_IMETHODIMP nsIconChannel::OnStartRequest(nsIRequest* aRequest,
+                                            nsISupports* aContext) {
   if (mListener) {
-    return mListener->OnStartRequest(this);
+    return mListener->OnStartRequest(this, aContext);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsIconChannel::OnStopRequest(nsIRequest* aRequest,
+nsIconChannel::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
                              nsresult aStatus) {
   if (mListener) {
-    mListener->OnStopRequest(this, aStatus);
+    mListener->OnStopRequest(this, aContext, aStatus);
     mListener = nullptr;
   }
 
   // Remove from load group
   if (mLoadGroup) {
     mLoadGroup->RemoveRequest(this, nullptr, aStatus);
   }
 
   // Drop notification callbacks to prevent cycles.
   mCallbacks = nullptr;
 
   return NS_OK;
 }
 
 // nsIStreamListener methods
 NS_IMETHODIMP
-nsIconChannel::OnDataAvailable(nsIRequest* aRequest,
+nsIconChannel::OnDataAvailable(nsIRequest* aRequest, nsISupports* aContext,
                                nsIInputStream* aStream, uint64_t aOffset,
                                uint32_t aCount) {
   if (mListener) {
-    return mListener->OnDataAvailable(this, aStream, aOffset, aCount);
+    return mListener->OnDataAvailable(this, aContext, aStream, aOffset, aCount);
   }
   return NS_OK;
 }
--- a/image/imgLoader.cpp
+++ b/image/imgLoader.cpp
@@ -2638,17 +2638,17 @@ ProxyListener::ProxyListener(nsIStreamLi
 }
 
 ProxyListener::~ProxyListener() { /* destructor code */
 }
 
 /** nsIRequestObserver methods **/
 
 NS_IMETHODIMP
-ProxyListener::OnStartRequest(nsIRequest* aRequest) {
+ProxyListener::OnStartRequest(nsIRequest* aRequest, nsISupports* ctxt) {
   if (!mDestListener) {
     return NS_ERROR_FAILURE;
   }
 
   nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest));
   if (channel) {
     // We need to set the initiator type for the image load
     nsCOMPtr<nsITimedChannel> timedChannel = do_QueryInterface(channel);
@@ -2681,40 +2681,40 @@ ProxyListener::OnStartRequest(nsIRequest
           if (NS_SUCCEEDED(rv)) {
             mDestListener = fromListener;
           }
         }
       }
     }
   }
 
-  return mDestListener->OnStartRequest(aRequest);
+  return mDestListener->OnStartRequest(aRequest, ctxt);
 }
 
 NS_IMETHODIMP
-ProxyListener::OnStopRequest(nsIRequest* aRequest,
+ProxyListener::OnStopRequest(nsIRequest* aRequest, nsISupports* ctxt,
                              nsresult status) {
   if (!mDestListener) {
     return NS_ERROR_FAILURE;
   }
 
-  return mDestListener->OnStopRequest(aRequest, status);
+  return mDestListener->OnStopRequest(aRequest, ctxt, status);
 }
 
 /** nsIStreamListener methods **/
 
 NS_IMETHODIMP
-ProxyListener::OnDataAvailable(nsIRequest* aRequest,
+ProxyListener::OnDataAvailable(nsIRequest* aRequest, nsISupports* ctxt,
                                nsIInputStream* inStr, uint64_t sourceOffset,
                                uint32_t count) {
   if (!mDestListener) {
     return NS_ERROR_FAILURE;
   }
 
-  return mDestListener->OnDataAvailable(aRequest, inStr, sourceOffset,
+  return mDestListener->OnDataAvailable(aRequest, ctxt, inStr, sourceOffset,
                                         count);
 }
 
 /** nsThreadRetargetableStreamListener methods **/
 NS_IMETHODIMP
 ProxyListener::CheckListenerChain() {
   NS_ASSERTION(NS_IsMainThread(), "Should be on the main thread!");
   nsresult rv = NS_OK;
@@ -2827,17 +2827,17 @@ void imgCacheValidator::UpdateProxies(bo
       proxy->NotifyListener();
     }
   }
 }
 
 /** nsIRequestObserver methods **/
 
 NS_IMETHODIMP
-imgCacheValidator::OnStartRequest(nsIRequest* aRequest) {
+imgCacheValidator::OnStartRequest(nsIRequest* aRequest, nsISupports* ctxt) {
   // We may be holding on to a document, so ensure that it's released.
   nsCOMPtr<nsISupports> context = mContext.forget();
 
   // If for some reason we don't still have an existing request (probably
   // because OnStartRequest got delivered more than once), just bail.
   if (!mRequest) {
     MOZ_ASSERT_UNREACHABLE("OnStartRequest delivered more than once?");
     aRequest->Cancel(NS_BINDING_ABORTED);
@@ -2907,46 +2907,46 @@ imgCacheValidator::OnStartRequest(nsIReq
 
   mDestListener = new ProxyListener(mNewRequest);
 
   // Try to add the new request into the cache. Note that the entry must be in
   // the cache before the proxies' ownership changes, because adding a proxy
   // changes the caching behaviour for imgRequests.
   mImgLoader->PutIntoCache(mNewRequest->CacheKey(), mNewEntry);
   UpdateProxies(/* aCancelRequest */ false, /* aSyncNotify */ true);
-  return mDestListener->OnStartRequest(aRequest);
+  return mDestListener->OnStartRequest(aRequest, ctxt);
 }
 
 NS_IMETHODIMP
-imgCacheValidator::OnStopRequest(nsIRequest* aRequest,
+imgCacheValidator::OnStopRequest(nsIRequest* aRequest, nsISupports* ctxt,
                                  nsresult status) {
   // Be sure we've released the document that we may have been holding on to.
   mContext = nullptr;
 
   if (!mDestListener) {
     return NS_OK;
   }
 
-  return mDestListener->OnStopRequest(aRequest, status);
+  return mDestListener->OnStopRequest(aRequest, ctxt, status);
 }
 
 /** nsIStreamListener methods **/
 
 NS_IMETHODIMP
-imgCacheValidator::OnDataAvailable(nsIRequest* aRequest,
+imgCacheValidator::OnDataAvailable(nsIRequest* aRequest, nsISupports* ctxt,
                                    nsIInputStream* inStr, uint64_t sourceOffset,
                                    uint32_t count) {
   if (!mDestListener) {
     // XXX see bug 113959
     uint32_t _retval;
     inStr->ReadSegments(NS_DiscardSegment, nullptr, count, &_retval);
     return NS_OK;
   }
 
-  return mDestListener->OnDataAvailable(aRequest, inStr, sourceOffset,
+  return mDestListener->OnDataAvailable(aRequest, ctxt, inStr, sourceOffset,
                                         count);
 }
 
 /** nsIThreadRetargetableStreamListener methods **/
 
 NS_IMETHODIMP
 imgCacheValidator::CheckListenerChain() {
   NS_ASSERTION(NS_IsMainThread(), "Should be on the main thread!");
--- a/image/imgRequest.cpp
+++ b/image/imgRequest.cpp
@@ -640,17 +640,17 @@ bool imgRequest::GetMultipart() const {
 bool imgRequest::HadInsecureRedirect() const {
   MutexAutoLock lock(mMutex);
   return mHadInsecureRedirect;
 }
 
 /** nsIRequestObserver methods **/
 
 NS_IMETHODIMP
-imgRequest::OnStartRequest(nsIRequest* aRequest) {
+imgRequest::OnStartRequest(nsIRequest* aRequest, nsISupports* ctxt) {
   LOG_SCOPE(gImgLog, "imgRequest::OnStartRequest");
 
   RefPtr<Image> image;
 
   // Figure out if we're multipart.
   nsCOMPtr<nsIMultiPartChannel> multiPartChannel = do_QueryInterface(aRequest);
   MOZ_ASSERT(multiPartChannel || !mIsMultiPartChannel,
              "Stopped being multipart?");
@@ -730,27 +730,27 @@ imgRequest::OnStartRequest(nsIRequest* a
              this, static_cast<uint32_t>(rv),
              NS_SUCCEEDED(rv) ? "succeeded" : "failed"));
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-imgRequest::OnStopRequest(nsIRequest* aRequest,
+imgRequest::OnStopRequest(nsIRequest* aRequest, nsISupports* ctxt,
                           nsresult status) {
   LOG_FUNC(gImgLog, "imgRequest::OnStopRequest");
   MOZ_ASSERT(NS_IsMainThread(), "Can't send notifications off-main-thread");
 
   RefPtr<Image> image = GetImage();
 
   RefPtr<imgRequest> strongThis = this;
 
   if (mIsMultiPartChannel && mNewPartPending) {
-    OnDataAvailable(aRequest, nullptr, 0, 0);
+    OnDataAvailable(aRequest, ctxt, nullptr, 0, 0);
   }
 
   // XXXldb What if this is a non-last part of a multipart request?
   // xxx before we release our reference to mRequest, lets
   // save the last status that we saw so that the
   // imgRequestProxy will have access to it.
   if (mRequest) {
     mRequest = nullptr;  // we no longer need the request
@@ -774,17 +774,17 @@ imgRequest::OnStopRequest(nsIRequest* aR
     isPartial = true;
     status = NS_OK;  // fake happy face
   }
 
   // Tell the image that it has all of the source data. Note that this can
   // trigger a failure, since the image might be waiting for more non-optional
   // data and this is the point where we break the news that it's not coming.
   if (image) {
-    nsresult rv = image->OnImageDataComplete(aRequest, nullptr, status, lastPart);
+    nsresult rv = image->OnImageDataComplete(aRequest, ctxt, status, lastPart);
 
     // If we got an error in the OnImageDataComplete() call, we don't want to
     // proceed as if nothing bad happened. However, we also want to give
     // precedence to failure status codes from necko, since presumably they're
     // more meaningful.
     if (NS_FAILED(rv) && NS_SUCCEEDED(status)) {
       status = rv;
     }
@@ -984,17 +984,17 @@ void imgRequest::FinishPreparingForNewPa
   }
 
   if (IsDecodeRequested()) {
     aResult.mImage->StartDecoding(imgIContainer::FLAG_NONE);
   }
 }
 
 NS_IMETHODIMP
-imgRequest::OnDataAvailable(nsIRequest* aRequest,
+imgRequest::OnDataAvailable(nsIRequest* aRequest, nsISupports* aContext,
                             nsIInputStream* aInStr, uint64_t aOffset,
                             uint32_t aCount) {
   LOG_SCOPE_WITH_PARAM(gImgLog, "imgRequest::OnDataAvailable", "count", aCount);
 
   NS_ASSERTION(aRequest, "imgRequest::OnDataAvailable -- no request!");
 
   RefPtr<Image> image;
   RefPtr<ProgressTracker> progressTracker;
@@ -1057,17 +1057,17 @@ imgRequest::OnDataAvailable(nsIRequest* 
       // Something went wrong; probably a content type issue.
       Cancel(NS_IMAGELIB_ERROR_FAILURE);
       return NS_BINDING_ABORTED;
     }
   }
 
   // Notify the image that it has new data.
   if (aInStr) {
-    nsresult rv = image->OnImageDataAvailable(aRequest, nullptr, aInStr,
+    nsresult rv = image->OnImageDataAvailable(aRequest, aContext, aInStr,
                                               aOffset, aCount);
 
     if (NS_FAILED(rv)) {
       MOZ_LOG(gImgLog, LogLevel::Warning,
               ("[this=%p] imgRequest::OnDataAvailable -- "
                "copy to RasterImage failed\n",
                this));
       Cancel(NS_IMAGELIB_ERROR_FAILURE);
--- a/image/test/unit/image_load_helpers.js
+++ b/image/test/unit/image_load_helpers.js
@@ -78,36 +78,36 @@ function ImageListener(start_callback, s
 
 function NS_FAILED(val)
 {
   return !!(val & 0x80000000);
 }
 
 function ChannelListener()
 {
-  this.onStartRequest = function onStartRequest(aRequest)
+  this.onStartRequest = function onStartRequest(aRequest, aContext)
   {
     if (this.outputListener)
-      this.outputListener.onStartRequest(aRequest);
+      this.outputListener.onStartRequest(aRequest, aContext);
 
     this.requestStatus |= START_REQUEST;
   }
 
-  this.onDataAvailable = function onDataAvailable(aRequest, aInputStream, aOffset, aCount)
+  this.onDataAvailable = function onDataAvailable(aRequest, aContext, aInputStream, aOffset, aCount)
   {
     if (this.outputListener)
-      this.outputListener.onDataAvailable(aRequest, aInputStream, aOffset, aCount);
+      this.outputListener.onDataAvailable(aRequest, aContext, aInputStream, aOffset, aCount);
 
     this.requestStatus |= DATA_AVAILABLE;
   }
 
-  this.onStopRequest = function onStopRequest(aRequest, aStatusCode)
+  this.onStopRequest = function onStopRequest(aRequest, aContext, aStatusCode)
   {
     if (this.outputListener)
-      this.outputListener.onStopRequest(aRequest, aStatusCode);
+      this.outputListener.onStopRequest(aRequest, aContext, aStatusCode);
 
     // If we failed (or were canceled - failure is implied if canceled),
     // there's no use tracking our state, since it's meaningless.
     if (NS_FAILED(aStatusCode))
       this.requestStatus = 0;
     else
       this.requestStatus |= STOP_REQUEST;
   }
--- a/layout/style/StreamLoader.cpp
+++ b/layout/style/StreamLoader.cpp
@@ -20,17 +20,17 @@ StreamLoader::StreamLoader(mozilla::css:
     : mSheetLoadData(aSheetLoadData), mStatus(NS_OK) {}
 
 StreamLoader::~StreamLoader() {}
 
 NS_IMPL_ISUPPORTS(StreamLoader, nsIStreamListener)
 
 /* nsIRequestObserver implementation */
 NS_IMETHODIMP
-StreamLoader::OnStartRequest(nsIRequest* aRequest) {
+StreamLoader::OnStartRequest(nsIRequest* aRequest, nsISupports*) {
   // It's kinda bad to let Web content send a number that results
   // in a potentially large allocation directly, but efficiency of
   // compression bombs is so great that it doesn't make much sense
   // to require a site to send one before going ahead and allocating.
   nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
   if (channel) {
     int64_t length;
     nsresult rv = channel->GetContentLength(&length);
@@ -42,17 +42,17 @@ StreamLoader::OnStartRequest(nsIRequest*
         return (mStatus = NS_ERROR_OUT_OF_MEMORY);
       }
     }
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
-StreamLoader::OnStopRequest(nsIRequest* aRequest,
+StreamLoader::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
                             nsresult aStatus) {
   // Decoded data
   nsCString utf8String;
   {
     // Hold the nsStringBuffer for the bytes from the stack to ensure release
     // no matter which return branch is taken.
     nsCString bytes(mBytes);
     mBytes.Truncate();
@@ -109,17 +109,17 @@ StreamLoader::OnStopRequest(nsIRequest* 
   // accessing fields of mSheetLoadData from here.
   mSheetLoadData->mLoader->ParseSheet(utf8String, mSheetLoadData,
                                       Loader::AllowAsyncParse::Yes);
   return NS_OK;
 }
 
 /* nsIStreamListener implementation */
 NS_IMETHODIMP
-StreamLoader::OnDataAvailable(nsIRequest*,
+StreamLoader::OnDataAvailable(nsIRequest*, nsISupports*,
                               nsIInputStream* aInputStream, uint64_t,
                               uint32_t aCount) {
   if (NS_FAILED(mStatus)) {
     return mStatus;
   }
   uint32_t dummy;
   return aInputStream->ReadSegments(WriteSegmentFun, this, aCount, &dummy);
 }
--- a/layout/style/nsFontFaceLoader.cpp
+++ b/layout/style/nsFontFaceLoader.cpp
@@ -292,30 +292,30 @@ nsFontFaceLoader::OnStreamComplete(nsISt
     mLoadTimer = nullptr;
   }
 
   return NS_SUCCESS_ADOPTED_DATA;
 }
 
 // nsIRequestObserver
 NS_IMETHODIMP
-nsFontFaceLoader::OnStartRequest(nsIRequest* aRequest) {
+nsFontFaceLoader::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext) {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsCOMPtr<nsIThreadRetargetableRequest> req = do_QueryInterface(aRequest);
   if (req) {
     nsCOMPtr<nsIEventTarget> sts =
         do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
     Unused << NS_WARN_IF(NS_FAILED(req->RetargetDeliveryTo(sts)));
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsFontFaceLoader::OnStopRequest(nsIRequest* aRequest,
+nsFontFaceLoader::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
                                 nsresult aStatusCode) {
   MOZ_ASSERT(NS_IsMainThread());
   DropChannel();
   return NS_OK;
 }
 
 void nsFontFaceLoader::Cancel() {
   MOZ_DIAGNOSTIC_ASSERT(!mInLoadTimerCallback);
--- a/media/mtransport/ipc/WebrtcProxyChannel.cpp
+++ b/media/mtransport/ipc/WebrtcProxyChannel.cpp
@@ -326,40 +326,41 @@ WebrtcProxyChannel::OnTransportAvailable
 
   InvokeOnConnected();
 
   return NS_OK;
 }
 
 // nsIRequestObserver (from nsIStreamListener)
 NS_IMETHODIMP
-WebrtcProxyChannel::OnStartRequest(nsIRequest* aRequest) {
+WebrtcProxyChannel::OnStartRequest(nsIRequest* aRequest,
+                                   nsISupports* aContext) {
   LOG(("WebrtcProxyChannel::OnStartRequest %p\n", this));
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-WebrtcProxyChannel::OnStopRequest(nsIRequest* aRequest,
+WebrtcProxyChannel::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
                                   nsresult aStatusCode) {
   LOG(("WebrtcProxyChannel::OnStopRequest %p status=%u\n", this,
        static_cast<uint32_t>(aStatusCode)));
 
   // see nsHttpChannel::ProcessFailedProxyConnect for most error codes
   if (NS_FAILED(aStatusCode)) {
     CloseWithReason(aStatusCode);
     return aStatusCode;
   }
 
   return NS_OK;
 }
 
 // nsIStreamListener
 NS_IMETHODIMP
-WebrtcProxyChannel::OnDataAvailable(nsIRequest* aRequest,
+WebrtcProxyChannel::OnDataAvailable(nsIRequest* aRequest, nsISupports* aContext,
                                     nsIInputStream* aInputStream,
                                     uint64_t aOffset, uint32_t aCount) {
   LOG(("WebrtcProxyChannel::OnDataAvailable %p count=%u\n", this, aCount));
   MOZ_ASSERT(0, "unreachable data available");
   return NS_OK;
 }
 
 // nsIInputStreamCallback
--- a/mobile/android/chrome/content/CastingApps.js
+++ b/mobile/android/chrome/content/CastingApps.js
@@ -337,33 +337,33 @@ var CastingApps = {
         contentPolicyType: Ci.nsIContentPolicy.TYPE_INTERNAL_VIDEO,
       });
     } catch (e) {
      aCallback(null);
      return;
     }
 
     let listener = {
-      onStartRequest: function(request) {
+      onStartRequest: function(request, context) {
         switch (channel.responseStatus) {
           case 301:
           case 302:
           case 303:
             request.cancel(0);
             let location = channel.getResponseHeader("Location");
             CastingApps._getContentTypeForURI(CastingApps.makeURI(location), aElement, aCallback);
             break;
           default:
             aCallback(channel.contentType);
             request.cancel(0);
             break;
         }
       },
-      onStopRequest: function(request, statusCode) {},
-      onDataAvailable: function(request, stream, offset, count) {},
+      onStopRequest: function(request, context, statusCode) {},
+      onDataAvailable: function(request, context, stream, offset, count) {},
     };
 
     if (channel) {
       channel.asyncOpen(listener);
     } else {
       aCallback(null);
     }
   },
--- a/modules/libjar/nsJARChannel.cpp
+++ b/modules/libjar/nsJARChannel.cpp
@@ -524,18 +524,18 @@ nsresult nsJARChannel::CheckPendingEvent
   return NS_OK;
 }
 
 void nsJARChannel::NotifyError(nsresult aError) {
   MOZ_ASSERT(NS_FAILED(aError));
 
   mStatus = aError;
 
-  OnStartRequest(nullptr);
-  OnStopRequest(nullptr, aError);
+  OnStartRequest(nullptr, nullptr);
+  OnStopRequest(nullptr, nullptr, aError);
 }
 
 void nsJARChannel::FireOnProgress(uint64_t aProgress) {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(mProgressSink);
 
   mProgressSink->OnProgress(this, nullptr, aProgress, mContentLength);
 }
@@ -980,21 +980,21 @@ nsJARChannel::GetZipEntry(nsIZipEntry **
   return reader->GetEntry(mJarEntry, aZipEntry);
 }
 
 //-----------------------------------------------------------------------------
 // nsIStreamListener
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
-nsJARChannel::OnStartRequest(nsIRequest *req) {
+nsJARChannel::OnStartRequest(nsIRequest *req, nsISupports *ctx) {
   LOG(("nsJARChannel::OnStartRequest [this=%p %s]\n", this, mSpec.get()));
 
   mRequest = req;
-  nsresult rv = mListener->OnStartRequest(this);
+  nsresult rv = mListener->OnStartRequest(this, nullptr);
   mRequest = nullptr;
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Restrict loadable content types.
   nsAutoCString contentType;
   GetContentType(contentType);
   auto contentPolicyType = mLoadInfo->GetExternalContentPolicyType();
   if (contentType.Equals(APPLICATION_HTTP_INDEX_FORMAT) &&
@@ -1011,25 +1011,25 @@ nsJARChannel::OnStartRequest(nsIRequest 
           NS_ConvertUTF8toUTF16(contentType))) {
     return NS_ERROR_CORRUPTED_CONTENT;
   }
 
   return rv;
 }
 
 NS_IMETHODIMP
-nsJARChannel::OnStopRequest(nsIRequest *req,
+nsJARChannel::OnStopRequest(nsIRequest *req, nsISupports *ctx,
                             nsresult status) {
   LOG(("nsJARChannel::OnStopRequest [this=%p %s status=%" PRIx32 "]\n", this,
        mSpec.get(), static_cast<uint32_t>(status)));
 
   if (NS_SUCCEEDED(mStatus)) mStatus = status;
 
   if (mListener) {
-    mListener->OnStopRequest(this, status);
+    mListener->OnStopRequest(this, nullptr, status);
     mListener = nullptr;
   }
 
   if (mLoadGroup) mLoadGroup->RemoveRequest(this, nullptr, status);
 
   mPump = nullptr;
   mIsPending = false;
 
@@ -1042,24 +1042,24 @@ nsJARChannel::OnStopRequest(nsIRequest *
   // To deallocate file descriptor by RemoteOpenFileChild destructor.
   mJarFile = nullptr;
 #endif
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsJARChannel::OnDataAvailable(nsIRequest *req,
+nsJARChannel::OnDataAvailable(nsIRequest *req, nsISupports *ctx,
                               nsIInputStream *stream, uint64_t offset,
                               uint32_t count) {
   LOG(("nsJARChannel::OnDataAvailable [this=%p %s]\n", this, mSpec.get()));
 
   nsresult rv;
 
-  rv = mListener->OnDataAvailable(this, stream, offset, count);
+  rv = mListener->OnDataAvailable(this, nullptr, stream, offset, count);
 
   // simply report progress here instead of hooking ourselves up as a
   // nsITransportEventSink implementation.
   // XXX do the 64-bit stuff for real
   if (mProgressSink && NS_SUCCEEDED(rv)) {
     if (NS_IsMainThread()) {
       FireOnProgress(offset + count);
     } else {
--- a/modules/libjar/test/unit/test_jarchannel.js
+++ b/modules/libjar/test/unit/test_jarchannel.js
@@ -29,30 +29,30 @@ const tmpDir = dirSvc.get("TmpD", Ci.nsI
 function Listener(callback) {
     this._callback = callback;
 }
 Listener.prototype = {
     gotStartRequest: false,
     available: -1,
     gotStopRequest: false,
     QueryInterface: ChromeUtils.generateQI(["nsIRequestObserver"]),
-    onDataAvailable(request, stream, offset, count) {
+    onDataAvailable(request, ctx, stream, offset, count) {
         try {
             this.available = stream.available();
             Assert.equal(this.available, count);
             // Need to consume stream to avoid assertion
             new nsIBinaryInputStream(stream).readBytes(count);
         } catch (ex) {
             do_throw(ex);
         }
     },
-    onStartRequest(request) {
+    onStartRequest(request, ctx) {
         this.gotStartRequest = true;
     },
-    onStopRequest(request, status) {
+    onStopRequest(request, ctx, status) {
         this.gotStopRequest = true;
         Assert.equal(status, 0);
         if (this._callback) {
             this._callback.call(null, this);
         }
     },
 };
 
--- a/modules/libjar/zipwriter/nsDeflateConverter.cpp
+++ b/modules/libjar/zipwriter/nsDeflateConverter.cpp
@@ -88,16 +88,17 @@ NS_IMETHODIMP nsDeflateConverter::AsyncC
   NS_ENSURE_SUCCESS(rv, rv);
 
   mListener = aListener;
   mContext = aCtxt;
   return rv;
 }
 
 NS_IMETHODIMP nsDeflateConverter::OnDataAvailable(nsIRequest *aRequest,
+                                                  nsISupports *aContext,
                                                   nsIInputStream *aInputStream,
                                                   uint64_t aOffset,
                                                   uint32_t aCount) {
   if (!mListener) return NS_ERROR_NOT_INITIALIZED;
 
   auto buffer = MakeUnique<char[]>(aCount);
   NS_ENSURE_TRUE(buffer, NS_ERROR_OUT_OF_MEMORY);
 
@@ -110,62 +111,64 @@ NS_IMETHODIMP nsDeflateConverter::OnData
 
   int zerr = Z_OK;
   // deflate loop
   while (mZstream.avail_in > 0 && zerr == Z_OK) {
     zerr = deflate(&mZstream, Z_NO_FLUSH);
 
     while (mZstream.avail_out == 0) {
       // buffer is full, push the data out to the listener
-      rv = PushAvailableData(aRequest, nullptr);
+      rv = PushAvailableData(aRequest, aContext);
       NS_ENSURE_SUCCESS(rv, rv);
       zerr = deflate(&mZstream, Z_NO_FLUSH);
     }
   }
 
   return NS_OK;
 }
 
-NS_IMETHODIMP nsDeflateConverter::OnStartRequest(nsIRequest *aRequest) {
+NS_IMETHODIMP nsDeflateConverter::OnStartRequest(nsIRequest *aRequest,
+                                                 nsISupports *aContext) {
   if (!mListener) return NS_ERROR_NOT_INITIALIZED;
 
-  return mListener->OnStartRequest(aRequest);
+  return mListener->OnStartRequest(aRequest, mContext);
 }
 
 NS_IMETHODIMP nsDeflateConverter::OnStopRequest(nsIRequest *aRequest,
+                                                nsISupports *aContext,
                                                 nsresult aStatusCode) {
   if (!mListener) return NS_ERROR_NOT_INITIALIZED;
 
   nsresult rv;
 
   int zerr;
   do {
     zerr = deflate(&mZstream, Z_FINISH);
-    rv = PushAvailableData(aRequest, nullptr);
+    rv = PushAvailableData(aRequest, aContext);
     NS_ENSURE_SUCCESS(rv, rv);
   } while (zerr == Z_OK);
 
   deflateEnd(&mZstream);
 
-  return mListener->OnStopRequest(aRequest, aStatusCode);
+  return mListener->OnStopRequest(aRequest, mContext, aStatusCode);
 }
 
 nsresult nsDeflateConverter::PushAvailableData(nsIRequest *aRequest,
                                                nsISupports *aContext) {
   uint32_t bytesToWrite = sizeof(mWriteBuffer) - mZstream.avail_out;
   // We don't need to do anything if there isn't any data
   if (bytesToWrite == 0) return NS_OK;
 
   MOZ_ASSERT(bytesToWrite <= INT32_MAX);
   nsCOMPtr<nsIInputStream> stream;
   nsresult rv = NS_NewByteInputStream(getter_AddRefs(stream),
                                       (char *)mWriteBuffer, bytesToWrite);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  rv = mListener->OnDataAvailable(aRequest, stream, mOffset,
+  rv = mListener->OnDataAvailable(aRequest, mContext, stream, mOffset,
                                   bytesToWrite);
 
   // now set the state for 'deflate'
   mZstream.next_out = mWriteBuffer;
   mZstream.avail_out = sizeof(mWriteBuffer);
 
   mOffset += bytesToWrite;
   return rv;
--- a/modules/libjar/zipwriter/nsZipDataStream.cpp
+++ b/modules/libjar/zipwriter/nsZipDataStream.cpp
@@ -51,41 +51,44 @@ nsresult nsZipDataStream::Init(nsZipWrit
   } else {
     mHeader->mMethod = ZIP_METHOD_STORE;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP nsZipDataStream::OnDataAvailable(nsIRequest *aRequest,
+                                               nsISupports *aContext,
                                                nsIInputStream *aInputStream,
                                                uint64_t aOffset,
                                                uint32_t aCount) {
   if (!mOutput) return NS_ERROR_NOT_INITIALIZED;
 
   auto buffer = MakeUnique<char[]>(aCount);
   NS_ENSURE_TRUE(buffer, NS_ERROR_OUT_OF_MEMORY);
 
   nsresult rv = ZW_ReadData(aInputStream, buffer.get(), aCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  return ProcessData(aRequest, nullptr, buffer.get(), aOffset, aCount);
+  return ProcessData(aRequest, aContext, buffer.get(), aOffset, aCount);
 }
 
-NS_IMETHODIMP nsZipDataStream::OnStartRequest(nsIRequest *aRequest) {
+NS_IMETHODIMP nsZipDataStream::OnStartRequest(nsIRequest *aRequest,
+                                              nsISupports *aContext) {
   if (!mOutput) return NS_ERROR_NOT_INITIALIZED;
 
-  return mOutput->OnStartRequest(aRequest);
+  return mOutput->OnStartRequest(aRequest, aContext);
 }
 
 NS_IMETHODIMP nsZipDataStream::OnStopRequest(nsIRequest *aRequest,
+                                             nsISupports *aContext,
                                              nsresult aStatusCode) {
   if (!mOutput) return NS_ERROR_NOT_INITIALIZED;
 
-  nsresult rv = mOutput->OnStopRequest(aRequest, aStatusCode);
+  nsresult rv = mOutput->OnStopRequest(aRequest, aContext, aStatusCode);
   mOutput = nullptr;
   if (NS_FAILED(rv)) {
     mWriter->EntryCompleteCallback(mHeader, rv);
   } else {
     rv = CompleteEntry();
     rv = mWriter->EntryCompleteCallback(mHeader, rv);
   }
 
@@ -115,44 +118,44 @@ nsresult nsZipDataStream::ProcessData(ns
   mHeader->mCRC = crc32(
       mHeader->mCRC, reinterpret_cast<const unsigned char *>(aBuffer), aCount);
 
   MOZ_ASSERT(aCount <= INT32_MAX);
   nsCOMPtr<nsIInputStream> stream;
   nsresult rv = NS_NewByteInputStream(getter_AddRefs(stream), aBuffer, aCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  rv = mOutput->OnDataAvailable(aRequest, stream, aOffset, aCount);
+  rv = mOutput->OnDataAvailable(aRequest, aContext, stream, aOffset, aCount);
   mHeader->mUSize += aCount;
 
   return rv;
 }
 
 nsresult nsZipDataStream::ReadStream(nsIInputStream *aStream) {
   if (!mOutput) return NS_ERROR_NOT_INITIALIZED;
 
-  nsresult rv = OnStartRequest(nullptr);
+  nsresult rv = OnStartRequest(nullptr, nullptr);
   NS_ENSURE_SUCCESS(rv, rv);
 
   auto buffer = MakeUnique<char[]>(4096);
   NS_ENSURE_TRUE(buffer, NS_ERROR_OUT_OF_MEMORY);
 
   uint32_t read = 0;
   uint32_t offset = 0;
   do {
     rv = aStream->Read(buffer.get(), 4096, &read);
     if (NS_FAILED(rv)) {
-      OnStopRequest(nullptr, rv);
+      OnStopRequest(nullptr, nullptr, rv);
       return rv;
     }
 
     if (read > 0) {
       rv = ProcessData(nullptr, nullptr, buffer.get(), offset, read);
       if (NS_FAILED(rv)) {
-        OnStopRequest(nullptr, rv);
+        OnStopRequest(nullptr, nullptr, rv);
         return rv;
       }
       offset += read;
     }
   } while (read > 0);
 
-  return OnStopRequest(nullptr, NS_OK);
+  return OnStopRequest(nullptr, nullptr, NS_OK);
 }
--- a/modules/libjar/zipwriter/nsZipWriter.cpp
+++ b/modules/libjar/zipwriter/nsZipWriter.cpp
@@ -535,17 +535,17 @@ NS_IMETHODIMP nsZipWriter::ProcessQueue(
   if (!mStream) return NS_ERROR_NOT_INITIALIZED;
   if (mInQueue) return NS_ERROR_IN_PROGRESS;
 
   mProcessObserver = aObserver;
   mProcessContext = aContext;
   mInQueue = true;
 
   if (mProcessObserver)
-    mProcessObserver->OnStartRequest(nullptr);
+    mProcessObserver->OnStartRequest(nullptr, mProcessContext);
 
   BeginProcessingNextItem();
 
   return NS_OK;
 }
 
 NS_IMETHODIMP nsZipWriter::Close() {
   if (!mStream) return NS_ERROR_NOT_INITIALIZED;
@@ -615,21 +615,23 @@ NS_IMETHODIMP nsZipWriter::Close() {
   mHeaders.Clear();
   mEntryHash.Clear();
   mQueue.Clear();
 
   return rv;
 }
 
 // Our nsIRequestObserver monitors removal operations performed on the queue
-NS_IMETHODIMP nsZipWriter::OnStartRequest(nsIRequest *aRequest) {
+NS_IMETHODIMP nsZipWriter::OnStartRequest(nsIRequest *aRequest,
+                                          nsISupports *aContext) {
   return NS_OK;
 }
 
 NS_IMETHODIMP nsZipWriter::OnStopRequest(nsIRequest *aRequest,
+                                         nsISupports *aContext,
                                          nsresult aStatusCode) {
   if (NS_FAILED(aStatusCode)) {
     FinishQueue(aStatusCode);
     Cleanup();
   }
 
   nsresult rv = mStream->Flush();
   if (NS_FAILED(rv)) {
@@ -1024,16 +1026,17 @@ void nsZipWriter::BeginProcessingNextIte
   FinishQueue(NS_OK);
 }
 
 /*
  * Ends processing with the given status.
  */
 void nsZipWriter::FinishQueue(nsresult aStatus) {
   nsCOMPtr<nsIRequestObserver> observer = mProcessObserver;
+  nsCOMPtr<nsISupports> context = mProcessContext;
   // Clean up everything first in case the observer decides to queue more
   // things
   mProcessObserver = nullptr;
   mProcessContext = nullptr;
   mInQueue = false;
 
-  if (observer) observer->OnStopRequest(nullptr, aStatus);
+  if (observer) observer->OnStopRequest(nullptr, context, aStatus);
 }
--- a/modules/libjar/zipwriter/test/unit/test_asyncadd.js
+++ b/modules/libjar/zipwriter/test/unit/test_asyncadd.js
@@ -17,20 +17,20 @@ var TESTS = [
     size: 3402,
     crc: 0x504a5c30,
   },
 ];
 
 var size = 0;
 
 var observer = {
-  onStartRequest(request) {
+  onStartRequest(request, context) {
   },
 
-  onStopRequest(request, status) {
+  onStopRequest(request, context, status) {
     Assert.equal(status, Cr.NS_OK);
 
     zipW.close();
     size += ZIP_EOCDR_HEADER_SIZE;
 
     Assert.equal(size, tmpFile.fileSize);
 
     // Test the stored data with the zipreader
--- a/modules/libjar/zipwriter/test/unit/test_asyncbadadd.js
+++ b/modules/libjar/zipwriter/test/unit/test_asyncbadadd.js
@@ -1,20 +1,20 @@
 /* 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/.
  */
 
 const FILENAME = "missing.txt";
 
 var observer = {
-  onStartRequest(request) {
+  onStartRequest(request, context) {
   },
 
-  onStopRequest(request, status) {
+  onStopRequest(request, context, status) {
     Assert.equal(status, Cr.NS_ERROR_FILE_NOT_FOUND);
     zipW.close();
     Assert.equal(ZIP_EOCDR_HEADER_SIZE, tmpFile.fileSize);
     do_test_finished();
   },
 };
 
 function run_test() {
--- a/modules/libjar/zipwriter/test/unit/test_asyncbadremove.js
+++ b/modules/libjar/zipwriter/test/unit/test_asyncbadremove.js
@@ -1,20 +1,20 @@
 /* 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/.
  */
 
 const FILENAME = "missing.txt";
 
 var observer = {
-  onStartRequest(request) {
+  onStartRequest(request, context) {
   },
 
-  onStopRequest(request, status) {
+  onStopRequest(request, context, status) {
     Assert.equal(status, Cr.NS_ERROR_FILE_NOT_FOUND);
     zipW.close();
     Assert.equal(ZIP_EOCDR_HEADER_SIZE, tmpFile.fileSize);
     do_test_finished();
   },
 };
 
 function run_test() {
--- a/modules/libjar/zipwriter/test/unit/test_asyncremove.js
+++ b/modules/libjar/zipwriter/test/unit/test_asyncremove.js
@@ -4,20 +4,20 @@
  */
 
 var TESTS = [
   "test.txt",
   "test.png",
 ];
 
 var observer = {
-  onStartRequest(request) {
+  onStartRequest(request, context) {
   },
 
-  onStopRequest(request, status) {
+  onStopRequest(request, context, status) {
     Assert.equal(status, Cr.NS_OK);
 
     zipW.close();
 
     // Empty zip file should just be the end of central directory marker
     var newTmpFile = tmpFile.clone();
     Assert.equal(newTmpFile.fileSize, ZIP_EOCDR_HEADER_SIZE);
     do_test_finished();
--- a/modules/libjar/zipwriter/test/unit/test_bug399727.js
+++ b/modules/libjar/zipwriter/test/unit/test_bug399727.js
@@ -16,27 +16,27 @@ function BinaryComparer(file, callback) 
 }
 
 BinaryComparer.prototype = {
   fileStream: null,
   offset: null,
   length: null,
   callback: null,
 
-  onStartRequest(aRequest) {
+  onStartRequest(aRequest, aContext) {
   },
 
-  onStopRequest(aRequest, aStatusCode) {
+  onStopRequest(aRequest, aContext, aStatusCode) {
     this.fileStream.close();
     Assert.equal(aStatusCode, Cr.NS_OK);
     Assert.equal(this.offset, this.length);
     this.callback();
   },
 
-  onDataAvailable(aRequest, aInputStream, aOffset, aCount) {
+  onDataAvailable(aRequest, aContext, aInputStream, aOffset, aCount) {
     var stream = Cc["@mozilla.org/binaryinputstream;1"].
                  createInstance(Ci.nsIBinaryInputStream);
     stream.setInputStream(aInputStream);
     var source, actual;
     for (var i = 0; i < aCount; i++) {
       try {
         source = this.fileStream.read8();
       } catch (e) {
--- a/modules/libjar/zipwriter/test/unit/test_bug717061.js
+++ b/modules/libjar/zipwriter/test/unit/test_bug717061.js
@@ -15,27 +15,27 @@ function BinaryComparer(file, callback) 
 }
 
 BinaryComparer.prototype = {
   fileStream: null,
   offset: null,
   length: null,
   callback: null,
 
-  onStartRequest(aRequest) {
+  onStartRequest(aRequest, aContext) {
   },
 
-  onStopRequest(aRequest, aStatusCode) {
+  onStopRequest(aRequest, aContext, aStatusCode) {
     this.fileStream.close();
     Assert.equal(aStatusCode, Cr.NS_OK);
     Assert.equal(this.offset, this.length);
     this.callback();
   },
 
-  onDataAvailable(aRequest, aInputStream, aOffset, aCount) {
+  onDataAvailable(aRequest, aContext, aInputStream, aOffset, aCount) {
     var stream = Cc["@mozilla.org/binaryinputstream;1"].
       createInstance(Ci.nsIBinaryInputStream);
     stream.setInputStream(aInputStream);
     var source, actual;
     for (var i = 0; i < aCount; i++) {
       try {
         source = this.fileStream.read8();
       } catch (e) {
--- a/netwerk/base/BackgroundFileSaver.cpp
+++ b/netwerk/base/BackgroundFileSaver.cpp
@@ -961,36 +961,39 @@ BackgroundFileSaverStreamListener::Backg
 bool BackgroundFileSaverStreamListener::HasInfiniteBuffer() { return true; }
 
 nsAsyncCopyProgressFun
 BackgroundFileSaverStreamListener::GetProgressCallback() {
   return AsyncCopyProgressCallback;
 }
 
 NS_IMETHODIMP
-BackgroundFileSaverStreamListener::OnStartRequest(nsIRequest *aRequest) {
+BackgroundFileSaverStreamListener::OnStartRequest(nsIRequest *aRequest,
+                                                  nsISupports *aContext) {
   NS_ENSURE_ARG(aRequest);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 BackgroundFileSaverStreamListener::OnStopRequest(nsIRequest *aRequest,
+                                                 nsISupports *aContext,
                                                  nsresult aStatusCode) {
   // If an error occurred, cancel the operation immediately.  On success, wait
   // until the caller has determined whether the file should be renamed.
   if (NS_FAILED(aStatusCode)) {
     Finish(aStatusCode);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 BackgroundFileSaverStreamListener::OnDataAvailable(nsIRequest *aRequest,
+                                                   nsISupports *aContext,
                                                    nsIInputStream *aInputStream,
                                                    uint64_t aOffset,
                                                    uint32_t aCount) {
   nsresult rv;
 
   NS_ENSURE_ARG(aRequest);
 
   // Read the requested data.  Since the pipe has an infinite buffer, we don't
--- a/netwerk/base/MemoryDownloader.cpp
+++ b/netwerk/base/MemoryDownloader.cpp
@@ -12,33 +12,33 @@ namespace mozilla {
 namespace net {
 
 NS_IMPL_ISUPPORTS(MemoryDownloader, nsIStreamListener, nsIRequestObserver)
 
 MemoryDownloader::MemoryDownloader(IObserver* aObserver)
     : mObserver(aObserver), mStatus(NS_ERROR_NOT_INITIALIZED) {}
 
 NS_IMETHODIMP
-MemoryDownloader::OnStartRequest(nsIRequest* aRequest) {
+MemoryDownloader::OnStartRequest(nsIRequest* aRequest, nsISupports* aCtxt) {
   MOZ_ASSERT(!mData);
   mData.reset(new FallibleTArray<uint8_t>());
   mStatus = NS_OK;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-MemoryDownloader::OnStopRequest(nsIRequest* aRequest,
+MemoryDownloader::OnStopRequest(nsIRequest* aRequest, nsISupports* aCtxt,
                                 nsresult aStatus) {
   MOZ_ASSERT_IF(NS_FAILED(mStatus), NS_FAILED(aStatus));
   MOZ_ASSERT(!mData == NS_FAILED(mStatus));
   Data data;
   data.swap(mData);
   RefPtr<IObserver> observer;
   observer.swap(mObserver);
-  observer->OnDownloadComplete(this, aRequest, nullptr, aStatus, std::move(data));
+  observer->OnDownloadComplete(this, aRequest, aCtxt, aStatus, std::move(data));
   return NS_OK;
 }
 
 nsresult MemoryDownloader::ConsumeData(nsIInputStream* aIn, void* aClosure,
                                        const char* aFromRawSegment,
                                        uint32_t aToOffset, uint32_t aCount,
                                        uint32_t* aWriteCount) {
   MemoryDownloader* self = static_cast<MemoryDownloader*>(aClosure);
@@ -48,17 +48,17 @@ nsresult MemoryDownloader::ConsumeData(n
     self->mStatus = NS_ERROR_OUT_OF_MEMORY;
     return NS_ERROR_OUT_OF_MEMORY;
   }
   *aWriteCount = aCount;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-MemoryDownloader::OnDataAvailable(nsIRequest* aRequest,
+MemoryDownloader::OnDataAvailable(nsIRequest* aRequest, nsISupports* aCtxt,
                                   nsIInputStream* aInStr,
                                   uint64_t aSourceOffset, uint32_t aCount) {
   uint32_t n;
   MOZ_ASSERT(mData);
   nsresult rv = aInStr->ReadSegments(ConsumeData, this, aCount, &n);
   if (NS_SUCCEEDED(mStatus) && NS_FAILED(rv)) {
     mStatus = rv;
   }
--- a/netwerk/base/NetUtil.jsm
+++ b/netwerk/base/NetUtil.jsm
@@ -60,18 +60,18 @@ var NetUtil = {
         copier.init(aSource, aSink,
                     null /* Default event target */,
                     0 /* Default length */,
                     true, true /* Auto-close */);
 
         var observer;
         if (aCallback) {
             observer = {
-                onStartRequest(aRequest) {},
-                onStopRequest(aRequest, aStatusCode) {
+                onStartRequest(aRequest, aContext) {},
+                onStopRequest(aRequest, aContext, aStatusCode) {
                     aCallback(aStatusCode);
                 },
             };
         } else {
             observer = null;
         }
 
         // start the copying
@@ -112,18 +112,18 @@ var NetUtil = {
         let pipe = Cc["@mozilla.org/pipe;1"].
                    createInstance(Ci.nsIPipe);
         pipe.init(true, true, 0, PR_UINT32_MAX, null);
 
         // Create a listener that will give data to the pipe's output stream.
         let listener = Cc["@mozilla.org/network/simple-stream-listener;1"].
                        createInstance(Ci.nsISimpleStreamListener);
         listener.init(pipe.outputStream, {
-            onStartRequest(aRequest) {},
-            onStopRequest(aRequest, aStatusCode) {
+            onStartRequest(aRequest, aContext) {},
+            onStopRequest(aRequest, aContext, aStatusCode) {
                 pipe.outputStream.close();
                 aCallback(pipe.inputStream, aStatusCode, aRequest);
             },
         });
 
         // Input streams are handled slightly differently from everything else.
         if (aSource instanceof Ci.nsIInputStream) {
             let pump = Cc["@mozilla.org/network/input-stream-pump;1"].
--- a/netwerk/base/NetworkConnectivityService.cpp
+++ b/netwerk/base/NetworkConnectivityService.cpp
@@ -246,22 +246,24 @@ NetworkConnectivityService::RecheckIPCon
     rv = mIPv6Channel->AsyncOpen(this);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-NetworkConnectivityService::OnStartRequest(nsIRequest *aRequest) {
+NetworkConnectivityService::OnStartRequest(nsIRequest *aRequest,
+                                           nsISupports *aContext) {
   return NS_OK;
 }
 
 NS_IMETHODIMP
 NetworkConnectivityService::OnStopRequest(nsIRequest *aRequest,
+                                          nsISupports *aContext,
                                           nsresult aStatusCode) {
   if (aStatusCode == NS_ERROR_ABORT) {
     return NS_OK;
   }
 
   ConnectivityState status = NS_FAILED(aStatusCode) ? NOT_AVAILABLE : OK;
 
   if (aRequest == mIPv4Channel) {
@@ -287,16 +289,17 @@ NetworkConnectivityService::OnStopReques
     NotifyObservers("network:connectivity-service:ip-checks-complete");
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 NetworkConnectivityService::OnDataAvailable(nsIRequest *aRequest,
+                                            nsISupports *aContext,
                                             nsIInputStream *aInputStream,
                                             uint64_t aOffset, uint32_t aCount) {
   nsAutoCString data;
   Unused << NS_ReadInputStreamToString(aInputStream, data, aCount);
   return NS_OK;
 }
 
 }  // namespace net
--- a/netwerk/base/Predictor.cpp
+++ b/netwerk/base/Predictor.cpp
@@ -2317,23 +2317,25 @@ Predictor::OnPredictDNS(nsIURI *aURI) {
 
 // Predictor::PrefetchListener
 // nsISupports
 NS_IMPL_ISUPPORTS(Predictor::PrefetchListener, nsIStreamListener,
                   nsIRequestObserver)
 
 // nsIRequestObserver
 NS_IMETHODIMP
-Predictor::PrefetchListener::OnStartRequest(nsIRequest *aRequest) {
+Predictor::PrefetchListener::OnStartRequest(nsIRequest *aRequest,
+                                            nsISupports *aContext) {
   mStartTime = TimeStamp::Now();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 Predictor::PrefetchListener::OnStopRequest(nsIRequest *aRequest,
+                                           nsISupports *aContext,
                                            nsresult aStatusCode) {
   PREDICTOR_LOG(("OnStopRequest this=%p aStatusCode=0x%" PRIX32, this,
                  static_cast<uint32_t>(aStatusCode)));
   NS_ENSURE_ARG(aRequest);
   if (NS_FAILED(aStatusCode)) {
     return aStatusCode;
   }
   Telemetry::AccumulateTimeDelta(Telemetry::PREDICTOR_PREFETCH_TIME,
@@ -2378,16 +2380,17 @@ Predictor::PrefetchListener::OnStopReque
   }
 
   return rv;
 }
 
 // nsIStreamListener
 NS_IMETHODIMP
 Predictor::PrefetchListener::OnDataAvailable(nsIRequest *aRequest,
+                                             nsISupports *aContext,
                                              nsIInputStream *aInputStream,
                                              uint64_t aOffset,
                                              const uint32_t aCount) {
   uint32_t result;
   return aInputStream->ReadSegments(NS_DiscardSegment, nullptr, aCount,
                                     &result);
 }
 
--- a/netwerk/base/SimpleChannelParent.cpp
+++ b/netwerk/base/SimpleChannelParent.cpp
@@ -72,33 +72,35 @@ NS_IMETHODIMP
 SimpleChannelParent::Delete() {
   // Nothing to do.
   return NS_OK;
 }
 
 void SimpleChannelParent::ActorDestroy(ActorDestroyReason aWhy) {}
 
 NS_IMETHODIMP
-SimpleChannelParent::OnStartRequest(nsIRequest* aRequest) {
+SimpleChannelParent::OnStartRequest(nsIRequest* aRequest,
+                                    nsISupports* aContext) {
   // We don't have a way to prevent nsBaseChannel from calling AsyncOpen on
   // the created nsSimpleChannel. We don't have anywhere to send the data in the
   // parent, so abort the binding.
   return NS_BINDING_ABORTED;
 }
 
 NS_IMETHODIMP
-SimpleChannelParent::OnStopRequest(nsIRequest* aRequest,
+SimpleChannelParent::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
                                    nsresult aStatusCode) {
   // See above.
   MOZ_ASSERT(NS_FAILED(aStatusCode));
   return NS_OK;
 }
 
 NS_IMETHODIMP
 SimpleChannelParent::OnDataAvailable(nsIRequest* aRequest,
+                                     nsISupports* aContext,
                                      nsIInputStream* aInputStream,
                                      uint64_t aOffset, uint32_t aCount) {
   // See above.
   MOZ_CRASH("Should never be called");
 }
 
 }  // namespace net
 }  // namespace mozilla
--- a/netwerk/base/nsAsyncStreamCopier.cpp
+++ b/netwerk/base/nsAsyncStreamCopier.cpp
@@ -107,17 +107,17 @@ void nsAsyncStreamCopier::Complete(nsres
       observer = mObserver;
       mObserver = nullptr;
     }
   }
 
   if (observer) {
     LOG(("  calling OnStopRequest [status=%" PRIx32 "]\n",
          static_cast<uint32_t>(status)));
-    observer->OnStopRequest(AsRequest(), status);
+    observer->OnStopRequest(AsRequest(), ctx, status);
   }
 }
 
 void nsAsyncStreamCopier::OnAsyncCopyComplete(void *closure, nsresult status) {
   nsAsyncStreamCopier *self = (nsAsyncStreamCopier *)closure;
   self->Complete(status);
   NS_RELEASE(self);  // addref'd in AsyncCopy
 }
@@ -323,17 +323,17 @@ nsAsyncStreamCopier::AsyncCopy(nsIReques
     if (NS_FAILED(rv)) return rv;
   }
 
   // from this point forward, AsyncCopy is going to return NS_OK.  any errors
   // will be reported via OnStopRequest.
   mIsPending = true;
 
   if (mObserver) {
-    rv = mObserver->OnStartRequest(AsRequest());
+    rv = mObserver->OnStartRequest(AsRequest(), nullptr);
     if (NS_FAILED(rv)) Cancel(rv);
   }
 
   if (!mShouldSniffBuffering) {
     // No buffer sniffing required, let's proceed
     AsyncCopyInternal();
     return NS_OK;
   }
--- a/netwerk/base/nsBaseChannel.cpp
+++ b/netwerk/base/nsBaseChannel.cpp
@@ -276,18 +276,18 @@ void nsBaseChannel::HandleAsyncRedirect(
 
 void nsBaseChannel::ContinueHandleAsyncRedirect(nsresult result) {
   mWaitingOnAsyncRedirect = false;
 
   if (NS_FAILED(result)) Cancel(result);
 
   if (NS_FAILED(result) && mListener) {
     // Notify our consumer ourselves
-    mListener->OnStartRequest(this);
-    mListener->OnStopRequest(this, mStatus);
+    mListener->OnStartRequest(this, nullptr);
+    mListener->OnStopRequest(this, nullptr, mStatus);
     ChannelDone();
   }
 
   if (mLoadGroup) mLoadGroup->RemoveRequest(this, nullptr, mStatus);
 
   // Drop notification callbacks to prevent cycles.
   mCallbacks = nullptr;
   CallbacksChanged();
@@ -734,17 +734,17 @@ static void CallUnknownTypeSniffer(void 
   RefPtr<nsUnknownDecoder> sniffer = new nsUnknownDecoder();
 
   nsAutoCString detected;
   nsresult rv = sniffer->GetMIMETypeFromContent(chan, aData, aCount, detected);
   if (NS_SUCCEEDED(rv)) chan->SetContentType(detected);
 }
 
 NS_IMETHODIMP
-nsBaseChannel::OnStartRequest(nsIRequest *request) {
+nsBaseChannel::OnStartRequest(nsIRequest *request, nsISupports *ctxt) {
   MOZ_ASSERT_IF(mRequest, request == mRequest);
 
   if (mPump) {
     // If our content type is unknown, use the content type
     // sniffer. If the sniffer is not available for some reason, then we just
     // keep going as-is.
     if (NS_SUCCEEDED(mStatus) &&
         mContentType.EqualsLiteral(UNKNOWN_CONTENT_TYPE)) {
@@ -755,34 +755,34 @@ nsBaseChannel::OnStartRequest(nsIRequest
     // Now, the general type sniffers. Skip this if we have none.
     if (mLoadFlags & LOAD_CALL_CONTENT_SNIFFERS)
       mPump->PeekStream(CallTypeSniffers, static_cast<nsIChannel *>(this));
   }
 
   SUSPEND_PUMP_FOR_SCOPE();
 
   if (mListener)  // null in case of redirect
-    return mListener->OnStartRequest(this);
+    return mListener->OnStartRequest(this, nullptr);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsBaseChannel::OnStopRequest(nsIRequest *request,
+nsBaseChannel::OnStopRequest(nsIRequest *request, nsISupports *ctxt,
                              nsresult status) {
   // If both mStatus and status are failure codes, we keep mStatus as-is since
   // that is consistent with our GetStatus and Cancel methods.
   if (NS_SUCCEEDED(mStatus)) mStatus = status;
 
   // Cause Pending to return false.
   mPump = nullptr;
   mRequest = nullptr;
   mPumpingData = false;
 
   if (mListener)  // null in case of redirect
-    mListener->OnStopRequest(this, mStatus);
+    mListener->OnStopRequest(this, nullptr, mStatus);
   ChannelDone();
 
   // No need to suspend pump in this scope since we will not be receiving
   // any more events from it.
 
   if (mLoadGroup) mLoadGroup->RemoveRequest(this, nullptr, mStatus);
 
   // Drop notification callbacks to prevent cycles.
@@ -791,23 +791,23 @@ nsBaseChannel::OnStopRequest(nsIRequest 
 
   return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 // nsBaseChannel::nsIStreamListener
 
 NS_IMETHODIMP
-nsBaseChannel::OnDataAvailable(nsIRequest *request,
+nsBaseChannel::OnDataAvailable(nsIRequest *request, nsISupports *ctxt,
                                nsIInputStream *stream, uint64_t offset,
                                uint32_t count) {
   SUSPEND_PUMP_FOR_SCOPE();
 
   nsresult rv =
-      mListener->OnDataAvailable(this, stream, offset, count);
+      mListener->OnDataAvailable(this, nullptr, stream, offset, count);
   if (mSynthProgressEvents && NS_SUCCEEDED(rv)) {
     int64_t prog = offset + count;
     if (NS_IsMainThread()) {
       OnTransportStatus(nullptr, NS_NET_STATUS_READING, prog, mContentLength);
     } else {
       class OnTransportStatusAsyncEvent : public mozilla::Runnable {
         RefPtr<nsBaseChannel> mChannel;
         int64_t mProgress;
--- a/netwerk/base/nsDownloader.cpp
+++ b/netwerk/base/nsDownloader.cpp
@@ -31,17 +31,17 @@ NS_IMPL_ISUPPORTS(nsDownloader, nsIDownl
 NS_IMETHODIMP
 nsDownloader::Init(nsIDownloadObserver *observer, nsIFile *location) {
   mObserver = observer;
   mLocation = location;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDownloader::OnStartRequest(nsIRequest *request) {
+nsDownloader::OnStartRequest(nsIRequest *request, nsISupports *ctxt) {
   nsresult rv;
   if (!mLocation) {
     nsCOMPtr<nsIFile> location;
     rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(location));
     if (NS_FAILED(rv)) return rv;
 
     char buf[13];
     NS_MakeRandomString(buf, 8);
@@ -62,24 +62,24 @@ nsDownloader::OnStartRequest(nsIRequest 
   // we could wrap this output stream with a buffered output stream,
   // but it shouldn't be necessary since we will be writing large
   // chunks given to us via OnDataAvailable.
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDownloader::OnStopRequest(nsIRequest *request,
+nsDownloader::OnStopRequest(nsIRequest *request, nsISupports *ctxt,
                             nsresult status) {
   if (mSink) {
     mSink->Close();
     mSink = nullptr;
   }
 
-  mObserver->OnDownloadComplete(this, request, nullptr, status, mLocation);
+  mObserver->OnDownloadComplete(this, request, ctxt, status, mLocation);
   mObserver = nullptr;
 
   return NS_OK;
 }
 
 nsresult nsDownloader::ConsumeData(nsIInputStream *in, void *closure,
                                    const char *fromRawSegment,
                                    uint32_t toOffset, uint32_t count,
@@ -87,14 +87,14 @@ nsresult nsDownloader::ConsumeData(nsIIn
   nsDownloader *self = (nsDownloader *)closure;
   if (self->mSink) return self->mSink->Write(fromRawSegment, count, writeCount);
 
   *writeCount = count;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDownloader::OnDataAvailable(nsIRequest *request,
+nsDownloader::OnDataAvailable(nsIRequest *request, nsISupports *ctxt,
                               nsIInputStream *inStr, uint64_t sourceOffset,
                               uint32_t count) {
   uint32_t n;
   return inStr->ReadSegments(ConsumeData, this, count, &n);
 }
--- a/netwerk/base/nsIRequestObserver.idl
+++ b/netwerk/base/nsIRequestObserver.idl
@@ -12,26 +12,30 @@ interface nsIRequest;
  */
 [scriptable, uuid(fd91e2e0-1481-11d3-9333-00104ba0fd40)]
 interface nsIRequestObserver : nsISupports
 {
     /**
      * Called to signify the beginning of an asynchronous request.
      *
      * @param aRequest request being observed
+     * @param aContext user defined context
      *
      * An exception thrown from onStartRequest has the side-effect of
      * causing the request to be canceled.
      */
-    void onStartRequest(in nsIRequest aRequest);
+    void onStartRequest(in nsIRequest aRequest,
+                        in nsISupports aContext);
 
     /**
      * Called to signify the end of an asynchronous request.  This
      * call is always preceded by a call to onStartRequest.
      *
      * @param aRequest request being observed
+     * @param aContext user defined context
      * @param aStatusCode reason for stopping (NS_OK if completed successfully)
      *
      * An exception thrown from onStopRequest is generally ignored.
      */
     void onStopRequest(in nsIRequest aRequest,
+                       in nsISupports aContext,
                        in nsresult aStatusCode);
 };
--- a/netwerk/base/nsIStreamListener.idl
+++ b/netwerk/base/nsIStreamListener.idl
@@ -14,25 +14,27 @@ interface nsIInputStream;
 interface nsIStreamListener : nsIRequestObserver
 {
     /**
      * Called when the next chunk of data (corresponding to the request) may
      * be read without blocking the calling thread.  The onDataAvailable impl
      * must read exactly |aCount| bytes of data before returning.
      *
      * @param aRequest request corresponding to the source of the data
+     * @param aContext user defined context
      * @param aInputStream input stream containing the data chunk
      * @param aOffset
      *        Number of bytes that were sent in previous onDataAvailable calls
      *        for this request. In other words, the sum of all previous count
      *        parameters.
      * @param aCount number of bytes available in the stream
      *
      * NOTE: The aInputStream parameter must implement readSegments.
      *
      * An exception thrown from onDataAvailable has the side-effect of
      * causing the request to be canceled.
      */
     void onDataAvailable(in nsIRequest aRequest,
+                         in nsISupports aContext, 
                          in nsIInputStream aInputStream,
                          in unsigned long long aOffset,
                          in unsigned long aCount);
 };
--- a/netwerk/base/nsIncrementalDownload.cpp
+++ b/netwerk/base/nsIncrementalDownload.cpp
@@ -177,29 +177,29 @@ void nsIncrementalDownload::UpdateProgre
     mProgressSink->OnProgress(this, mObserverContext, mCurrentSize + mChunkLen,
                               mTotalSize);
 }
 
 nsresult nsIncrementalDownload::CallOnStartRequest() {
   if (!mObserver || mDidOnStartRequest) return NS_OK;
 
   mDidOnStartRequest = true;
-  return mObserver->OnStartRequest(this);
+  return mObserver->OnStartRequest(this, mObserverContext);
 }
 
 void nsIncrementalDownload::CallOnStopRequest() {
   if (!mObserver) return;
 
   // Ensure that OnStartRequest is always called once before OnStopRequest.
   nsresult rv = CallOnStartRequest();
   if (NS_SUCCEEDED(mStatus)) mStatus = rv;
 
   mIsPending = false;
 
-  mObserver->OnStopRequest(this, mStatus);
+  mObserver->OnStopRequest(this, mObserverContext, mStatus);
   mObserver = nullptr;
   mObserverContext = nullptr;
 }
 
 nsresult nsIncrementalDownload::StartTimer(int32_t interval) {
   return NS_NewTimerWithObserver(getter_AddRefs(mTimer), this, interval * 1000,
                                  nsITimer::TYPE_ONE_SHOT);
 }
@@ -460,17 +460,18 @@ nsIncrementalDownload::Start(nsIRequestO
 
   mIsPending = true;
   return NS_OK;
 }
 
 // nsIRequestObserver
 
 NS_IMETHODIMP
-nsIncrementalDownload::OnStartRequest(nsIRequest *request) {
+nsIncrementalDownload::OnStartRequest(nsIRequest *request,
+                                      nsISupports *context) {
   nsresult rv;
 
   nsCOMPtr<nsIHttpChannel> http = do_QueryInterface(request, &rv);
   if (NS_FAILED(rv)) return rv;
 
   // Ensure that we are receiving a 206 response.
   uint32_t code;
   rv = http->GetResponseStatus(&code);
@@ -632,17 +633,17 @@ nsIncrementalDownload::OnStartRequest(ns
 
   mChunk = mozilla::MakeUniqueFallible<char[]>(mChunkSize);
   if (!mChunk) rv = NS_ERROR_OUT_OF_MEMORY;
 
   return rv;
 }
 
 NS_IMETHODIMP
-nsIncrementalDownload::OnStopRequest(nsIRequest *request,
+nsIncrementalDownload::OnStopRequest(nsIRequest *request, nsISupports *context,
                                      nsresult status) {
   // Not a real error; just a trick to kill off the channel without our
   // listener having to care.
   if (status == NS_ERROR_DOWNLOAD_NOT_PARTIAL) return NS_OK;
 
   // Not a real error; just a trick used to suppress OnDataAvailable calls.
   if (status == NS_ERROR_DOWNLOAD_COMPLETE) status = NS_OK;
 
@@ -666,16 +667,17 @@ nsIncrementalDownload::OnStopRequest(nsI
 
   return StartTimer(mInterval);  // Do next chunk
 }
 
 // nsIStreamListener
 
 NS_IMETHODIMP
 nsIncrementalDownload::OnDataAvailable(nsIRequest *request,
+                                       nsISupports *context,
                                        nsIInputStream *input, uint64_t offset,
                                        uint32_t count) {
   while (count) {
     uint32_t space = mChunkSize - mChunkLen;
     uint32_t n, len = std::min(space, count);
 
     nsresult rv = input->Read(&mChunk[mChunkLen], len, &n);
     if (NS_FAILED(rv)) return rv;
--- a/netwerk/base/nsIncrementalStreamLoader.cpp
+++ b/netwerk/base/nsIncrementalStreamLoader.cpp
@@ -46,17 +46,18 @@ nsIncrementalStreamLoader::GetNumBytesRe
 /* readonly attribute nsIRequest request; */
 NS_IMETHODIMP
 nsIncrementalStreamLoader::GetRequest(nsIRequest **aRequest) {
   NS_IF_ADDREF(*aRequest = mRequest);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsIncrementalStreamLoader::OnStartRequest(nsIRequest *request) {
+nsIncrementalStreamLoader::OnStartRequest(nsIRequest *request,
+                                          nsISupports *ctxt) {
   nsCOMPtr<nsIChannel> chan(do_QueryInterface(request));
   if (chan) {
     int64_t contentLength = -1;
     chan->GetContentLength(&contentLength);
     if (contentLength >= 0) {
       // On 64bit platforms size of uint64_t coincides with the size of size_t,
       // so we want to compare with the minimum from size_t and int64_t.
       if (static_cast<uint64_t>(contentLength) >
@@ -67,21 +68,22 @@ nsIncrementalStreamLoader::OnStartReques
       }
 
       // preallocate buffer
       if (!mData.initCapacity(contentLength)) {
         return NS_ERROR_OUT_OF_MEMORY;
       }
     }
   }
+  mContext = ctxt;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsIncrementalStreamLoader::OnStopRequest(nsIRequest *request,
+nsIncrementalStreamLoader::OnStopRequest(nsIRequest *request, nsISupports *ctxt,
                                          nsresult aStatus) {
   AUTO_PROFILER_LABEL("nsIncrementalStreamLoader::OnStopRequest", NETWORK);
 
   if (mObserver) {
     // provide nsIIncrementalStreamLoader::request during call to
     // OnStreamComplete
     mRequest = request;
     size_t length = mData.length();
@@ -92,16 +94,17 @@ nsIncrementalStreamLoader::OnStopRequest
       // The observer didn't take ownership of the extracted data buffer, so
       // put it back into mData.
       mData.replaceRawBuffer(elems, length);
     }
     // done.. cleanup
     ReleaseData();
     mRequest = nullptr;
     mObserver = nullptr;
+    mContext = nullptr;
   }
   return NS_OK;
 }
 
 nsresult nsIncrementalStreamLoader::WriteSegmentFun(
     nsIInputStream *inStr, void *closure, const char *fromSegment,
     uint32_t toOffset, uint32_t count, uint32_t *writeCount) {
   nsIncrementalStreamLoader *self = (nsIncrementalStreamLoader *)closure;
@@ -168,16 +171,17 @@ nsresult nsIncrementalStreamLoader::Writ
   self->mBytesConsumed += consumedCount;
   *writeCount = count;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsIncrementalStreamLoader::OnDataAvailable(nsIRequest *request,
+                                           nsISupports *ctxt,
                                            nsIInputStream *inStr,
                                            uint64_t sourceOffset,
                                            uint32_t count) {
   if (mObserver) {
     // provide nsIIncrementalStreamLoader::request during call to
     // OnStreamComplete
     mRequest = request;
   }
--- a/netwerk/base/nsInputStreamPump.cpp
+++ b/netwerk/base/nsInputStreamPump.cpp
@@ -479,17 +479,17 @@ uint32_t nsInputStreamPump::OnStateStart
     if (NS_FAILED(rv) && rv != NS_BASE_STREAM_CLOSED) mStatus = rv;
   }
 
   {
     // Note: Must exit mutex for call to OnStartRequest to avoid
     // deadlocks when calls to RetargetDeliveryTo for multiple
     // nsInputStreamPumps are needed (e.g. nsHttpChannel).
     RecursiveMutexAutoUnlock unlock(mMutex);
-    rv = mListener->OnStartRequest(this);
+    rv = mListener->OnStartRequest(this, nullptr);
   }
 
   // an error returned from OnStartRequest should cause us to abort; however,
   // we must not stomp on mStatus if already canceled.
   if (NS_FAILED(rv) && NS_SUCCEEDED(mStatus)) mStatus = rv;
 
   return NS_SUCCEEDED(mStatus) ? STATE_TRANSFER : STATE_STOP;
 }
@@ -546,17 +546,17 @@ uint32_t nsInputStreamPump::OnStateTrans
          "(%u)]\n",
          mStreamOffset, avail, odaAvail));
 
     {
       // Note: Must exit mutex for call to OnStartRequest to avoid
       // deadlocks when calls to RetargetDeliveryTo for multiple
       // nsInputStreamPumps are needed (e.g. nsHttpChannel).
       RecursiveMutexAutoUnlock unlock(mMutex);
-      rv = mListener->OnDataAvailable(this, mAsyncStream,
+      rv = mListener->OnDataAvailable(this, nullptr, mAsyncStream,
                                       mStreamOffset, odaAvail);
     }
 
     // don't enter this code if ODA failed or called Cancel
     if (NS_SUCCEEDED(rv) && NS_SUCCEEDED(mStatus)) {
       // test to see if this ODA failed to consume data
       if (tellable) {
         // NOTE: if Tell fails, which can happen if the stream is
@@ -647,17 +647,17 @@ uint32_t nsInputStreamPump::OnStateStop(
   mAsyncStream = nullptr;
   mTargetThread = nullptr;
   mIsPending = false;
   {
     // Note: Must exit mutex for call to OnStartRequest to avoid
     // deadlocks when calls to RetargetDeliveryTo for multiple
     // nsInputStreamPumps are needed (e.g. nsHttpChannel).
     RecursiveMutexAutoUnlock unlock(mMutex);
-    mListener->OnStopRequest(this, mStatus);
+    mListener->OnStopRequest(this, nullptr, mStatus);
   }
   mListener = nullptr;
 
   if (mLoadGroup) mLoadGroup->RemoveRequest(this, nullptr, mStatus);
 
   return STATE_IDLE;
 }
 
--- a/netwerk/base/nsLoadGroup.cpp
+++ b/netwerk/base/nsLoadGroup.cpp
@@ -451,17 +451,17 @@ nsLoadGroup::AddRequest(nsIRequest *requ
     //
     nsCOMPtr<nsIRequestObserver> observer = do_QueryReferent(mObserver);
     if (observer) {
       LOG(
           ("LOADGROUP [%p]: Firing OnStartRequest for request %p."
            "(foreground count=%d).\n",
            this, request, mForegroundCount));
 
-      rv = observer->OnStartRequest(request);
+      rv = observer->OnStartRequest(request, ctxt);
       if (NS_FAILED(rv)) {
         LOG(("LOADGROUP [%p]: OnStartRequest for request %p FAILED.\n", this,
              request));
         //
         // The URI load has been canceled by the observer.  Clean up
         // the damage...
         //
 
@@ -567,17 +567,17 @@ nsLoadGroup::RemoveRequest(nsIRequest *r
     // Fire the OnStopRequest out to the observer...
     nsCOMPtr<nsIRequestObserver> observer = do_QueryReferent(mObserver);
     if (observer) {
       LOG(
           ("LOADGROUP [%p]: Firing OnStopRequest for request %p."
            "(foreground count=%d).\n",
            this, request, mForegroundCount));
 
-      rv = observer->OnStopRequest(request, aStatus);
+      rv = observer->OnStopRequest(request, ctxt, aStatus);
 
       if (NS_FAILED(rv)) {
         LOG(("LOADGROUP [%p]: OnStopRequest for request %p FAILED.\n", this,
              request));
       }
     }
 
     // If that was the last request -> remove ourselves from loadgroup
--- a/netwerk/base/nsRequestObserverProxy.cpp
+++ b/netwerk/base/nsRequestObserverProxy.cpp
@@ -50,17 +50,17 @@ class nsOnStartRequestEvent : public nsA
     if (!mProxy->mObserver) {
       MOZ_ASSERT_UNREACHABLE(
           "already handled onStopRequest event "
           "(observer is null)");
       return NS_OK;
     }
 
     LOG(("handle startevent=%p\n", this));
-    nsresult rv = mProxy->mObserver->OnStartRequest(mRequest);
+    nsresult rv = mProxy->mObserver->OnStartRequest(mRequest, mProxy->mContext);
     if (NS_FAILED(rv)) {
       LOG(("OnStartRequest failed [rv=%" PRIx32 "] canceling request!\n",
            static_cast<uint32_t>(rv)));
       rv = mRequest->Cancel(rv);
       NS_ASSERTION(NS_SUCCEEDED(rv), "Cancel failed for request!");
     }
 
     return NS_OK;
@@ -95,17 +95,17 @@ class nsOnStopRequestEvent : public nsAR
     // Do not allow any more events to be handled after OnStopRequest
     mProxy->mObserver = nullptr;
 
     nsresult status = NS_OK;
     DebugOnly<nsresult> rv = mRequest->GetStatus(&status);
     NS_ASSERTION(NS_SUCCEEDED(rv), "GetStatus failed for request!");
 
     LOG(("handle stopevent=%p\n", this));
-    (void)observer->OnStopRequest(mRequest, status);
+    (void)observer->OnStopRequest(mRequest, mProxy->mContext, status);
 
     return NS_OK;
   }
 };
 
 //-----------------------------------------------------------------------------
 // nsRequestObserverProxy::nsISupports implementation...
 //-----------------------------------------------------------------------------
@@ -113,32 +113,35 @@ class nsOnStopRequestEvent : public nsAR
 NS_IMPL_ISUPPORTS(nsRequestObserverProxy, nsIRequestObserver,
                   nsIRequestObserverProxy)
 
 //-----------------------------------------------------------------------------
 // nsRequestObserverProxy::nsIRequestObserver implementation...
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
-nsRequestObserverProxy::OnStartRequest(nsIRequest *request) {
+nsRequestObserverProxy::OnStartRequest(nsIRequest *request,
+                                       nsISupports *context) {
+  MOZ_ASSERT(!context || context == mContext);
   LOG(("nsRequestObserverProxy::OnStartRequest [this=%p req=%p]\n", this,
        request));
 
   nsOnStartRequestEvent *ev = new nsOnStartRequestEvent(this, request);
   if (!ev) return NS_ERROR_OUT_OF_MEMORY;
 
   LOG(("post startevent=%p\n", ev));
   nsresult rv = FireEvent(ev);
   if (NS_FAILED(rv)) delete ev;
   return rv;
 }
 
 NS_IMETHODIMP
-nsRequestObserverProxy::OnStopRequest(nsIRequest *request,
+nsRequestObserverProxy::OnStopRequest(nsIRequest *request, nsISupports *context,
                                       nsresult status) {
+  MOZ_ASSERT(!context || context == mContext);
   LOG(("nsRequestObserverProxy: OnStopRequest [this=%p req=%p status=%" PRIx32
        "]\n",
        this, request, static_cast<uint32_t>(status)));
 
   // The status argument is ignored because, by the time the OnStopRequestEvent
   // is actually processed, the status of the request may have changed :-(
   // To make sure that an accurate status code is always used, GetStatus() is
   // called when the OnStopRequestEvent is actually processed (see above).
--- a/netwerk/base/nsSimpleStreamListener.cpp
+++ b/netwerk/base/nsSimpleStreamListener.cpp
@@ -17,34 +17,36 @@ NS_IMPL_ISUPPORTS(nsSimpleStreamListener
                   nsIStreamListener, nsIRequestObserver)
 
 //
 //----------------------------------------------------------------------------
 // nsIRequestObserver implementation...
 //----------------------------------------------------------------------------
 //
 NS_IMETHODIMP
-nsSimpleStreamListener::OnStartRequest(nsIRequest *aRequest) {
-  return mObserver ? mObserver->OnStartRequest(aRequest) : NS_OK;
+nsSimpleStreamListener::OnStartRequest(nsIRequest *aRequest,
+                                       nsISupports *aContext) {
+  return mObserver ? mObserver->OnStartRequest(aRequest, aContext) : NS_OK;
 }
 
 NS_IMETHODIMP
 nsSimpleStreamListener::OnStopRequest(nsIRequest *request,
-                                      nsresult aStatus) {
-  return mObserver ? mObserver->OnStopRequest(request, aStatus)
+                                      nsISupports *aContext, nsresult aStatus) {
+  return mObserver ? mObserver->OnStopRequest(request, aContext, aStatus)
                    : NS_OK;
 }
 
 //
 //----------------------------------------------------------------------------
 // nsIStreamListener implementation...
 //----------------------------------------------------------------------------
 //
 NS_IMETHODIMP
 nsSimpleStreamListener::OnDataAvailable(nsIRequest *request,
+                                        nsISupports *aContext,
                                         nsIInputStream *aSource,
                                         uint64_t aOffset, uint32_t aCount) {
   uint32_t writeCount;
   nsresult rv = mSink->WriteFrom(aSource, aCount, &writeCount);
   //
   // Equate zero bytes read and NS_SUCCEEDED to stopping the read.
   //
   if (NS_SUCCEEDED(rv) && (writeCount == 0)) return NS_BASE_STREAM_CLOSED;
--- a/netwerk/base/nsStreamListenerTee.cpp
+++ b/netwerk/base/nsStreamListenerTee.cpp
@@ -7,51 +7,51 @@
 
 namespace mozilla {
 namespace net {
 
 NS_IMPL_ISUPPORTS(nsStreamListenerTee, nsIStreamListener, nsIRequestObserver,
                   nsIStreamListenerTee, nsIThreadRetargetableStreamListener)
 
 NS_IMETHODIMP
-nsStreamListenerTee::OnStartRequest(nsIRequest *request) {
+nsStreamListenerTee::OnStartRequest(nsIRequest *request, nsISupports *context) {
   NS_ENSURE_TRUE(mListener, NS_ERROR_NOT_INITIALIZED);
-  nsresult rv1 = mListener->OnStartRequest(request);
+  nsresult rv1 = mListener->OnStartRequest(request, context);
   nsresult rv2 = NS_OK;
-  if (mObserver) rv2 = mObserver->OnStartRequest(request);
+  if (mObserver) rv2 = mObserver->OnStartRequest(request, context);
 
   // Preserve NS_SUCCESS_XXX in rv1 in case mObserver didn't throw
   return (NS_FAILED(rv2) && NS_SUCCEEDED(rv1)) ? rv2 : rv1;
 }
 
 NS_IMETHODIMP
-nsStreamListenerTee::OnStopRequest(nsIRequest *request,
+nsStreamListenerTee::OnStopRequest(nsIRequest *request, nsISupports *context,
                                    nsresult status) {
   NS_ENSURE_TRUE(mListener, NS_ERROR_NOT_INITIALIZED);
   // it is critical that we close out the input stream tee
   if (mInputTee) {
     mInputTee->SetSink(nullptr);
     mInputTee = nullptr;
   }
 
   // release sink on the same thread where the data was written (bug 716293)
   if (mEventTarget) {
     NS_ProxyRelease("nsStreamListenerTee::mSink", mEventTarget, mSink.forget());
   } else {
     mSink = nullptr;
   }
 
-  nsresult rv = mListener->OnStopRequest(request, status);
-  if (mObserver) mObserver->OnStopRequest(request, status);
+  nsresult rv = mListener->OnStopRequest(request, context, status);
+  if (mObserver) mObserver->OnStopRequest(request, context, status);
   mObserver = nullptr;
   return rv;
 }
 
 NS_IMETHODIMP
-nsStreamListenerTee::OnDataAvailable(nsIRequest *request,
+nsStreamListenerTee::OnDataAvailable(nsIRequest *request, nsISupports *context,
                                      nsIInputStream *input, uint64_t offset,
                                      uint32_t count) {
   NS_ENSURE_TRUE(mListener, NS_ERROR_NOT_INITIALIZED);
   NS_ENSURE_TRUE(mSink, NS_ERROR_NOT_INITIALIZED);
 
   nsCOMPtr<nsIInputStream> tee;
   nsresult rv;
 
@@ -68,17 +68,17 @@ nsStreamListenerTee::OnDataAvailable(nsI
   } else {
     // re-initialize the input tee since the input stream may have changed.
     rv = mInputTee->SetSource(input);
     if (NS_FAILED(rv)) return rv;
 
     tee = mInputTee;
   }
 
-  return mListener->OnDataAvailable(request, tee, offset, count);
+  return mListener->OnDataAvailable(request, context, tee, offset, count);
 }
 
 NS_IMETHODIMP
 nsStreamListenerTee::CheckListenerChain() {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread!");
   nsresult rv = NS_OK;
   nsCOMPtr<nsIThreadRetargetableStreamListener> retargetableListener =
       do_QueryInterface(mListener, &rv);
--- a/netwerk/base/nsStreamLoader.cpp
+++ b/netwerk/base/nsStreamLoader.cpp
@@ -48,17 +48,17 @@ nsStreamLoader::GetNumBytesRead(uint32_t
 
 NS_IMETHODIMP
 nsStreamLoader::GetRequest(nsIRequest **aRequest) {
   NS_IF_ADDREF(*aRequest = mRequest);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsStreamLoader::OnStartRequest(nsIRequest *request) {
+nsStreamLoader::OnStartRequest(nsIRequest *request, nsISupports *ctxt) {
   nsCOMPtr<nsIChannel> chan(do_QueryInterface(request));
   if (chan) {
     int64_t contentLength = -1;
     chan->GetContentLength(&contentLength);
     if (contentLength >= 0) {
       // On 64bit platforms size of uint64_t coincides with the size of size_t,
       // so we want to compare with the minimum from size_t and int64_t.
       if (static_cast<uint64_t>(contentLength) >
@@ -68,24 +68,25 @@ nsStreamLoader::OnStartRequest(nsIReques
         return NS_ERROR_OUT_OF_MEMORY;
       }
       // preallocate buffer
       if (!mData.initCapacity(contentLength)) {
         return NS_ERROR_OUT_OF_MEMORY;
       }
     }
   }
+  mContext = ctxt;
   if (mRequestObserver) {
-    mRequestObserver->OnStartRequest(request);
+    mRequestObserver->OnStartRequest(request, ctxt);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsStreamLoader::OnStopRequest(nsIRequest *request,
+nsStreamLoader::OnStopRequest(nsIRequest *request, nsISupports *ctxt,
                               nsresult aStatus) {
   AUTO_PROFILER_LABEL("nsStreamLoader::OnStopRequest", NETWORK);
 
   if (mObserver) {
     // provide nsIStreamLoader::request during call to OnStreamComplete
     mRequest = request;
     size_t length = mData.length();
     uint8_t *elems = mData.extractOrCopyRawBuffer();
@@ -95,20 +96,21 @@ nsStreamLoader::OnStopRequest(nsIRequest
       // The observer didn't take ownership of the extracted data buffer, so
       // put it back into mData.
       mData.replaceRawBuffer(elems, length);
     }
     // done.. cleanup
     ReleaseData();
     mRequest = nullptr;
     mObserver = nullptr;
+    mContext = nullptr;
   }
 
   if (mRequestObserver) {
-    mRequestObserver->OnStopRequest(request, aStatus);
+    mRequestObserver->OnStopRequest(request, ctxt, aStatus);
     mRequestObserver = nullptr;
   }
 
   return NS_OK;
 }
 
 nsresult nsStreamLoader::WriteSegmentFun(nsIInputStream *inStr, void *closure,
                                          const char *fromSegment,
@@ -122,17 +124,17 @@ nsresult nsStreamLoader::WriteSegmentFun
   }
 
   *writeCount = count;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsStreamLoader::OnDataAvailable(nsIRequest *request,
+nsStreamLoader::OnDataAvailable(nsIRequest *request, nsISupports *ctxt,
                                 nsIInputStream *inStr, uint64_t sourceOffset,
                                 uint32_t count) {
   uint32_t countRead;
   return inStr->ReadSegments(WriteSegmentFun, this, count, &countRead);
 }
 
 void nsStreamLoader::ReleaseData() { mData.clearAndFree(); }
 
--- a/netwerk/base/nsSyncStreamListener.cpp
+++ b/netwerk/base/nsSyncStreamListener.cpp
@@ -55,22 +55,23 @@ nsSyncStreamListener::GetInputStream(nsI
   return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 // nsSyncStreamListener::nsIStreamListener
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
-nsSyncStreamListener::OnStartRequest(nsIRequest *request) {
+nsSyncStreamListener::OnStartRequest(nsIRequest *request,
+                                     nsISupports *context) {
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSyncStreamListener::OnDataAvailable(nsIRequest *request,
+nsSyncStreamListener::OnDataAvailable(nsIRequest *request, nsISupports *context,
                                       nsIInputStream *stream, uint64_t offset,
                                       uint32_t count) {
   uint32_t bytesWritten;
 
   nsresult rv = mPipeOut->WriteFrom(stream, count, &bytesWritten);
 
   // if we get an error, then return failure.  this will cause the
   // channel to be canceled, and as a result our OnStopRequest method
@@ -82,17 +83,17 @@ nsSyncStreamListener::OnDataAvailable(ns
   // the pipe was created to have "infinite" room.
   NS_ASSERTION(bytesWritten == count, "did not write all data");
 
   mKeepWaiting = false;  // unblock Read
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSyncStreamListener::OnStopRequest(nsIRequest *request,
+nsSyncStreamListener::OnStopRequest(nsIRequest *request, nsISupports *context,
                                     nsresult status) {
   mStatus = status;
   mKeepWaiting = false;  // unblock Read
   mDone = true;
   return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
--- a/netwerk/dns/TRR.cpp
+++ b/netwerk/dns/TRR.cpp
@@ -468,17 +468,17 @@ TRR::OnPush(nsIHttpChannel *associated, 
     return NS_ERROR_FAILURE;
   }
 
   RefPtr<TRR> trr = new TRR(mHostResolver, mPB);
   return trr->ReceivePush(pushed, mRec);
 }
 
 NS_IMETHODIMP
-TRR::OnStartRequest(nsIRequest *aRequest) {
+TRR::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext) {
   LOG(("TRR::OnStartRequest %p %s %d\n", this, mHost.get(), mType));
   mStartTime = TimeStamp::Now();
   return NS_OK;
 }
 
 static uint16_t get16bit(unsigned char *aData, int index) {
   return ((aData[index] << 8) | aData[index + 1]);
 }
@@ -961,17 +961,17 @@ nsresult TRR::On200Response() {
     }
   } else {
     LOG(("TRR::On200Response DohDecode %x\n", (int)rv));
   }
   return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
-TRR::OnStopRequest(nsIRequest *aRequest,
+TRR::OnStopRequest(nsIRequest *aRequest, nsISupports *aContext,
                    nsresult aStatusCode) {
   // The dtor will be run after the function returns
   LOG(("TRR:OnStopRequest %p %s %d failed=%d code=%X\n", this, mHost.get(),
        mType, mFailed, (unsigned int)aStatusCode));
   nsCOMPtr<nsIChannel> channel;
   channel.swap(mChannel);
 
   // Bad content is still considered "okay" if the HTTP response is okay
@@ -1010,17 +1010,17 @@ TRR::OnStopRequest(nsIRequest *aRequest,
 
   LOG(("TRR:OnStopRequest %p status %x mFailed %d\n", this, (int)aStatusCode,
        mFailed));
   FailData(NS_ERROR_UNKNOWN_HOST);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-TRR::OnDataAvailable(nsIRequest *aRequest,
+TRR::OnDataAvailable(nsIRequest *aRequest, nsISupports *aContext,
                      nsIInputStream *aInputStream, uint64_t aOffset,
                      const uint32_t aCount) {
   LOG(("TRR:OnDataAvailable %p %s %d failed=%d aCount=%u\n", this, mHost.get(),
        mType, mFailed, (unsigned int)aCount));
   // receive DNS response into the local buffer
   if (mFailed) {
     return NS_ERROR_FAILURE;
   }
--- a/netwerk/protocol/about/nsAboutCacheEntry.cpp
+++ b/netwerk/protocol/about/nsAboutCacheEntry.cpp
@@ -497,26 +497,28 @@ nsAboutCacheEntry::Channel::OnMetaDataEl
   return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 // nsIStreamListener implementation
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
-nsAboutCacheEntry::Channel::OnStartRequest(nsIRequest *request) {
+nsAboutCacheEntry::Channel::OnStartRequest(nsIRequest *request,
+                                           nsISupports *ctx) {
   mHexDumpState = 0;
 
   NS_NAMED_LITERAL_CSTRING(buffer, "<hr/>\n<pre>");
   uint32_t n;
   return mOutputStream->Write(buffer.get(), buffer.Length(), &n);
 }
 
 NS_IMETHODIMP
 nsAboutCacheEntry::Channel::OnDataAvailable(nsIRequest *request,
+                                            nsISupports *ctx,
                                             nsIInputStream *aInputStream,
                                             uint64_t aOffset, uint32_t aCount) {
   uint32_t n;
   return aInputStream->ReadSegments(&nsAboutCacheEntry::Channel::PrintCacheData,
                                     this, aCount, &n);
 }
 
 /* static */ nsresult nsAboutCacheEntry::Channel::PrintCacheData(
@@ -532,17 +534,17 @@ nsAboutCacheEntry::Channel::OnDataAvaila
   a->mOutputStream->Write(buffer.get(), buffer.Length(), &n);
 
   *aWriteCount = aCount;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsAboutCacheEntry::Channel::OnStopRequest(nsIRequest *request,
+nsAboutCacheEntry::Channel::OnStopRequest(nsIRequest *request, nsISupports *ctx,
                                           nsresult result) {
   NS_NAMED_LITERAL_CSTRING(buffer, "</pre>\n");
   uint32_t n;
   mOutputStream->Write(buffer.get(), buffer.Length(), &n);
 
   CloseContent();
 
   return NS_OK;
--- a/netwerk/protocol/data/DataChannelParent.cpp
+++ b/netwerk/protocol/data/DataChannelParent.cpp
@@ -72,33 +72,33 @@ NS_IMETHODIMP
 DataChannelParent::Delete() {
   // Nothing to do.
   return NS_OK;
 }
 
 void DataChannelParent::ActorDestroy(ActorDestroyReason why) {}
 
 NS_IMETHODIMP
-DataChannelParent::OnStartRequest(nsIRequest *aRequest) {
+DataChannelParent::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext) {
   // We don't have a way to prevent nsBaseChannel from calling AsyncOpen on
   // the created nsDataChannel. We don't have anywhere to send the data in the
   // parent, so abort the binding.
   return NS_BINDING_ABORTED;
 }
 
 NS_IMETHODIMP
-DataChannelParent::OnStopRequest(nsIRequest *aRequest,
+DataChannelParent::OnStopRequest(nsIRequest *aRequest, nsISupports *aContext,
                                  nsresult aStatusCode) {
   // See above.
   MOZ_ASSERT(NS_FAILED(aStatusCode));
   return NS_OK;
 }
 
 NS_IMETHODIMP
-DataChannelParent::OnDataAvailable(nsIRequest *aRequest,
+DataChannelParent::OnDataAvailable(nsIRequest *aRequest, nsISupports *aContext,
                                    nsIInputStream *aInputStream,
                                    uint64_t aOffset, uint32_t aCount) {
   // See above.
   MOZ_CRASH("Should never be called");
 }
 
 }  // namespace net
 }  // namespace mozilla
--- a/netwerk/protocol/file/FileChannelParent.cpp
+++ b/netwerk/protocol/file/FileChannelParent.cpp
@@ -72,33 +72,33 @@ NS_IMETHODIMP
 FileChannelParent::Delete() {
   // Nothing to do.
   return NS_OK;
 }
 
 void FileChannelParent::ActorDestroy(ActorDestroyReason why) {}
 
 NS_IMETHODIMP
-FileChannelParent::OnStartRequest(nsIRequest *aRequest) {
+FileChannelParent::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext) {
   // We don't have a way to prevent nsBaseChannel from calling AsyncOpen on
   // the created nsDataChannel. We don't have anywhere to send the data in the
   // parent, so abort the binding.
   return NS_BINDING_ABORTED;
 }
 
 NS_IMETHODIMP
-FileChannelParent::OnStopRequest(nsIRequest *aRequest,
+FileChannelParent::OnStopRequest(nsIRequest *aRequest, nsISupports *aContext,
                                  nsresult aStatusCode) {
   // See above.
   MOZ_ASSERT(NS_FAILED(aStatusCode));
   return NS_OK;
 }
 
 NS_IMETHODIMP
-FileChannelParent::OnDataAvailable(nsIRequest *aRequest,
+FileChannelParent::OnDataAvailable(nsIRequest *aRequest, nsISupports *aContext,
                                    nsIInputStream *aInputStream,
                                    uint64_t aOffset, uint32_t aCount) {
   // See above.
   MOZ_CRASH("Should never be called");
 }
 
 }  // namespace net
 }  // namespace mozilla
--- a/netwerk/protocol/ftp/FTPChannelChild.cpp
+++ b/netwerk/protocol/ftp/FTPChannelChild.cpp
@@ -311,17 +311,17 @@ void FTPChannelChild::DoOnStartRequest(c
     if (NS_FAILED(rv)) {
       Cancel(rv);
     }
   } else {
     Cancel(rv);
   }
 
   AutoEventEnqueuer ensureSerialDispatch(mEventQ);
-  rv = mListener->OnStartRequest(this);
+  rv = mListener->OnStartRequest(this, nullptr);
   if (NS_FAILED(rv)) Cancel(rv);
 
   if (mDivertingToParent) {
     mListener = nullptr;
     if (mLoadGroup) {
       mLoadGroup->RemoveRequest(this, nullptr, mStatus);
     }
   }
@@ -425,17 +425,17 @@ void FTPChannelChild::DoOnDataAvailable(
   nsresult rv = NS_NewByteInputStream(getter_AddRefs(stringStream), data.get(),
                                       count, NS_ASSIGNMENT_DEPEND);
   if (NS_FAILED(rv)) {
     Cancel(rv);
     return;
   }
 
   AutoEventEnqueuer ensureSerialDispatch(mEventQ);
-  rv = mListener->OnDataAvailable(this, stringStream, offset, count);
+  rv = mListener->OnDataAvailable(this, nullptr, stringStream, offset, count);
   if (NS_FAILED(rv)) Cancel(rv);
   stringStream->Close();
 }
 
 class FTPStopRequestEvent : public NeckoTargetChannelEvent<FTPChannelChild> {
  public:
   FTPStopRequestEvent(FTPChannelChild* aChild, const nsresult& aChannelStatus,
                       const nsCString& aErrorMsg, bool aUseUTF8)
@@ -509,17 +509,17 @@ void FTPChannelChild::DoOnStopRequest(co
     mUnknownDecoderEventQ.AppendElement(
         MakeUnique<MaybeDivertOnStopFTPEvent>(this, aChannelStatus));
   }
 
   {  // Ensure that all queued ipdl events are dispatched before
     // we initiate protocol deletion below.
     mIsPending = false;
     AutoEventEnqueuer ensureSerialDispatch(mEventQ);
-    (void)mListener->OnStopRequest(this, aChannelStatus);
+    (void)mListener->OnStopRequest(this, nullptr, aChannelStatus);
 
     mListener = nullptr;
 
     if (mLoadGroup) mLoadGroup->RemoveRequest(this, nullptr, aChannelStatus);
   }
 
   // This calls NeckoChild::DeallocPFTPChannelChild(), which deletes |this| if
   // IPDL holds the last reference.  Don't rely on |this| existing after here!
@@ -549,19 +549,19 @@ mozilla::ipc::IPCResult FTPChannelChild:
 void FTPChannelChild::DoFailedAsyncOpen(const nsresult& statusCode) {
   LOG(("FTPChannelChild::DoFailedAsyncOpen [this=%p status=%" PRIx32 "]\n",
        this, static_cast<uint32_t>(statusCode)));
   mStatus = statusCode;
 
   if (mLoadGroup) mLoadGroup->RemoveRequest(this, nullptr, statusCode);
 
   if (mListener) {
-    mListener->OnStartRequest(this);
+    mListener->OnStartRequest(this, nullptr);
     mIsPending = false;
-    mListener->OnStopRequest(this, statusCode);
+    mListener->OnStopRequest(this, nullptr, statusCode);
   } else {
     mIsPending = false;
   }
 
   mListener = nullptr;
 
   if (mIPCOpen) Send__delete__(this);
 }
--- a/netwerk/protocol/ftp/FTPChannelParent.cpp
+++ b/netwerk/protocol/ftp/FTPChannelParent.cpp
@@ -267,17 +267,17 @@ void FTPChannelParent::DivertOnDataAvail
       mChannel->Cancel(rv);
     }
     mStatus = rv;
     return;
   }
 
   AutoEventEnqueuer ensureSerialDispatch(mEventQ);
 
-  rv = OnDataAvailable(mChannel, stringStream, offset, count);
+  rv = OnDataAvailable(mChannel, nullptr, stringStream, offset, count);
 
   stringStream->Close();
   if (NS_FAILED(rv)) {
     if (mChannel) {
       mChannel->Cancel(rv);
     }
     mStatus = rv;
   }
@@ -327,17 +327,17 @@ void FTPChannelParent::DivertOnStopReque
     nsCOMPtr<nsIForcePendingChannel> forcePendingIChan =
         do_QueryInterface(mChannel);
     if (forcePendingIChan) {
       forcePendingIChan->ForcePending(false);
     }
   }
 
   AutoEventEnqueuer ensureSerialDispatch(mEventQ);
-  OnStopRequest(mChannel, status);
+  OnStopRequest(mChannel, nullptr, status);
 }
 
 class FTPDivertCompleteEvent : public MainThreadChannelEvent {
  public:
   explicit FTPDivertCompleteEvent(FTPChannelParent* aParent)
       : mParent(aParent) {}
 
   void Run() override { mParent->DivertComplete(); }
@@ -374,23 +374,23 @@ void FTPChannelParent::DivertComplete() 
   }
 }
 
 //-----------------------------------------------------------------------------
 // FTPChannelParent::nsIRequestObserver
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
-FTPChannelParent::OnStartRequest(nsIRequest* aRequest) {
+FTPChannelParent::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext) {
   LOG(("FTPChannelParent::OnStartRequest [this=%p]\n", this));
 
   if (mDivertingFromChild) {
     MOZ_RELEASE_ASSERT(mDivertToListener,
                        "Cannot divert if listener is unset!");
-    return mDivertToListener->OnStartRequest(aRequest);
+    return mDivertToListener->OnStartRequest(aRequest, aContext);
   }
 
   nsCOMPtr<nsIChannel> chan = do_QueryInterface(aRequest);
   MOZ_ASSERT(chan);
   NS_ENSURE_TRUE(chan, NS_ERROR_UNEXPECTED);
 
   // Send down any permissions which are relevant to this URL if we are
   // performing a document load.
@@ -435,48 +435,48 @@ FTPChannelParent::OnStartRequest(nsIRequ
                                         lastModified, entityID, uriparam)) {
     return NS_ERROR_UNEXPECTED;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-FTPChannelParent::OnStopRequest(nsIRequest* aRequest,
+FTPChannelParent::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
                                 nsresult aStatusCode) {
   LOG(("FTPChannelParent::OnStopRequest: [this=%p status=%" PRIu32 "]\n", this,
        static_cast<uint32_t>(aStatusCode)));
 
   if (mDivertingFromChild) {
     MOZ_RELEASE_ASSERT(mDivertToListener,
                        "Cannot divert if listener is unset!");
-    return mDivertToListener->OnStopRequest(aRequest, aStatusCode);
+    return mDivertToListener->OnStopRequest(aRequest, aContext, aStatusCode);
   }
 
   if (mIPCClosed || !SendOnStopRequest(aStatusCode, mErrorMsg, mUseUTF8)) {
     return NS_ERROR_UNEXPECTED;
   }
 
   return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 // FTPChannelParent::nsIStreamListener
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
-FTPChannelParent::OnDataAvailable(nsIRequest* aRequest,
+FTPChannelParent::OnDataAvailable(nsIRequest* aRequest, nsISupports* aContext,
                                   nsIInputStream* aInputStream,
                                   uint64_t aOffset, uint32_t aCount) {
   LOG(("FTPChannelParent::OnDataAvailable [this=%p]\n", this));
 
   if (mDivertingFromChild) {
     MOZ_RELEASE_ASSERT(mDivertToListener,
                        "Cannot divert if listener is unset!");
-    return mDivertToListener->OnDataAvailable(aRequest, aInputStream,
+    return mDivertToListener->OnDataAvailable(aRequest, aContext, aInputStream,
                                               aOffset, aCount);
   }
 
   nsCString data;
   nsresult rv = NS_ReadInputStreamToString(aInputStream, data, aCount);
   if (NS_FAILED(rv)) return rv;
 
   if (mIPCClosed || !SendOnDataAvailable(mStatus, data, aOffset, aCount))
@@ -714,17 +714,17 @@ void FTPChannelParent::StartDiversion() 
     if (forcePendingIChan) {
       forcePendingIChan->ForcePending(true);
     }
   }
 
   {
     AutoEventEnqueuer ensureSerialDispatch(mEventQ);
     // Call OnStartRequest for the "DivertTo" listener.
-    nsresult rv = OnStartRequest(mChannel);
+    nsresult rv = OnStartRequest(mChannel, nullptr);
     if (NS_FAILED(rv)) {
       if (mChannel) {
         mChannel->Cancel(rv);
       }
       mStatus = rv;
       return;
     }
   }
@@ -794,26 +794,26 @@ void FTPChannelParent::NotifyDiversionFa
   // Channel has already sent OnStartRequest to the child, so ensure that we
   // call it here if it hasn't already been called.
   if (!mDivertedOnStartRequest) {
     nsCOMPtr<nsIForcePendingChannel> forcePendingIChan =
         do_QueryInterface(mChannel);
     if (forcePendingIChan) {
       forcePendingIChan->ForcePending(true);
     }
-    mDivertToListener->OnStartRequest(mChannel);
+    mDivertToListener->OnStartRequest(mChannel, nullptr);
 
     if (forcePendingIChan) {
       forcePendingIChan->ForcePending(false);
     }
   }
   // If the channel is pending, it will call OnStopRequest itself; otherwise, do
   // it here.
   if (!isPending) {
-    mDivertToListener->OnStopRequest(mChannel, aErrorCode);
+    mDivertToListener->OnStopRequest(mChannel, nullptr, aErrorCode);
   }
   mDivertToListener = nullptr;
   mChannel = nullptr;
 
   if (!mIPCClosed) {
     Unused << SendDeleteSelf();
   }
 }
--- a/netwerk/protocol/ftp/nsFtpConnectionThread.cpp
+++ b/netwerk/protocol/ftp/nsFtpConnectionThread.cpp
@@ -1791,23 +1791,23 @@ nsFtpState::OnTransportStatus(nsITranspo
   mChannel->OnTransportStatus(nullptr, status, progress,
                               mFileSize - mChannel->StartPos());
   return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
-nsFtpState::OnStartRequest(nsIRequest *request) {
+nsFtpState::OnStartRequest(nsIRequest *request, nsISupports *context) {
   mStorReplyReceived = false;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsFtpState::OnStopRequest(nsIRequest *request,
+nsFtpState::OnStopRequest(nsIRequest *request, nsISupports *context,
                           nsresult status) {
   mUploadRequest = nullptr;
 
   // Close() will be called when reply to STOR command is received
   // see bug #389394
   if (!mStorReplyReceived) return NS_OK;
 
   // We're done uploading.  Let our consumer know that we're done.
--- a/netwerk/protocol/http/AlternateServices.cpp
+++ b/netwerk/protocol/http/AlternateServices.cpp
@@ -763,25 +763,27 @@ void TransactionObserver::Complete(nsHtt
   mAuthOK = !socketControl->GetFailedVerification();
   LOG(("TransactionObserve::Complete %p trans %p authOK %d versionOK %d\n",
        this, aTrans, mAuthOK, mVersionOK));
 }
 
 #define MAX_WK 32768
 
 NS_IMETHODIMP
-TransactionObserver::OnStartRequest(nsIRequest *aRequest) {
+TransactionObserver::OnStartRequest(nsIRequest *aRequest,
+                                    nsISupports *aContext) {
   MOZ_ASSERT(NS_IsMainThread());
   // only consider the first 32KB.. because really.
   mWKResponse.SetCapacity(MAX_WK);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 TransactionObserver::OnDataAvailable(nsIRequest *aRequest,
+                                     nsISupports *aContext,
                                      nsIInputStream *aStream, uint64_t aOffset,
                                      uint32_t aCount) {
   MOZ_ASSERT(NS_IsMainThread());
   uint32_t oldLen = mWKResponse.Length();
   uint64_t newLen = aCount + oldLen;
   if (newLen < MAX_WK) {
     nsresult rv;
     auto handle = mWKResponse.BulkWrite(newLen, oldLen, false, rv);
@@ -798,17 +800,17 @@ TransactionObserver::OnDataAvailable(nsI
     } else {
       LOG(("TransactionObserver onDataAvailable %p read error\n", this));
     }
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
-TransactionObserver::OnStopRequest(nsIRequest *aRequest,
+TransactionObserver::OnStopRequest(nsIRequest *aRequest, nsISupports *aContext,
                                    nsresult code) {
   MOZ_ASSERT(NS_IsMainThread());
   LOG(("TransactionObserver onStopRequest %p code %" PRIx32 "\n", this,
        static_cast<uint32_t>(code)));
   if (NS_SUCCEEDED(code)) {
     nsHttpResponseHead *hdrs = mChannel->GetResponseHead();
     LOG(("TransactionObserver onStopRequest %p http resp %d\n", this,
          hdrs ? hdrs->Status() : -1));
--- a/netwerk/protocol/http/HttpBaseChannel.cpp
+++ b/netwerk/protocol/http/HttpBaseChannel.cpp
@@ -1144,34 +1144,35 @@ class InterceptFailedOnStop : public nsI
   nsCOMPtr<nsIStreamListener> mNext;
   HttpBaseChannel* mChannel;
 
  public:
   InterceptFailedOnStop(nsIStreamListener* arg, HttpBaseChannel* chan)
       : mNext(arg), mChannel(chan) {}
   NS_DECL_THREADSAFE_ISUPPORTS
 
-  NS_IMETHOD OnStartRequest(nsIRequest* aRequest) override {
-    return mNext->OnStartRequest(aRequest);
+  NS_IMETHOD OnStartRequest(nsIRequest* aRequest,
+                            nsISupports* aContext) override {
+    return mNext->OnStartRequest(aRequest, aContext);
   }
 
-  NS_IMETHOD OnStopRequest(nsIRequest* aRequest,
+  NS_IMETHOD OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
                            nsresult aStatusCode) override {
     if (NS_FAILED(aStatusCode) && NS_SUCCEEDED(mChannel->mStatus)) {
       LOG(("HttpBaseChannel::InterceptFailedOnStop %p seting status %" PRIx32,
            mChannel, static_cast<uint32_t>(aStatusCode)));
       mChannel->mStatus = aStatusCode;
     }
-    return mNext->OnStopRequest(aRequest, aStatusCode);
+    return mNext->OnStopRequest(aRequest, aContext, aStatusCode);
   }
 
-  NS_IMETHOD OnDataAvailable(nsIRequest* aRequest,
+  NS_IMETHOD OnDataAvailable(nsIRequest* aRequest, nsISupports* aContext,
                              nsIInputStream* aInputStream, uint64_t aOffset,
                              uint32_t aCount) override {
-    return mNext->OnDataAvailable(aRequest, aInputStream, aOffset,
+    return mNext->OnDataAvailable(aRequest, aContext, aInputStream, aOffset,
                                   aCount);
   }
 };
 
 NS_IMPL_ISUPPORTS(InterceptFailedOnStop, nsIStreamListener, nsIRequestObserver)
 
 NS_IMETHODIMP
 HttpBaseChannel::DoApplyContentConversions(nsIStreamListener* aNextListener,
@@ -3288,29 +3289,29 @@ void HttpBaseChannel::DoNotifyListener()
   // LOAD_ONLY_IF_MODIFIED) we want to set mAfterOnStartRequestBegun to true
   // before notifying listener.
   if (!mAfterOnStartRequestBegun) {
     mAfterOnStartRequestBegun = true;
   }
 
   if (mListener && !mOnStartRequestCalled) {
     nsCOMPtr<nsIStreamListener> listener = mListener;
-    listener->OnStartRequest(this);
+    listener->OnStartRequest(this, nullptr);
 
     mOnStartRequestCalled = true;
   }
 
   // Make sure mIsPending is set to false. At this moment we are done from
   // the point of view of our consumer and we have to report our self
   // as not-pending.
   mIsPending = false;
 
   if (mListener && !mOnStopRequestCalled) {
     nsCOMPtr<nsIStreamListener> listener = mListener;
-    listener->OnStopRequest(this, mStatus);
+    listener->OnStopRequest(this, nullptr, mStatus);
 
     mOnStopRequestCalled = true;
   }
 
   // notify "http-on-stop-connect" observers
   gHttpHandler->OnStopRequest(this);
 
   // This channel has finished its job, potentially release any tail-blocked
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -79,19 +79,20 @@ using namespace mozilla::ipc;
 
 namespace mozilla {
 namespace net {
 
 NS_IMPL_ISUPPORTS(InterceptStreamListener, nsIStreamListener,
                   nsIRequestObserver, nsIProgressEventSink)
 
 NS_IMETHODIMP
-InterceptStreamListener::OnStartRequest(nsIRequest* aRequest) {
+InterceptStreamListener::OnStartRequest(nsIRequest* aRequest,
+                                        nsISupports* aContext) {
   if (mOwner) {
-    mOwner->DoOnStartRequest(mOwner, nullptr);
+    mOwner->DoOnStartRequest(mOwner, mContext);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 InterceptStreamListener::OnStatus(nsIRequest* aRequest, nsISupports* aContext,
                                   nsresult status, const char16_t* aStatusArg) {
   if (mOwner) {
@@ -106,45 +107,47 @@ InterceptStreamListener::OnProgress(nsIR
   if (mOwner) {
     mOwner->DoOnProgress(mOwner, aProgress, aProgressMax);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 InterceptStreamListener::OnDataAvailable(nsIRequest* aRequest,
+                                         nsISupports* aContext,
                                          nsIInputStream* aInputStream,
                                          uint64_t aOffset, uint32_t aCount) {
   if (!mOwner) {
     return NS_OK;
   }
 
   uint32_t loadFlags;
   mOwner->GetLoadFlags(&loadFlags);
 
   if (!(loadFlags & HttpBaseChannel::LOAD_BACKGROUND)) {
     nsCOMPtr<nsIURI> uri;
     mOwner->GetURI(getter_AddRefs(uri));
 
     nsAutoCString host;
     uri->GetHost(host);
 
-    OnStatus(mOwner, nullptr, NS_NET_STATUS_READING,
+    OnStatus(mOwner, aContext, NS_NET_STATUS_READING,
              NS_ConvertUTF8toUTF16(host).get());
 
     int64_t progress = aOffset + aCount;
-    OnProgress(mOwner, nullptr, progress, mOwner->mSynthesizedStreamLength);
+    OnProgress(mOwner, aContext, progress, mOwner->mSynthesizedStreamLength);
   }
 
-  mOwner->DoOnDataAvailable(mOwner, nullptr, aInputStream, aOffset, aCount);
+  mOwner->DoOnDataAvailable(mOwner, mContext, aInputStream, aOffset, aCount);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 InterceptStreamListener::OnStopRequest(nsIRequest* aRequest,
+                                       nsISupports* aContext,
                                        nsresult aStatusCode) {
   if (mOwner) {
     mOwner->DoPreOnStopRequest(aStatusCode);
     mOwner->DoOnStopRequest(mOwner, aStatusCode, mContext);
   }
   Cleanup();
   return NS_OK;
 }
@@ -600,34 +603,34 @@ class SyntheticDiversionListener final :
 
  public:
   explicit SyntheticDiversionListener(HttpChannelChild* aChannel)
       : mChannel(aChannel) {
     MOZ_ASSERT(mChannel);
   }
 
   NS_IMETHOD
-  OnStartRequest(nsIRequest* aRequest) override {
+  OnStartRequest(nsIRequest* aRequest, nsISupports* aContext) override {
     MOZ_ASSERT_UNREACHABLE(
         "SyntheticDiversionListener should never see OnStartRequest");
     return NS_OK;
   }
 
   NS_IMETHOD
-  OnStopRequest(nsIRequest* aRequest,
+  OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
                 nsresult aStatus) override {
     if (mChannel->mIPCOpen) {
       mChannel->SendDivertOnStopRequest(aStatus);
       mChannel->SendDivertComplete();
     }
     return NS_OK;
   }
 
   NS_IMETHOD
-  OnDataAvailable(nsIRequest* aRequest,
+  OnDataAvailable(nsIRequest* aRequest, nsISupports* aContext,
                   nsIInputStream* aInputStream, uint64_t aOffset,
                   uint32_t aCount) override {
     if (!mChannel->mIPCOpen) {
       aRequest->Cancel(NS_ERROR_ABORT);
       return NS_ERROR_ABORT;
     }
 
     nsAutoCString data;
@@ -657,17 +660,17 @@ void HttpChannelChild::DoOnStartRequest(
     return;
   }
 
   if (mSynthesizedResponsePump && mLoadFlags & LOAD_CALL_CONTENT_SNIFFERS) {
     mSynthesizedResponsePump->PeekStream(CallTypeSniffers,
                                          static_cast<nsIChannel*>(this));
   }
 
-  nsresult rv = mListener->OnStartRequest(aRequest);
+  nsresult rv = mListener->OnStartRequest(aRequest, aContext);
   if (NS_FAILED(rv)) {
     Cancel(rv);
     return;
   }
   mOnStartRequestCalled = true;
 
   if (mDivertingToParent) {
     mListener = nullptr;
@@ -956,17 +959,17 @@ void HttpChannelChild::DoOnDataAvailable
                                          nsISupports* aContext,
                                          nsIInputStream* aStream,
                                          uint64_t offset, uint32_t count) {
   AUTO_PROFILER_LABEL("HttpChannelChild::DoOnDataAvailable", NETWORK);
   LOG(("HttpChannelChild::DoOnDataAvailable [this=%p]\n", this));
   if (mCanceled) return;
 
   nsresult rv =
-      mListener->OnDataAvailable(aRequest, aStream, offset, count);
+      mListener->OnDataAvailable(aRequest, aContext, aStream, offset, count);
   if (NS_FAILED(rv)) {
     CancelOnMainThread(rv);
   }
 }
 
 class StopRequestEvent : public NeckoTargetChannelEvent<HttpChannelChild> {
  public:
   StopRequestEvent(HttpChannelChild* child, const nsresult& channelStatus,
@@ -1220,17 +1223,17 @@ void HttpChannelChild::DoOnStopRequest(n
   };
   checkForBlockedContent();
 
   MOZ_ASSERT(!mOnStopRequestCalled, "We should not call OnStopRequest twice");
 
   // In theory mListener should not be null, but in practice sometimes it is.
   MOZ_ASSERT(mListener);
   if (mListener) {
-    mListener->OnStopRequest(aRequest, mStatus);
+    mListener->OnStopRequest(aRequest, aContext, mStatus);
   }
   mOnStopRequestCalled = true;
 
   // notify "http-on-stop-connect" observers
   gHttpHandler->OnStopRequest(this);
 
   ReleaseListeners();
 
--- a/netwerk/protocol/http/HttpChannelParent.cpp
+++ b/netwerk/protocol/http/HttpChannelParent.cpp
@@ -1085,17 +1085,17 @@ void HttpChannelParent::DivertOnDataAvai
       mChannel->Cancel(rv);
     }
     mStatus = rv;
     return;
   }
 
   AutoEventEnqueuer ensureSerialDispatch(mEventQ);
 
-  rv = mParentListener->OnDataAvailable(mChannel, stringStream, offset,
+  rv = mParentListener->OnDataAvailable(mChannel, nullptr, stringStream, offset,
                                         count);
   stringStream->Close();
   if (NS_FAILED(rv)) {
     if (mChannel) {
       mChannel->Cancel(rv);
     }
     mStatus = rv;
   }
@@ -1144,17 +1144,17 @@ void HttpChannelParent::DivertOnStopRequ
   nsresult status = NS_FAILED(mStatus) ? mStatus : statusCode;
 
   // Reset fake pending status in case OnStopRequest has already been called.
   if (mChannel) {
     mChannel->ForcePending(false);
   }
 
   AutoEventEnqueuer ensureSerialDispatch(mEventQ);
-  mParentListener->OnStopRequest(mChannel, status);
+  mParentListener->OnStopRequest(mChannel, nullptr, status);
 }
 
 class DivertCompleteEvent : public MainThreadChannelEvent {
  public:
   explicit DivertCompleteEvent(HttpChannelParent* aParent) : mParent(aParent) {}
 
   void Run() override { mParent->DivertComplete(); }
 
@@ -1304,17 +1304,17 @@ static void GetTimingAttributes(HttpBase
   // to be passed down.
   aChannel->GetProtocolVersion(aTiming.protocolVersion);
 
   aChannel->GetCacheReadStart(&aTiming.cacheReadStart);
   aChannel->GetCacheReadEnd(&aTiming.cacheReadEnd);
 }
 
 NS_IMETHODIMP
-HttpChannelParent::OnStartRequest(nsIRequest* aRequest) {
+HttpChannelParent::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext) {
   nsresult rv;
 
   LOG(("HttpChannelParent::OnStartRequest [this=%p, aRequest=%p]\n", this,
        aRequest));
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_RELEASE_ASSERT(!mDivertingFromChild,
                      "Cannot call OnStartRequest if diverting is set!");
 
@@ -1474,17 +1474,17 @@ HttpChannelParent::OnStartRequest(nsIReq
       rv = NS_ERROR_UNEXPECTED;
     }
   }
 
   return rv;
 }
 
 NS_IMETHODIMP
-HttpChannelParent::OnStopRequest(nsIRequest* aRequest,
+HttpChannelParent::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
                                  nsresult aStatusCode) {
   LOG(("HttpChannelParent::OnStopRequest: [this=%p aRequest=%p status=%" PRIx32
        "]\n",
        this, aRequest, static_cast<uint32_t>(aStatusCode)));
   MOZ_ASSERT(NS_IsMainThread());
 
   if (mDoingCrossProcessRedirect) {
     LOG(("Child was cancelled for cross-process redirect. Bail."));
@@ -1560,17 +1560,17 @@ HttpChannelParent::OnStopRequest(nsIRequ
   return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 // HttpChannelParent::nsIStreamListener
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
-HttpChannelParent::OnDataAvailable(nsIRequest* aRequest,
+HttpChannelParent::OnDataAvailable(nsIRequest* aRequest, nsISupports* aContext,
                                    nsIInputStream* aInputStream,
                                    uint64_t aOffset, uint32_t aCount) {
   LOG(("HttpChannelParent::OnDataAvailable [this=%p aRequest=%p offset=%" PRIu64
        " count=%" PRIu32 "]\n",
        this, aRequest, aOffset, aCount));
   MOZ_ASSERT(NS_IsMainThread());
 
   MOZ_RELEASE_ASSERT(!mDivertingFromChild,
@@ -2234,17 +2234,17 @@ void HttpChannelParent::StartDiversion()
   if (mChannel) {
     mChannel->ForcePending(true);
   }
 
   {
     AutoEventEnqueuer ensureSerialDispatch(mEventQ);
 
     // Call OnStartRequest for the "DivertTo" listener.
-    nsresult rv = mDivertListener->OnStartRequest(mChannel);
+    nsresult rv = mDivertListener->OnStartRequest(mChannel, nullptr);
     if (NS_FAILED(rv)) {
       if (mChannel) {
         mChannel->Cancel(rv);
       }
       mStatus = rv;
     }
   }
   mDivertedOnStartRequest = true;
@@ -2325,23 +2325,23 @@ void HttpChannelParent::NotifyDiversionF
     nsCOMPtr<nsIChannelWithDivertableParentListener> divertChannel =
         do_QueryInterface(static_cast<nsIChannel*>(mChannel.get()));
     divertChannel->ResumeInternal();
   }
   // Channel has already sent OnStartRequest to the child, so ensure that we
   // call it here if it hasn't already been called.
   if (!mDivertedOnStartRequest) {
     mChannel->ForcePending(true);
-    mParentListener->OnStartRequest(mChannel);
+    mParentListener->OnStartRequest(mChannel, nullptr);
     mChannel->ForcePending(false);
   }
   // If the channel is pending, it will call OnStopRequest itself; otherwise, do
   // it here.
   if (!isPending) {
-    mParentListener->OnStopRequest(mChannel, aErrorCode);
+    mParentListener->OnStopRequest(mChannel, nullptr, aErrorCode);
   }
 
   if (!mIPCClosed) {
     Unused << DoSendDeleteSelf();
   }
 
   // DoSendDeleteSelf will need channel Id to remove the strong reference in
   // BackgroundChannelRegistrar if channel pairing is aborted.
--- a/netwerk/protocol/http/HttpChannelParentListener.cpp
+++ b/netwerk/protocol/http/HttpChannelParentListener.cpp
@@ -66,58 +66,61 @@ NS_INTERFACE_MAP_BEGIN(HttpChannelParent
   NS_INTERFACE_MAP_ENTRY_CONCRETE(HttpChannelParentListener)
 NS_INTERFACE_MAP_END
 
 //-----------------------------------------------------------------------------
 // HttpChannelParentListener::nsIRequestObserver
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
-HttpChannelParentListener::OnStartRequest(nsIRequest* aRequest) {
+HttpChannelParentListener::OnStartRequest(nsIRequest* aRequest,
+                                          nsISupports* aContext) {
   MOZ_RELEASE_ASSERT(!mSuspendedForDiversion,
                      "Cannot call OnStartRequest if suspended for diversion!");
 
   if (!mNextListener) return NS_ERROR_UNEXPECTED;
 
   LOG(("HttpChannelParentListener::OnStartRequest [this=%p]\n", this));
-  return mNextListener->OnStartRequest(aRequest);
+  return mNextListener->OnStartRequest(aRequest, aContext);
 }
 
 NS_IMETHODIMP
 HttpChannelParentListener::OnStopRequest(nsIRequest* aRequest,
+                                         nsISupports* aContext,
                                          nsresult aStatusCode) {
   MOZ_RELEASE_ASSERT(!mSuspendedForDiversion,
                      "Cannot call OnStopRequest if suspended for diversion!");
 
   if (!mNextListener) return NS_ERROR_UNEXPECTED;
 
   LOG(("HttpChannelParentListener::OnStopRequest: [this=%p status=%" PRIu32
        "]\n",
        this, static_cast<uint32_t>(aStatusCode)));
-  nsresult rv = mNextListener->OnStopRequest(aRequest, aStatusCode);
+  nsresult rv = mNextListener->OnStopRequest(aRequest, aContext, aStatusCode);
 
   mNextListener = nullptr;
   return rv;
 }
 
 //-----------------------------------------------------------------------------
 // HttpChannelParentListener::nsIStreamListener
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 HttpChannelParentListener::OnDataAvailable(nsIRequest* aRequest,
+                                           nsISupports* aContext,
                                            nsIInputStream* aInputStream,
                                            uint64_t aOffset, uint32_t aCount) {
   MOZ_RELEASE_ASSERT(!mSuspendedForDiversion,
                      "Cannot call OnDataAvailable if suspended for diversion!");
 
   if (!mNextListener) return NS_ERROR_UNEXPECTED;
 
   LOG(("HttpChannelParentListener::OnDataAvailable [this=%p]\n", this));
-  return mNextListener->OnDataAvailable(aRequest, aInputStream,
+  return mNextListener->OnDataAvailable(aRequest, aContext, aInputStream,
                                         aOffset, aCount);
 }
 
 //-----------------------------------------------------------------------------
 // HttpChannelParentListener::nsIInterfaceRequestor
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
--- a/netwerk/protocol/http/InterceptedHttpChannel.cpp
+++ b/netwerk/protocol/http/InterceptedHttpChannel.cpp
@@ -1003,36 +1003,37 @@ InterceptedHttpChannel::OnRedirectVerify
 
   mIsPending = false;
   ReleaseListeners();
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-InterceptedHttpChannel::OnStartRequest(nsIRequest* aRequest) {
+InterceptedHttpChannel::OnStartRequest(nsIRequest* aRequest,
+                                       nsISupports* aContext) {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (!mProgressSink) {
     GetCallback(mProgressSink);
   }
 
   if (mPump && mLoadFlags & LOAD_CALL_CONTENT_SNIFFERS) {
     mPump->PeekStream(CallTypeSniffers, static_cast<nsIChannel*>(this));
   }
 
   if (mListener) {
-    mListener->OnStartRequest(this);
+    mListener->OnStartRequest(this, nullptr);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 InterceptedHttpChannel::OnStopRequest(nsIRequest* aRequest,
-                                      nsresult aStatus) {
+                                      nsISupports* aContext, nsresult aStatus) {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (NS_SUCCEEDED(mStatus)) {
     mStatus = aStatus;
   }
 
   MaybeCallBodyCallback();
 
@@ -1043,28 +1044,29 @@ InterceptedHttpChannel::OnStopRequest(ns
   MaybeCallStatusAndProgress();
 
   mIsPending = false;
 
   // Register entry to the PerformanceStorage resource timing
   MaybeReportTimingData();
 
   if (mListener) {
-    mListener->OnStopRequest(this, mStatus);
+    mListener->OnStopRequest(this, nullptr, mStatus);
   }
 
   gHttpHandler->OnStopRequest(this);
 
   ReleaseListeners();
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 InterceptedHttpChannel::OnDataAvailable(nsIRequest* aRequest,
+                                        nsISupports* aContext,
                                         nsIInputStream* aInputStream,
                                         uint64_t aOffset, uint32_t aCount) {
   // Any thread if the channel has been retargeted.
 
   if (mCanceled || !mListener) {
     // If there is no listener, we still need to drain the stream in order
     // maintain necko invariants.
     uint32_t unused = 0;
@@ -1073,17 +1075,17 @@ InterceptedHttpChannel::OnDataAvailable(
   }
   if (mProgressSink) {
     if (!(mLoadFlags & HttpBaseChannel::LOAD_BACKGROUND)) {
       mProgress = aOffset + aCount;
       MaybeCallStatusAndProgress();
     }
   }
 
-  return mListener->OnDataAvailable(this, aInputStream, aOffset,
+  return mListener->OnDataAvailable(this, nullptr, aInputStream, aOffset,
                                     aCount);
 }
 
 NS_IMETHODIMP
 InterceptedHttpChannel::MessageDiversionStarted(
     ADivertableParentChannel* aParentChannel) {
   MOZ_ASSERT(!mParentChannel);
   mParentChannel = aParentChannel;
--- a/netwerk/protocol/http/nsCORSListenerProxy.cpp
+++ b/netwerk/protocol/http/nsCORSListenerProxy.cpp
@@ -412,17 +412,18 @@ nsresult nsCORSListenerProxy::Init(nsICh
   }
 #ifdef DEBUG
   mInited = true;
 #endif
   return rv;
 }
 
 NS_IMETHODIMP
-nsCORSListenerProxy::OnStartRequest(nsIRequest* aRequest) {
+nsCORSListenerProxy::OnStartRequest(nsIRequest* aRequest,
+                                    nsISupports* aContext) {
   MOZ_ASSERT(mInited, "nsCORSListenerProxy has not been initialized properly");
   nsresult rv = CheckRequestApproved(aRequest);
   mRequestApproved = NS_SUCCEEDED(rv);
   if (!mRequestApproved) {
     nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
     if (channel) {
       nsCOMPtr<nsIURI> uri;
       NS_GetFinalChannelURI(channel, getter_AddRefs(uri));
@@ -448,28 +449,28 @@ nsCORSListenerProxy::OnStartRequest(nsIR
     }
 
     aRequest->Cancel(NS_ERROR_DOM_BAD_URI);
     nsCOMPtr<nsIStreamListener> listener;
     {
       MutexAutoLock lock(mMutex);
       listener = mOuterListener;
     }
-    listener->OnStartRequest(aRequest);
+    listener->OnStartRequest(aRequest, aContext);
 
     // Reason for NS_ERROR_DOM_BAD_URI already logged in CheckRequestApproved()
     return NS_ERROR_DOM_BAD_URI;
   }
 
   nsCOMPtr<nsIStreamListener> listener;
   {
     MutexAutoLock lock(mMutex);
     listener = mOuterListener;
   }
-  return listener->OnStartRequest(aRequest);
+  return listener->OnStartRequest(aRequest, aContext);
 }
 
 namespace {
 class CheckOriginHeader final : public nsIHttpHeaderVisitor {
  public:
   NS_DECL_ISUPPORTS
 
   CheckOriginHeader() : mHeaderCount(0) {}
@@ -598,49 +599,50 @@ nsresult nsCORSListenerProxy::CheckReque
       return NS_ERROR_DOM_BAD_URI;
     }
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCORSListenerProxy::OnStopRequest(nsIRequest* aRequest,
+nsCORSListenerProxy::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
                                    nsresult aStatusCode) {
   MOZ_ASSERT(mInited, "nsCORSListenerProxy has not been initialized properly");
   nsCOMPtr<nsIStreamListener> listener;
   {
     MutexAutoLock lock(mMutex);
     listener = mOuterListener.forget();
   }
-  nsresult rv = listener->OnStopRequest(aRequest, aStatusCode);
+  nsresult rv = listener->OnStopRequest(aRequest, aContext, aStatusCode);
   mOuterNotificationCallbacks = nullptr;
   mHttpChannel = nullptr;
   return rv;
 }
 
 NS_IMETHODIMP
 nsCORSListenerProxy::OnDataAvailable(nsIRequest* aRequest,
+                                     nsISupports* aContext,
                                      nsIInputStream* aInputStream,
                                      uint64_t aOffset, uint32_t aCount) {
   // NB: This can be called on any thread!  But we're guaranteed that it is
   // called between OnStartRequest and OnStopRequest, so we don't need to worry
   // about races.
 
   MOZ_ASSERT(mInited, "nsCORSListenerProxy has not been initialized properly");
   if (!mRequestApproved) {
     // Reason for NS_ERROR_DOM_BAD_URI already logged in CheckRequestApproved()
     return NS_ERROR_DOM_BAD_URI;
   }
   nsCOMPtr<nsIStreamListener> listener;
   {
     MutexAutoLock lock(mMutex);
     listener = mOuterListener;
   }
-  return listener->OnDataAvailable(aRequest, aInputStream, aOffset,
+  return listener->OnDataAvailable(aRequest, aContext, aInputStream, aOffset,
                                    aCount);
 }
 
 void nsCORSListenerProxy::SetInterceptController(
     nsINetworkInterceptController* aInterceptController) {
   mInterceptController = aInterceptController;
 }
 
@@ -1203,17 +1205,18 @@ void nsCORSPreflightListener::AddResultT
 
       newHeader->token = header;
       newHeader->expirationTime = expirationTime;
     }
   }
 }
 
 NS_IMETHODIMP
-nsCORSPreflightListener::OnStartRequest(nsIRequest* aRequest) {
+nsCORSPreflightListener::OnStartRequest(nsIRequest* aRequest,
+                                        nsISupports* aContext) {
 #ifdef DEBUG
   {
     nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
     nsCOMPtr<nsILoadInfo> loadInfo = channel ? channel->LoadInfo() : nullptr;
     MOZ_ASSERT(!loadInfo || !loadInfo->GetServiceWorkerTaintingSynthesized());
   }
 #endif
 
@@ -1228,25 +1231,27 @@ nsCORSPreflightListener::OnStartRequest(
     mCallback->OnPreflightFailed(rv);
   }
 
   return rv;
 }
 
 NS_IMETHODIMP
 nsCORSPreflightListener::OnStopRequest(nsIRequest* aRequest,
+                                       nsISupports* aContext,
                                        nsresult aStatus) {
   mCallback = nullptr;
   return NS_OK;
 }
 
 /** nsIStreamListener methods **/
 
 NS_IMETHODIMP
 nsCORSPreflightListener::OnDataAvailable(nsIRequest* aRequest,
+                                         nsISupports* ctxt,
                                          nsIInputStream* inStr,
                                          uint64_t sourceOffset,
                                          uint32_t count) {
   uint32_t totalRead;
   return inStr->ReadSegments(NS_DiscardSegment, nullptr, count, &totalRead);
 }
 
 NS_IMETHODIMP
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -1625,17 +1625,17 @@ nsresult nsHttpChannel::CallOnStartReque
     LOG(
         ("  calling mListener->OnStartRequest by ScopeExit [this=%p, "
          "listener=%p]\n",
          this, mListener.get()));
     MOZ_ASSERT(!mOnStartRequestCalled);
 
     if (mListener) {
       nsCOMPtr<nsIStreamListener> deleteProtector(mListener);
-      deleteProtector->OnStartRequest(this);
+      deleteProtector->OnStartRequest(this, nullptr);
     }
 
     mOnStartRequestCalled = true;
   });
 
   nsresult rv = EnsureMIMEOfScript(this, mURI, mResponseHead, mLoadInfo);
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -1697,17 +1697,17 @@ nsresult nsHttpChannel::CallOnStartReque
 
   // About to call OnStartRequest, dismiss the guard object.
   onStartGuard.release();
 
   if (mListener) {
     MOZ_ASSERT(!mOnStartRequestCalled,
                "We should not call OsStartRequest twice");
     nsCOMPtr<nsIStreamListener> deleteProtector(mListener);
-    rv = deleteProtector->OnStartRequest(this);
+    rv = deleteProtector->OnStartRequest(this, nullptr);
     mOnStartRequestCalled = true;
     if (NS_FAILED(rv)) return rv;
   } else {
     NS_WARNING("OnStartRequest skipped because of null listener");
     mOnStartRequestCalled = true;
   }
 
   // Install stream converter if required.
@@ -7304,17 +7304,17 @@ nsHttpChannel::HasCrossOriginOpenerPolic
       return NS_OK;
     }
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsHttpChannel::OnStartRequest(nsIRequest *request) {
+nsHttpChannel::OnStartRequest(nsIRequest *request, nsISupports *ctxt) {
   nsresult rv;
 
   MOZ_ASSERT(mRequestObserversCalled);
 
   AUTO_PROFILER_LABEL("nsHttpChannel::OnStartRequest", NETWORK);
 
   if (!(mCanceled || NS_FAILED(mStatus)) &&
       !WRONG_RACING_RESPONSE_SOURCE(request)) {
@@ -7528,17 +7528,17 @@ nsresult nsHttpChannel::ContinueOnStartR
   LOG(("nsHttpChannel::ContinueOnStartRequest4 [this=%p]", this));
 
   if (mFallingBack) return NS_OK;
 
   return CallOnStartRequest();
 }
 
 NS_IMETHODIMP
-nsHttpChannel::OnStopRequest(nsIRequest *request,
+nsHttpChannel::OnStopRequest(nsIRequest *request, nsISupports *ctxt,
                              nsresult status) {
   AUTO_PROFILER_LABEL("nsHttpChannel::OnStopRequest", NETWORK);
 
   LOG(("nsHttpChannel::OnStopRequest [this=%p request=%p status=%" PRIx32 "]\n",
        this, request, static_cast<uint32_t>(status)));
 
   LOG(("OnStopRequest %p requestFromCache: %d mFirstResponseSource: %d\n", this,
        request == mCachePump, static_cast<int32_t>(mFirstResponseSource)));
@@ -7733,17 +7733,17 @@ nsresult nsHttpChannel::ContinueOnStopRe
     MOZ_ASSERT(NS_FAILED(aStatus), "should have a failure code here");
     // NOTE: since we have a failure status, we can ignore the return
     // value from onStartRequest.
     LOG(("  calling mListener->OnStartRequest [this=%p, listener=%p]\n", this,
          mListener.get()));
     if (mListener) {
       MOZ_ASSERT(!mOnStartRequestCalled,
                  "We should not call OnStartRequest twice.");
-      mListener->OnStartRequest(this);
+      mListener->OnStartRequest(this, nullptr);
       mOnStartRequestCalled = true;
     } else {
       NS_WARNING("OnStartRequest skipped because of null listener");
     }
   }
 
   // if this transaction has been replaced, then bail.
   if (mTransactionReplaced) {
@@ -7936,17 +7936,17 @@ nsresult nsHttpChannel::ContinueOnStopRe
   }
 #endif
 
   if (mListener) {
     LOG(("nsHttpChannel %p calling OnStopRequest\n", this));
     MOZ_ASSERT(mOnStartRequestCalled,
                "OnStartRequest should be called before OnStopRequest");
     MOZ_ASSERT(!mOnStopRequestCalled, "We should not call OnStopRequest twice");
-    mListener->OnStopRequest(this, aStatus);
+    mListener->OnStopRequest(this, nullptr, aStatus);
     mOnStopRequestCalled = true;
   }
 
   // notify "http-on-stop-connect" observers
   gHttpHandler->OnStopRequest(this);
 
   RemoveAsNonTailRequest();
 
@@ -8003,17 +8003,17 @@ class OnTransportStatusAsyncEvent : publ
  private:
   nsCOMPtr<nsITransportEventSink> mEventSink;
   nsresult mTransportStatus;
   int64_t mProgress;
   int64_t mProgressMax;
 };
 
 NS_IMETHODIMP
-nsHttpChannel::OnDataAvailable(nsIRequest *request,
+nsHttpChannel::OnDataAvailable(nsIRequest *request, nsISupports *ctxt,
                                nsIInputStream *input, uint64_t offset,
                                uint32_t count) {
   nsresult rv;
   AUTO_PROFILER_LABEL("nsHttpChannel::OnDataAvailable", NETWORK);
 
   LOG(("nsHttpChannel::OnDataAvailable [this=%p request=%p offset=%" PRIu64
        " count=%" PRIu32 "]\n",
        this, request, offset, count));
@@ -8092,17 +8092,17 @@ nsHttpChannel::OnDataAvailable(nsIReques
     //
     int64_t offsetBefore = 0;
     nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(input);
     if (seekable && NS_FAILED(seekable->Tell(&offsetBefore))) {
       seekable = nullptr;
     }
 
     nsresult rv =
-        mListener->OnDataAvailable(this, input, mLogicalOffset, count);
+        mListener->OnDataAvailable(this, nullptr, input, mLogicalOffset, count);
     if (NS_SUCCEEDED(rv)) {
       // by contract mListener must read all of "count" bytes, but
       // nsInputStreamPump is tolerant to seekable streams that violate that
       // and it will redeliver incompletely read data. So we need to do
       // the same thing when updating the progress counter to stay in sync.
       int64_t offsetAfter, delta;
       if (seekable && NS_SUCCEEDED(seekable->Tell(&offsetAfter))) {
         delta = offsetAfter - offsetBefore;
--- a/netwerk/protocol/res/ExtensionProtocolHandler.cpp
+++ b/netwerk/protocol/res/ExtensionProtocolHandler.cpp
@@ -231,18 +231,18 @@ Result<Ok, nsresult> ExtensionStreamGett
   return Ok();
 }
 
 static void CancelRequest(nsIStreamListener* aListener, nsIChannel* aChannel,
                           nsresult aResult) {
   MOZ_ASSERT(aListener);
   MOZ_ASSERT(aChannel);
 
-  aListener->OnStartRequest(aChannel);
-  aListener->OnStopRequest(aChannel, aResult);
+  aListener->OnStartRequest(aChannel, nullptr);
+  aListener->OnStopRequest(aChannel, nullptr, aResult);
   aChannel->Cancel(NS_BINDING_ABORTED);
 }
 
 // Handle an input stream sent from the parent.
 void ExtensionStreamGetter::OnStream(already_AddRefed<nsIInputStream> aStream) {
   MOZ_ASSERT(IsNeckoChild());
   MOZ_ASSERT(mListener);
   MOZ_ASSERT(mMainThreadEventTarget);
--- a/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
+++ b/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
@@ -612,57 +612,60 @@ nsViewSourceChannel::SetBaseURI(nsIURI *
 
 NS_IMETHODIMP
 nsViewSourceChannel::GetProtocolVersion(nsACString &aProtocolVersion) {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 // nsIRequestObserver methods
 NS_IMETHODIMP
-nsViewSourceChannel::OnStartRequest(nsIRequest *aRequest) {
+nsViewSourceChannel::OnStartRequest(nsIRequest *aRequest,
+                                    nsISupports *aContext) {
   NS_ENSURE_TRUE(mListener, NS_ERROR_FAILURE);
   // The channel may have gotten redirected... Time to update our info
   mChannel = do_QueryInterface(aRequest);
   mHttpChannel = do_QueryInterface(aRequest);
   mCachingChannel = do_QueryInterface(aRequest);
   mCacheInfoChannel = do_QueryInterface(mChannel);
   mUploadChannel = do_QueryInterface(aRequest);
 
   nsresult rv = UpdateLoadInfoResultPrincipalURI();
   if (NS_FAILED(rv)) {
     Cancel(rv);
   }
 
-  return mListener->OnStartRequest(static_cast<nsIViewSourceChannel *>(this));
+  return mListener->OnStartRequest(static_cast<nsIViewSourceChannel *>(this),
+                                   aContext);
 }
 
 NS_IMETHODIMP
-nsViewSourceChannel::OnStopRequest(nsIRequest *aRequest,
+nsViewSourceChannel::OnStopRequest(nsIRequest *aRequest, nsISupports *aContext,
                                    nsresult aStatus) {
   NS_ENSURE_TRUE(mListener, NS_ERROR_FAILURE);
   if (mChannel) {
     nsCOMPtr<nsILoadGroup> loadGroup;
     mChannel->GetLoadGroup(getter_AddRefs(loadGroup));
     if (loadGroup) {
       loadGroup->RemoveRequest(static_cast<nsIViewSourceChannel *>(this),
                                nullptr, aStatus);
     }
   }
   return mListener->OnStopRequest(static_cast<nsIViewSourceChannel *>(this),
-                                  aStatus);
+                                  aContext, aStatus);
 }
 
 // nsIStreamListener methods
 NS_IMETHODIMP
 nsViewSourceChannel::OnDataAvailable(nsIRequest *aRequest,
+                                     nsISupports *aContext,
                                      nsIInputStream *aInputStream,
                                      uint64_t aSourceOffset, uint32_t aLength) {
   NS_ENSURE_TRUE(mListener, NS_ERROR_FAILURE);
   return mListener->OnDataAvailable(static_cast<nsIViewSourceChannel *>(this),
-                                    aInputStream, aSourceOffset,
+                                    aContext, aInputStream, aSourceOffset,
                                     aLength);
 }
 
 // nsIHttpChannel methods
 
 // We want to forward most of nsIHttpChannel over to mHttpChannel, but we want
 // to override GetRequestHeader and VisitHeaders. The reason is that we don't
 // want various headers like Link: and Refresh: applying to view-source.
--- a/netwerk/protocol/websocket/WebSocketChannel.cpp
+++ b/netwerk/protocol/websocket/WebSocketChannel.cpp
@@ -3657,17 +3657,17 @@ WebSocketChannel::OnTransportAvailable(n
   }
 
   return NS_OK;
 }
 
 // nsIRequestObserver (from nsIStreamListener)
 
 NS_IMETHODIMP
-WebSocketChannel::OnStartRequest(nsIRequest *aRequest) {
+WebSocketChannel::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext) {
   LOG(("WebSocketChannel::OnStartRequest(): %p [%p %p] recvdhttpupgrade=%d\n",
        this, aRequest, mHttpChannel.get(), mRecvdHttpUpgradeTransport));
   MOZ_ASSERT(NS_IsMainThread(), "not main thread");
   MOZ_ASSERT(!mGotUpgradeOK, "OTA duplicated");
 
   if (mStopped) {
     LOG(("WebSocketChannel::OnStartRequest: Channel Already Done\n"));
     AbortSession(NS_ERROR_CONNECTION_REFUSED);
@@ -3842,17 +3842,17 @@ WebSocketChannel::OnStartRequest(nsIRequ
 
     return CallStartWebsocketData();
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-WebSocketChannel::OnStopRequest(nsIRequest *aRequest,
+WebSocketChannel::OnStopRequest(nsIRequest *aRequest, nsISupports *aContext,
                                 nsresult aStatusCode) {
   LOG(("WebSocketChannel::OnStopRequest() %p [%p %p %" PRIx32 "]\n", this,
        aRequest, mHttpChannel.get(), static_cast<uint32_t>(aStatusCode)));
   MOZ_ASSERT(NS_IsMainThread(), "not main thread");
 
   // OnTransportAvailable won't be called if the request is stopped with
   // an error. Abort the session now instead of waiting for timeout.
   if (NS_FAILED(aStatusCode) && !mRecvdHttpUpgradeTransport) {
@@ -3999,17 +3999,17 @@ WebSocketChannel::OnOutputStreamReady(ns
 
   if (mReleaseOnTransmit) ReleaseSession();
   return NS_OK;
 }
 
 // nsIStreamListener
 
 NS_IMETHODIMP
-WebSocketChannel::OnDataAvailable(nsIRequest *aRequest,
+WebSocketChannel::OnDataAvailable(nsIRequest *aRequest, nsISupports *aContext,
                                   nsIInputStream *aInputStream,
                                   uint64_t aOffset, uint32_t aCount) {
   LOG(("WebSocketChannel::OnDataAvailable() %p [%p %p %p %" PRIu64 " %u]\n",
        this, aRequest, mHttpChannel.get(), aInputStream, aOffset, aCount));
 
   // This is the HTTP OnDataAvailable Method, which means this is http data in
   // response to the upgrade request and there should be no http response body
   // if the upgrade succeeded. This generally should be caught by a non 101
--- a/netwerk/protocol/wyciwyg/WyciwygChannelChild.cpp
+++ b/netwerk/protocol/wyciwyg/WyciwygChannelChild.cpp
@@ -180,17 +180,17 @@ void WyciwygChannelChild::OnStartRequest
   if (!securityInfo.IsEmpty()) {
     rv = NS_DeserializeObject(securityInfo, getter_AddRefs(mSecurityInfo));
     MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv),
                           "Deserializing security info should not fail");
   }
 
   AutoEventEnqueuer ensureSerialDispatch(mEventQ);
 
-  rv = mListener->OnStartRequest(this);
+  rv = mListener->OnStartRequest(this, nullptr);
   if (NS_FAILED(rv)) Cancel(rv);
 }
 
 class WyciwygDataAvailableEvent
     : public NeckoTargetChannelEvent<WyciwygChannelChild> {
  public:
   WyciwygDataAvailableEvent(WyciwygChannelChild* child, const nsCString& data,
                             const uint64_t& offset)
@@ -229,17 +229,17 @@ void WyciwygChannelChild::OnDataAvailabl
                                       data.Length(), NS_ASSIGNMENT_DEPEND);
   if (NS_FAILED(rv)) {
     Cancel(rv);
     return;
   }
 
   AutoEventEnqueuer ensureSerialDispatch(mEventQ);
 
-  rv = mListener->OnDataAvailable(this, stringStream, offset,
+  rv = mListener->OnDataAvailable(this, nullptr, stringStream, offset,
                                   data.Length());
   if (NS_FAILED(rv)) Cancel(rv);
 
   if (mProgressSink && NS_SUCCEEDED(rv)) {
     mProgressSink->OnProgress(this, nullptr, offset + data.Length(),
                               mContentLength);
   }
 }
@@ -273,17 +273,17 @@ void WyciwygChannelChild::OnStopRequest(
     AutoEventEnqueuer ensureSerialDispatch(mEventQ);
 
     mState = WCC_ONSTOP;
 
     mIsPending = false;
 
     if (!mCanceled) mStatus = statusCode;
 
-    mListener->OnStopRequest(this, statusCode);
+    mListener->OnStopRequest(this, nullptr, statusCode);
 
     mListener = nullptr;
 
     if (mLoadGroup) mLoadGroup->RemoveRequest(this, nullptr, mStatus);
 
     mCallbacks = nullptr;
     mProgressSink = nullptr;
   }
@@ -315,18 +315,18 @@ void WyciwygChannelChild::CancelEarly(co
 
   mCanceled = true;
   mStatus = statusCode;
 
   mIsPending = false;
   if (mLoadGroup) mLoadGroup->RemoveRequest(this, nullptr, mStatus);
 
   if (mListener) {
-    mListener->OnStartRequest(this);
-    mListener->OnStopRequest(this, mStatus);
+    mListener->OnStartRequest(this, nullptr);
+    mListener->OnStopRequest(this, nullptr, mStatus);
   }
   mListener = nullptr;
 
   if (mIPCOpen) PWyciwygChannelChild::Send__delete__(this);
 }
 
 //-----------------------------------------------------------------------------
 // nsIRequest
--- a/netwerk/protocol/wyciwyg/WyciwygChannelParent.cpp
+++ b/netwerk/protocol/wyciwyg/WyciwygChannelParent.cpp
@@ -274,17 +274,18 @@ mozilla::ipc::IPCResult WyciwygChannelPa
   return IPC_OK();
 }
 
 //-----------------------------------------------------------------------------
 // WyciwygChannelParent::nsIRequestObserver
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
-WyciwygChannelParent::OnStartRequest(nsIRequest* aRequest) {
+WyciwygChannelParent::OnStartRequest(nsIRequest* aRequest,
+                                     nsISupports* aContext) {
   LOG(("WyciwygChannelParent::OnStartRequest [this=%p]\n", this));
 
   nsresult rv;
 
   nsCOMPtr<nsIWyciwygChannel> chan = do_QueryInterface(aRequest, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Send down any permissions which are relevant to this URL if we are
@@ -324,17 +325,17 @@ WyciwygChannelParent::OnStartRequest(nsI
                                         charset, secInfoStr)) {
     return NS_ERROR_UNEXPECTED;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-WyciwygChannelParent::OnStopRequest(nsIRequest* aRequest,
+WyciwygChannelParent::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
                                     nsresult aStatusCode) {
   LOG(("WyciwygChannelParent::OnStopRequest: [this=%p status=%" PRIu32 "]\n",
        this, static_cast<uint32_t>(aStatusCode)));
 
   if (mIPCClosed || !SendOnStopRequest(aStatusCode)) {
     return NS_ERROR_UNEXPECTED;
   }
 
@@ -342,16 +343,17 @@ WyciwygChannelParent::OnStopRequest(nsIR
 }
 
 //-----------------------------------------------------------------------------
 // WyciwygChannelParent::nsIStreamListener
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 WyciwygChannelParent::OnDataAvailable(nsIRequest* aRequest,
+                                      nsISupports* aContext,
                                       nsIInputStream* aInputStream,
                                       uint64_t aOffset, uint32_t aCount) {
   LOG(("WyciwygChannelParent::OnDataAvailable [this=%p]\n", this));
 
   nsCString data;
   nsresult rv = NS_ReadInputStreamToString(aInputStream, data, aCount);
   if (NS_FAILED(rv)) return rv;
 
--- a/netwerk/protocol/wyciwyg/nsWyciwygChannel.cpp
+++ b/netwerk/protocol/wyciwyg/nsWyciwygChannel.cpp
@@ -540,29 +540,29 @@ nsWyciwygChannel::OnCacheEntryAvailable(
   return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 // nsWyciwygChannel::nsIStreamListener
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
-nsWyciwygChannel::OnDataAvailable(nsIRequest *request,
+nsWyciwygChannel::OnDataAvailable(nsIRequest *request, nsISupports *ctx,
                                   nsIInputStream *input, uint64_t offset,
                                   uint32_t count) {
   LOG(("nsWyciwygChannel::OnDataAvailable [this=%p request=%p offset=%" PRIu64
        " count=%u]\n",
        this, request, offset, count));
 
   nsresult rv;
 
   nsCOMPtr<nsIStreamListener> listener = mListener;
 
   if (listener) {
-    rv = listener->OnDataAvailable(this, input, offset, count);
+    rv = listener->OnDataAvailable(this, nullptr, input, offset, count);
   } else {
     MOZ_ASSERT(false, "We must have a listener!");
     rv = NS_ERROR_UNEXPECTED;
   }
 
   // XXX handle 64-bit stuff for real
   if (mProgressSink && NS_SUCCEEDED(rv)) {
     mProgressSink->OnProgress(this, nullptr, offset + count, mContentLength);
@@ -571,46 +571,46 @@ nsWyciwygChannel::OnDataAvailable(nsIReq
   return rv;  // let the pump cancel on failure
 }
 
 //////////////////////////////////////////////////////////////////////////////
 // nsIRequestObserver
 //////////////////////////////////////////////////////////////////////////////
 
 NS_IMETHODIMP
-nsWyciwygChannel::OnStartRequest(nsIRequest *request) {
+nsWyciwygChannel::OnStartRequest(nsIRequest *request, nsISupports *ctx) {
   LOG(("nsWyciwygChannel::OnStartRequest [this=%p request=%p]\n", this,
        request));
 
   nsCOMPtr<nsIStreamListener> listener = mListener;
 
   if (listener) {
-    return listener->OnStartRequest(this);
+    return listener->OnStartRequest(this, nullptr);
   }
 
   MOZ_ASSERT(false, "We must have a listener!");
   return NS_ERROR_UNEXPECTED;
 }
 
 NS_IMETHODIMP
-nsWyciwygChannel::OnStopRequest(nsIRequest *request,
+nsWyciwygChannel::OnStopRequest(nsIRequest *request, nsISupports *ctx,
                                 nsresult status) {
   LOG(("nsWyciwygChannel::OnStopRequest [this=%p request=%p status=%" PRIu32
        "]\n",
        this, request, static_cast<uint32_t>(status)));
 
   if (NS_SUCCEEDED(mStatus)) mStatus = status;
 
   mIsPending = false;
 
   nsCOMPtr<nsIStreamListener> listener;
   listener.swap(mListener);
 
   if (listener) {
-    listener->OnStopRequest(this, mStatus);
+    listener->OnStopRequest(this, nullptr, mStatus);
   } else {
     MOZ_ASSERT(false, "We must have a listener!");
   }
 
   if (mLoadGroup) mLoadGroup->RemoveRequest(this, nullptr, mStatus);
 
   CloseCacheEntry(mStatus);
   mPump = nullptr;
@@ -709,19 +709,19 @@ void nsWyciwygChannel::WriteCharsetAndSo
 }
 
 void nsWyciwygChannel::NotifyListener() {
   nsCOMPtr<nsIStreamListener> listener;
 
   listener.swap(mListener);
 
   if (listener) {
-    listener->OnStartRequest(this);
+    listener->OnStartRequest(this, nullptr);
     mIsPending = false;
-    listener->OnStopRequest(this, mStatus);
+    listener->OnStopRequest(this, nullptr, mStatus);
   } else {
     MOZ_ASSERT(false, "We must have the listener!");
     mIsPending = false;
   }
 
   CloseCacheEntry(mStatus);
 
   // Remove ourselves from the load group.
--- a/netwerk/streamconv/converters/mozTXTToHTMLConv.cpp
+++ b/netwerk/streamconv/converters/mozTXTToHTMLConv.cpp
@@ -1213,29 +1213,29 @@ mozTXTToHTMLConv::Convert(nsIInputStream
 NS_IMETHODIMP
 mozTXTToHTMLConv::AsyncConvertData(const char* aFromType, const char* aToType,
                                    nsIStreamListener* aListener,
                                    nsISupports* aCtxt) {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-mozTXTToHTMLConv::OnDataAvailable(nsIRequest* request,
+mozTXTToHTMLConv::OnDataAvailable(nsIRequest* request, nsISupports* ctxt,
                                   nsIInputStream* inStr, uint64_t sourceOffset,
                                   uint32_t count) {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-mozTXTToHTMLConv::OnStartRequest(nsIRequest* request) {
+mozTXTToHTMLConv::OnStartRequest(nsIRequest* request, nsISupports* ctxt) {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-mozTXTToHTMLConv::OnStopRequest(nsIRequest* request,
+mozTXTToHTMLConv::OnStopRequest(nsIRequest* request, nsISupports* ctxt,
                                 nsresult aStatus) {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 mozTXTToHTMLConv::CiteLevelTXT(const char16_t* line, uint32_t* logLineStart,
                                uint32_t* _retval) {
   if (!logLineStart || !_retval || !line) return NS_ERROR_NULL_POINTER;
--- a/netwerk/streamconv/converters/nsDirIndexParser.cpp
+++ b/netwerk/streamconv/converters/nsDirIndexParser.cpp
@@ -82,26 +82,26 @@ nsDirIndexParser::GetEncoding(char **aEn
   *aEncoding = ToNewCString(mEncoding);
 
   if (!*aEncoding) return NS_ERROR_OUT_OF_MEMORY;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDirIndexParser::OnStartRequest(nsIRequest *aRequest) {
+nsDirIndexParser::OnStartRequest(nsIRequest *aRequest, nsISupports *aCtxt) {
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDirIndexParser::OnStopRequest(nsIRequest *aRequest,
+nsDirIndexParser::OnStopRequest(nsIRequest *aRequest, nsISupports *aCtxt,
                                 nsresult aStatusCode) {
   // Finish up
   if (mBuf.Length() > (uint32_t)mLineStart) {
-    ProcessData(aRequest, nullptr);
+    ProcessData(aRequest, aCtxt);
   }
 
   return NS_OK;
 }
 
 nsDirIndexParser::Field nsDirIndexParser::gFieldTable[] = {
     {"Filename", FIELD_FILENAME},
     {"Description", FIELD_DESCRIPTION},
@@ -292,17 +292,17 @@ nsresult nsDirIndexParser::ParseData(nsI
         break;
     }
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDirIndexParser::OnDataAvailable(nsIRequest *aRequest,
+nsDirIndexParser::OnDataAvailable(nsIRequest *aRequest, nsISupports *aCtxt,
                                   nsIInputStream *aStream,
                                   uint64_t aSourceOffset, uint32_t aCount) {
   if (aCount < 1) return NS_OK;
 
   int32_t len = mBuf.Length();
 
   // Ensure that our mBuf has capacity to hold the data we're about to
   // read.
@@ -314,17 +314,17 @@ nsDirIndexParser::OnDataAvailable(nsIReq
   rv = aStream->Read(mBuf.BeginWriting() + len, aCount, &count);
   if (NS_FAILED(rv)) return rv;
 
   // Set the string's length according to the amount of data we've read.
   // Note: we know this to work on nsCString. This isn't guaranteed to
   //       work on other strings.
   mBuf.SetLength(len + count);
 
-  return ProcessData(aRequest, nullptr);
+  return ProcessData(aRequest, aCtxt);
 }
 
 nsresult nsDirIndexParser::ProcessData(nsIRequest *aRequest,
                                        nsISupports *aCtxt) {
   if (!mListener) return NS_ERROR_FAILURE;
 
   int32_t numItems = 0;
 
--- a/netwerk/streamconv/converters/nsFTPDirListingConv.cpp
+++ b/netwerk/streamconv/converters/nsFTPDirListingConv.cpp
@@ -67,17 +67,17 @@ nsFTPDirListingConv::AsyncConvertData(co
           ("nsFTPDirListingConv::AsyncConvertData() converting FROM raw, TO "
            "application/http-index-format\n"));
 
   return NS_OK;
 }
 
 // nsIStreamListener implementation
 NS_IMETHODIMP
-nsFTPDirListingConv::OnDataAvailable(nsIRequest *request,
+nsFTPDirListingConv::OnDataAvailable(nsIRequest *request, nsISupports *ctxt,
                                      nsIInputStream *inStr,
                                      uint64_t sourceOffset, uint32_t count) {
   NS_ASSERTION(request, "FTP dir listing stream converter needs a request");
 
   nsresult rv;
 
   nsCOMPtr<nsIChannel> channel = do_QueryInterface(request, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
@@ -94,19 +94,19 @@ nsFTPDirListingConv::OnDataAvailable(nsI
 
   rv = inStr->Read(buffer.get(), streamLen, &read);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // the dir listings are ascii text, null terminate this sucker.
   buffer[streamLen] = '\0';
 
   MOZ_LOG(gFTPDirListConvLog, LogLevel::Debug,
-          ("nsFTPDirListingConv::OnData(request = %p, inStr = %p, "
+          ("nsFTPDirListingConv::OnData(request = %p, ctxt = %p, inStr = %p, "
            "sourceOffset = %" PRIu64 ", count = %u)\n",
-           request, inStr, sourceOffset, count));
+           request, ctxt, inStr, sourceOffset, count));
 
   if (!mBuffer.IsEmpty()) {
     // we have data left over from a previous OnDataAvailable() call.
     // combine the buffers so we don't lose any data.
     mBuffer.Append(buffer.get());
 
     buffer = MakeUniqueFallible<char[]>(mBuffer.Length() + 1);
     NS_ENSURE_TRUE(buffer, NS_ERROR_OUT_OF_MEMORY);
@@ -148,36 +148,36 @@ nsFTPDirListingConv::OnDataAvailable(nsI
   }
 
   // send the converted data out.
   nsCOMPtr<nsIInputStream> inputData;
 
   rv = NS_NewCStringInputStream(getter_AddRefs(inputData), indexFormat);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  rv = mFinalListener->OnDataAvailable(request, inputData, 0,
+  rv = mFinalListener->OnDataAvailable(request, ctxt, inputData, 0,
                                        indexFormat.Length());
 
   return rv;
 }
 
 // nsIRequestObserver implementation
 NS_IMETHODIMP
-nsFTPDirListingConv::OnStartRequest(nsIRequest *request) {
+nsFTPDirListingConv::OnStartRequest(nsIRequest *request, nsISupports *ctxt) {
   // we don't care about start. move along... but start masqeurading
   // as the http-index channel now.
-  return mFinalListener->OnStartRequest(request);
+  return mFinalListener->OnStartRequest(request, ctxt);
 }
 
 NS_IMETHODIMP
-nsFTPDirListingConv::OnStopRequest(nsIRequest *request,
+nsFTPDirListingConv::OnStopRequest(nsIRequest *request, nsISupports *ctxt,
                                    nsresult aStatus) {
   // we don't care about stop. move along...
 
-  return mFinalListener->OnStopRequest(request, aStatus);
+  return mFinalListener->OnStopRequest(request, ctxt, aStatus);
 }
 
 // nsFTPDirListingConv methods
 nsFTPDirListingConv::nsFTPDirListingConv() {
   mFinalListener = nullptr;
   mSentHeading = false;
 }
 
--- a/netwerk/streamconv/converters/nsHTTPCompressConv.cpp
+++ b/netwerk/streamconv/converters/nsHTTPCompressConv.cpp
@@ -111,28 +111,28 @@ nsHTTPCompressConv::AsyncConvertData(con
   MutexAutoLock lock(mMutex);
   // hook ourself up with the receiving listener.
   mListener = aListener;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsHTTPCompressConv::OnStartRequest(nsIRequest *request) {
+nsHTTPCompressConv::OnStartRequest(nsIRequest *request, nsISupports *aContext) {
   LOG(("nsHttpCompresssConv %p onstart\n", this));
   nsCOMPtr<nsIStreamListener> listener;
   {
     MutexAutoLock lock(mMutex);
     listener = mListener;
   }
-  return listener->OnStartRequest(request);
+  return listener->OnStartRequest(request, aContext);
 }
 
 NS_IMETHODIMP
-nsHTTPCompressConv::OnStopRequest(nsIRequest *request,
+nsHTTPCompressConv::OnStopRequest(nsIRequest *request, nsISupports *aContext,
                                   nsresult aStatus) {
   nsresult status = aStatus;
   LOG(("nsHttpCompresssConv %p onstop %" PRIx32 "\n", this,
        static_cast<uint32_t>(aStatus)));
 
   // Framing integrity is enforced for content-encoding: gzip, but not for
   // content-encoding: deflate. Note that gzip vs deflate is NOT determined
   // by content sniffing but only via header.
@@ -162,17 +162,17 @@ nsHTTPCompressConv::OnStopRequest(nsIReq
     }
   }
 
   nsCOMPtr<nsIStreamListener> listener;
   {
     MutexAutoLock lock(mMutex);
     listener = mListener;
   }
-  return listener->OnStopRequest(request, status);
+  return listener->OnStopRequest(request, aContext, status);
 }
 
 /* static */ nsresult nsHTTPCompressConv::BrotliHandler(
     nsIInputStream *stream, void *closure, const char *dataIn, uint32_t,
     uint32_t aAvail, uint32_t *countRead) {
   MOZ_ASSERT(stream);
   nsHTTPCompressConv *self = static_cast<nsHTTPCompressConv *>(closure);
   *countRead = 0;
@@ -250,17 +250,17 @@ nsHTTPCompressConv::OnStopRequest(nsIReq
     MOZ_ASSERT(res == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT);
   } while (res == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT);
 
   self->mBrotli->mStatus = NS_ERROR_UNEXPECTED;
   return self->mBrotli->mStatus;
 }
 
 NS_IMETHODIMP
-nsHTTPCompressConv::OnDataAvailable(nsIRequest *request,
+nsHTTPCompressConv::OnDataAvailable(nsIRequest *request, nsISupports *aContext,
                                     nsIInputStream *iStr,
                                     uint64_t aSourceOffset, uint32_t aCount) {
   nsresult rv = NS_ERROR_INVALID_CONTENT_ENCODING;
   uint32_t streamLen = aCount;
   LOG(("nsHttpCompressConv %p OnDataAvailable %d", this, aCount));
 
   if (streamLen == 0) {
     NS_ERROR("count of zero passed to OnDataAvailable");
@@ -344,37 +344,37 @@ nsHTTPCompressConv::OnDataAvailable(nsIR
           d_stream.next_out = mOutBuffer;
           d_stream.avail_out = (uInt)mOutBufferLen;
 
           int code = inflate(&d_stream, Z_NO_FLUSH);
           unsigned bytesWritten = (uInt)mOutBufferLen - d_stream.avail_out;
 
           if (code == Z_STREAM_END) {
             if (bytesWritten) {
-              rv = do_OnDataAvailable(request, nullptr, aSourceOffset,
+              rv = do_OnDataAvailable(request, aContext, aSourceOffset,
                                       (char *)mOutBuffer, bytesWritten);
               if (NS_FAILED(rv)) {
                 return rv;
               }
             }
 
             inflateEnd(&d_stream);
             mStreamEnded = true;
             break;
           } else if (code == Z_OK) {
             if (bytesWritten) {
-              rv = do_OnDataAvailable(request, nullptr, aSourceOffset,
+              rv = do_OnDataAvailable(request, aContext, aSourceOffset,
                                       (char *)mOutBuffer, bytesWritten);
               if (NS_FAILED(rv)) {
                 return rv;
               }
             }
           } else if (code == Z_BUF_ERROR) {
             if (bytesWritten) {
-              rv = do_OnDataAvailable(request, nullptr, aSourceOffset,
+              rv = do_OnDataAvailable(request, aContext, aSourceOffset,
                                       (char *)mOutBuffer, bytesWritten);
               if (NS_FAILED(rv)) {
                 return rv;
               }
             }
             break;
           } else if (code == Z_DATA_ERROR) {
             // some servers (notably Apache with mod_deflate) don't generate
@@ -426,37 +426,37 @@ nsHTTPCompressConv::OnDataAvailable(nsIR
           d_stream.next_out = mOutBuffer;
           d_stream.avail_out = (uInt)mOutBufferLen;
 
           int code = inflate(&d_stream, Z_NO_FLUSH);
           unsigned bytesWritten = (uInt)mOutBufferLen - d_stream.avail_out;
 
           if (code == Z_STREAM_END) {
             if (bytesWritten) {
-              rv = do_OnDataAvailable(request, nullptr, aSourceOffset,
+              rv = do_OnDataAvailable(request, aContext, aSourceOffset,
                                       (char *)mOutBuffer, bytesWritten);
               if (NS_FAILED(rv)) {
                 return rv;
               }
             }
 
             inflateEnd(&d_stream);
             mStreamEnded = true;
             break;
           } else if (code == Z_OK) {
             if (bytesWritten) {
-              rv = do_OnDataAvailable(request, nullptr, aSourceOffset,
+              rv = do_OnDataAvailable(request, aContext, aSourceOffset,
                                       (char *)mOutBuffer, bytesWritten);
               if (NS_FAILED(rv)) {
                 return rv;
               }
             }
           } else if (code == Z_BUF_ERROR) {
             if (bytesWritten) {
-              rv = do_OnDataAvailable(request, nullptr, aSourceOffset,
+              rv = do_OnDataAvailable(request, aContext, aSourceOffset,
                                       (char *)mOutBuffer, bytesWritten);
               if (NS_FAILED(rv)) {
                 return rv;
               }
             }
             break;
           } else {
             return NS_ERROR_INVALID_CONTENT_ENCODING;
@@ -466,17 +466,17 @@ nsHTTPCompressConv::OnDataAvailable(nsIR
       break;
 
     case HTTP_COMPRESS_BROTLI: {
       if (!mBrotli) {
         mBrotli = new BrotliWrapper();
       }
 
       mBrotli->mRequest = request;
-      mBrotli->mContext = nullptr;
+      mBrotli->mContext = aContext;
       mBrotli->mSourceOffset = aSourceOffset;
 
       uint32_t countRead;
       rv = iStr->ReadSegments(BrotliHandler, this, streamLen, &countRead);
       if (NS_SUCCEEDED(rv)) {
         rv = mBrotli->mStatus;
       }
       if (NS_FAILED(rv)) {
@@ -485,17 +485,17 @@ nsHTTPCompressConv::OnDataAvailable(nsIR
     } break;
 
     default:
       nsCOMPtr<nsIStreamListener> listener;
       {
         MutexAutoLock lock(mMutex);
         listener = mListener;
       }
-      rv = listener->OnDataAvailable(request, iStr, aSourceOffset,
+      rv = listener->OnDataAvailable(request, aContext, iStr, aSourceOffset,
                                      aCount);
       if (NS_FAILED(rv)) {
         return rv;
       }
   } /* switch */
 
   return NS_OK;
 } /* OnDataAvailable */
@@ -522,17 +522,17 @@ nsresult nsHTTPCompressConv::do_OnDataAv
   mStream->ShareData(buffer, count);
 
   nsCOMPtr<nsIStreamListener> listener;
   {
     MutexAutoLock lock(mMutex);
     listener = mListener;
   }
   nsresult rv =
-      listener->OnDataAvailable(request, mStream, offset, count);
+      listener->OnDataAvailable(request, context, mStream, offset, count);
 
   // Make sure the stream no longer references |buffer| in case our listener
   // is crazy enough to try to read from |mStream| after ODA.
   mStream->ShareData("", 0);
   mDecodedDataLength += count;
 
   return rv;
 }
--- a/netwerk/streamconv/converters/nsIndexedToHTML.cpp
+++ b/netwerk/streamconv/converters/nsIndexedToHTML.cpp
@@ -90,34 +90,34 @@ nsIndexedToHTML::Convert(nsIInputStream*
 NS_IMETHODIMP
 nsIndexedToHTML::AsyncConvertData(const char* aFromType, const char* aToType,
                                   nsIStreamListener* aListener,
                                   nsISupports* aCtxt) {
   return Init(aListener);
 }
 
 NS_IMETHODIMP
-nsIndexedToHTML::OnStartRequest(nsIRequest* request) {
+nsIndexedToHTML::OnStartRequest(nsIRequest* request, nsISupports* aContext) {
   nsCString buffer;
-  nsresult rv = DoOnStartRequest(request, nullptr, buffer);
+  nsresult rv = DoOnStartRequest(request, aContext, buffer);
   if (NS_FAILED(rv)) {
     request->Cancel(rv);
   }
 
-  rv = mListener->OnStartRequest(request);
+  rv = mListener->OnStartRequest(request, aContext);
   if (NS_FAILED(rv)) return rv;
 
   // The request may have been canceled, and if that happens, we want to
   // suppress calls to OnDataAvailable.
   request->GetStatus(&rv);
   if (NS_FAILED(rv)) return rv;
 
   // Push our buffer to the listener.
 
-  rv = SendToListener(request, nullptr, buffer);
+  rv = SendToListener(request, aContext, buffer);
   return rv;
 }
 
 nsresult nsIndexedToHTML::DoOnStartRequest(nsIRequest* request,
                                            nsISupports* aContext,
                                            nsCString& aBuffer) {
   nsresult rv;
 
@@ -140,17 +140,17 @@ nsresult nsIndexedToHTML::DoOnStartReque
   channel->SetContentType(NS_LITERAL_CSTRING("text/html"));
 
   mParser = nsDirIndexParser::CreateInstance();
   if (!mParser) return NS_ERROR_FAILURE;
 
   rv = mParser->SetListener(this);
   if (NS_FAILED(rv)) return rv;
 
-  rv = mParser->OnStartRequest(request);
+  rv = mParser->OnStartRequest(request, aContext);
   if (NS_FAILED(rv)) return rv;
 
   nsAutoCString baseUri, titleUri;
   rv = uri->GetAsciiSpec(baseUri);
   if (NS_FAILED(rv)) return rv;
 
   nsCOMPtr<nsIURI> titleURL;
   rv = NS_MutateURI(uri)
@@ -636,46 +636,46 @@ nsresult nsIndexedToHTML::DoOnStartReque
       " </thead>\n");
   buffer.AppendLiteral(" <tbody>\n");
 
   aBuffer = buffer;
   return rv;
 }
 
 NS_IMETHODIMP
-nsIndexedToHTML::OnStopRequest(nsIRequest* request,
+nsIndexedToHTML::OnStopRequest(nsIRequest* request, nsISupports* aContext,
                                nsresult aStatus) {
   if (NS_SUCCEEDED(aStatus)) {
     nsCString buffer;
     buffer.AssignLiteral("</tbody></table></body></html>\n");
 
-    aStatus = SendToListener(request, nullptr, buffer);
+    aStatus = SendToListener(request, aContext, buffer);
   }
 
-  mParser->OnStopRequest(request, aStatus);
+  mParser->OnStopRequest(request, aContext, aStatus);
   mParser = nullptr;
 
-  return mListener->OnStopRequest(request, aStatus);
+  return mListener->OnStopRequest(request, aContext, aStatus);
 }
 
 nsresult nsIndexedToHTML::SendToListener(nsIRequest* aRequest,
                                          nsISupports* aContext,
                                          const nsACString& aBuffer) {
   nsCOMPtr<nsIInputStream> inputData;
   nsresult rv = NS_NewCStringInputStream(getter_AddRefs(inputData), aBuffer);
   NS_ENSURE_SUCCESS(rv, rv);
-  return mListener->OnDataAvailable(aRequest, inputData, 0,
+  return mListener->OnDataAvailable(aRequest, aContext, inputData, 0,
                                     aBuffer.Length());
 }
 
 NS_IMETHODIMP
-nsIndexedToHTML::OnDataAvailable(nsIRequest* aRequest,
+nsIndexedToHTML::OnDataAvailable(nsIRequest* aRequest, nsISupports* aCtxt,
                                  nsIInputStream* aInput, uint64_t aOffset,
                                  uint32_t aCount) {
-  return mParser->OnDataAvailable(aRequest, aInput, aOffset, aCount);
+  return mParser->OnDataAvailable(aRequest, aCtxt, aInput, aOffset, aCount);
 }
 
 NS_IMETHODIMP
 nsIndexedToHTML::OnIndexAvailable(nsIRequest* aRequest, nsISupports* aCtxt,
                                   nsIDirIndex* aIndex) {
   nsresult rv;
   if (!aIndex) return NS_ERROR_NULL_POINTER;
 
--- a/netwerk/streamconv/converters/nsMultiMixedConv.cpp
+++ b/netwerk/streamconv/converters/nsMultiMixedConv.cpp
@@ -44,31 +44,31 @@ nsPartChannel::nsPartChannel(nsIChannel 
 void nsPartChannel::InitializeByteRange(int64_t aStart, int64_t aEnd) {
   mIsByteRangeRequest = true;
 
   mByteRangeStart = aStart;
   mByteRangeEnd = aEnd;
 }
 
 nsresult nsPartChannel::SendOnStartRequest(nsISupports *aContext) {
-  return mListener->OnStartRequest(this);
+  return mListener->OnStartRequest(this, aContext);
 }
 
 nsresult nsPartChannel::SendOnDataAvailable(nsISupports *aContext,
                                             nsIInputStream *aStream,
                                             uint64_t aOffset, uint32_t aLen) {
-  return mListener->OnDataAvailable(this, aStream, aOffset, aLen);
+  return mListener->OnDataAvailable(this, aContext, aStream, aOffset, aLen);
 }
 
 nsresult nsPartChannel::SendOnStopRequest(nsISupports *aContext,
                                           nsresult aStatus) {
   // Drop the listener
   nsCOMPtr<nsIStreamListener> listener;
   listener.swap(mListener);
-  return listener->OnStopRequest(this, aStatus);
+  return listener->OnStopRequest(this, aContext, aStatus);
 }
 
 void nsPartChannel::SetContentDisposition(
     const nsACString &aContentDispositionHeader) {
   mContentDispositionHeader = aContentDispositionHeader;
   nsCOMPtr<nsIURI> uri;
   GetURI(getter_AddRefs(uri));
   NS_GetFilenameFromDisposition(mContentDispositionFilename,
@@ -403,22 +403,23 @@ nsMultiMixedConv::AsyncConvertData(const
   // of these for each sub-part in the raw stream.
   mFinalListener = aListener;
 
   return NS_OK;
 }
 
 // nsIRequestObserver implementation
 NS_IMETHODIMP
-nsMultiMixedConv::OnStartRequest(nsIRequest *request) {
+nsMultiMixedConv::OnStartRequest(nsIRequest *request, nsISupports *ctxt) {
   // we're assuming the content-type is available at this stage
   NS_ASSERTION(mBoundary.IsEmpty(), "a second on start???");
 
   nsresult rv;
 
+  mContext = ctxt;
   mTotalSent = 0;
   mChannel = do_QueryInterface(request, &rv);
   if (NS_FAILED(rv)) return rv;
 
   nsAutoCString contentType;
 
   // ask the HTTP channel for the content-type and extract the boundary from it.
   nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(mChannel, &rv);
@@ -489,17 +490,17 @@ nsMultiMixedConv::OnStartRequest(nsIRequ
   mBoundaryTokenWithDashes = mTokenizer.AddCustomToken(
       NS_LITERAL_CSTRING("--") + mBoundary, mTokenizer.CASE_SENSITIVE);
 
   return NS_OK;
 }
 
 // nsIStreamListener implementation
 NS_IMETHODIMP
-nsMultiMixedConv::OnDataAvailable(nsIRequest *request,
+nsMultiMixedConv::OnDataAvailable(nsIRequest *request, nsISupports *context,
                                   nsIInputStream *inStr, uint64_t sourceOffset,
                                   uint32_t count) {
   // Failing these assertions may indicate that some of the target listeners of
   // this converter is looping the thead queue, which is harmful to how we
   // collect the raw (content) data.
   MOZ_DIAGNOSTIC_ASSERT(!mInOnDataAvailable,
                         "nsMultiMixedConv::OnDataAvailable reentered!");
   MOZ_DIAGNOSTIC_ASSERT(
@@ -518,17 +519,17 @@ nsMultiMixedConv::OnDataAvailable(nsIReq
   // parsing process.  Otherwise the raw data reference would not be thrown
   // away.
   nsresult rv_send = SendData();
 
   return NS_FAILED(rv_send) ? rv_send : rv_feed;
 }
 
 NS_IMETHODIMP
-nsMultiMixedConv::OnStopRequest(nsIRequest *request,
+nsMultiMixedConv::OnStopRequest(nsIRequest *request, nsISupports *ctxt,
                                 nsresult aStatus) {
   nsresult rv;
 
   if (mBoundary.IsEmpty()) {  // no token, no love.
     return NS_ERROR_FAILURE;
   }
 
   if (mPartChannel) {
@@ -547,18 +548,18 @@ nsMultiMixedConv::OnStopRequest(nsIReque
     }
 
     (void)SendStop(aStatus);
   } else if (NS_FAILED(aStatus) && !mRequestListenerNotified) {
     // underlying data production problem. we should not be in
     // the middle of sending data. if we were, mPartChannel,
     // above, would have been non-null.
 
-    (void)mFinalListener->OnStartRequest(request);
-    (void)mFinalListener->OnStopRequest(request, aStatus);
+    (void)mFinalListener->OnStartRequest(request, ctxt);
+    (void)mFinalListener->OnStopRequest(request, ctxt, aStatus);
   }
 
   return NS_OK;
 }
 
 nsresult nsMultiMixedConv::ConsumeToken(Token const &token) {
   nsresult rv;
 
--- a/netwerk/streamconv/converters/nsUnknownDecoder.cpp
+++ b/netwerk/streamconv/converters/nsUnknownDecoder.cpp
@@ -43,23 +43,23 @@ nsresult nsUnknownDecoder::ConvertedStre
   nsCString* decodedData = static_cast<nsCString*>(closure);
   decodedData->Append(rawSegment, count);
   *writeCount = count;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsUnknownDecoder::ConvertedStreamListener::OnStartRequest(
-    nsIRequest* request) {
+    nsIRequest* request, nsISupports* context) {
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsUnknownDecoder::ConvertedStreamListener::OnDataAvailable(
-    nsIRequest* request, nsIInputStream* stream,
+    nsIRequest* request, nsISupports* context, nsIInputStream* stream,
     uint64_t offset, uint32_t count) {
   uint32_t read;
   nsAutoCString decodedData;
   {
     MutexAutoLock lock(mDecoder->mMutex);
     decodedData = mDecoder->mDecodedData;
   }
   nsresult rv =
@@ -69,16 +69,17 @@ nsUnknownDecoder::ConvertedStreamListene
   }
   MutexAutoLock lock(mDecoder->mMutex);
   mDecoder->mDecodedData = decodedData;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsUnknownDecoder::ConvertedStreamListener::OnStopRequest(nsIRequest* request,
+                                                         nsISupports* context,
                                                          nsresult status) {
   return NS_OK;
 }
 
 nsUnknownDecoder::nsUnknownDecoder()
     : mBuffer(nullptr),
       mBufferLen(0),
       mRequireHTMLsuffix(false),
@@ -147,17 +148,17 @@ nsUnknownDecoder::AsyncConvertData(const
 
 // ----
 //
 // nsIStreamListener methods...
 //
 // ----
 
 NS_IMETHODIMP
-nsUnknownDecoder::OnDataAvailable(nsIRequest* request,
+nsUnknownDecoder::OnDataAvailable(nsIRequest* request, nsISupports* aCtxt,
                                   nsIInputStream* aStream,
                                   uint64_t aSourceOffset, uint32_t aCount) {
   nsresult rv = NS_OK;
 
   bool contentTypeEmpty;
   {
     MutexAutoLock lock(mMutex);
     if (!mNextListener) return NS_ERROR_FAILURE;
@@ -193,17 +194,17 @@ nsUnknownDecoder::OnDataAvailable(nsIReq
       // Adjust the source offset...  The call to FireListenerNotifications(...)
       // will make the first OnDataAvailable(...) call with an offset of 0.
       // So, this offset needs to be adjusted to reflect that...
       //
       aSourceOffset += mBufferLen;
 
       DetermineContentType(request);
 
-      rv = FireListenerNotifications(request, nullptr);
+      rv = FireListenerNotifications(request, aCtxt);
     }
   }
 
   // Must not fire ODA again if it failed once
   if (aCount && NS_SUCCEEDED(rv)) {
 #ifdef DEBUG
     {
       MutexAutoLock lock(mMutex);
@@ -222,31 +223,31 @@ nsUnknownDecoder::OnDataAvailable(nsIReq
       }
     }
 
     nsCOMPtr<nsIStreamListener> listener;
     {
       MutexAutoLock lock(mMutex);
       listener = mNextListener;
     }
-    rv = listener->OnDataAvailable(request, aStream, aSourceOffset,
+    rv = listener->OnDataAvailable(request, aCtxt, aStream, aSourceOffset,
                                    aCount);
   }
 
   return rv;
 }
 
 // ----
 //
 // nsIRequestObserver methods...
 //
 // ----
 
 NS_IMETHODIMP
-nsUnknownDecoder::OnStartRequest(nsIRequest* request) {
+nsUnknownDecoder::OnStartRequest(nsIRequest* request, nsISupports* aCtxt) {
   nsresult rv = NS_OK;
 
   {
     MutexAutoLock lock(mMutex);
     if (!mNextListener) return NS_ERROR_FAILURE;
   }
 
   // Allocate the sniffer buffer...
@@ -263,17 +264,17 @@ nsUnknownDecoder::OnStartRequest(nsIRequ
     divertable->UnknownDecoderInvolvedKeepData();
   }
 
   // Do not pass the OnStartRequest on to the next listener (yet)...
   return rv;
 }
 
 NS_IMETHODIMP
-nsUnknownDecoder::OnStopRequest(nsIRequest* request,
+nsUnknownDecoder::OnStopRequest(nsIRequest* request, nsISupports* aCtxt,
                                 nsresult aStatus) {
   nsresult rv = NS_OK;
 
   bool contentTypeEmpty;
   {
     MutexAutoLock lock(mMutex);
     if (!mNextListener) return NS_ERROR_FAILURE;
 
@@ -291,17 +292,17 @@ nsUnknownDecoder::OnStopRequest(nsIReque
     // OnStartRequest/OnDataAvailable, even though the underlying channel
     // has already hit OnStopRequest.
     nsCOMPtr<nsIForcePendingChannel> forcePendingChannel =
         do_QueryInterface(request);
     if (forcePendingChannel) {
       forcePendingChannel->ForcePending(true);
     }
 
-    rv = FireListenerNotifications(request, nullptr);
+    rv = FireListenerNotifications(request, aCtxt);
 
     if (NS_FAILED(rv)) {
       aStatus = rv;
     }
 
     // now we need to set pending state to false before calling OnStopRequest
     if (forcePendingChannel) {
       forcePendingChannel->ForcePending(false);
@@ -309,17 +310,17 @@ nsUnknownDecoder::OnStopRequest(nsIReque
   }
 
   nsCOMPtr<nsIStreamListener> listener;
   {
     MutexAutoLock lock(mMutex);
     listener = mNextListener;
     mNextListener = nullptr;
   }
-  rv = listener->OnStopRequest(request, aStatus);
+  rv = listener->OnStopRequest(request, aCtxt, aStatus);
 
   return rv;
 }
 
 // ----
 //
 // nsIContentSniffer methods...
 //
@@ -683,29 +684,29 @@ nsresult nsUnknownDecoder::FireListenerN
     }
 
     NS_ASSERTION(NS_SUCCEEDED(rv), "Unable to set content type on channel!");
 
     if (NS_FAILED(rv)) {
       // Cancel the request to make sure it has the correct status if
       // mNextListener looks at it.
       request->Cancel(rv);
-      listener->OnStartRequest(request);
+      listener->OnStartRequest(request, aCtxt);
 
       nsCOMPtr<nsIDivertableChannel> divertable = do_QueryInterface(request);
       if (divertable) {
         rv = divertable->UnknownDecoderInvolvedOnStartRequestCalled();
       }
 
       return rv;
     }
   }
 
   // Fire the OnStartRequest(...)
-  rv = listener->OnStartRequest(request);
+  rv = listener->OnStartRequest(request, aCtxt);
 
   nsCOMPtr<nsIDivertableChannel> divertable = do_QueryInterface(request);
   if (divertable) {
     rv = divertable->UnknownDecoderInvolvedOnStartRequestCalled();
     bool diverting;
     divertable->GetDivertingToParent(&diverting);
     if (diverting) {
       // The channel is diverted to the parent do not send any more data here.
@@ -744,17 +745,17 @@ nsresult nsUnknownDecoder::FireListenerN
     // Create a pipe and fill it with the data from the sniffer buffer.
     rv = NS_NewPipe(getter_AddRefs(in), getter_AddRefs(out), MAX_BUFFER_SIZE,
                     MAX_BUFFER_SIZE);
 
     if (NS_SUCCEEDED(rv)) {
       rv = out->Write(mBuffer, mBufferLen, &len);
       if (NS_SUCCEEDED(rv)) {
         if (len == mBufferLen) {
-          rv = listener->OnDataAvailable(request, in, 0, len);
+          rv = listener->OnDataAvailable(request, aCtxt, in, 0, len);
         } else {
           NS_ERROR("Unable to write all the data into the pipe.");
           rv = NS_ERROR_FAILURE;
         }
       }
     }
   }
 
@@ -783,31 +784,31 @@ nsresult nsUnknownDecoder::ConvertEncode
     rv = encodedChannel->DoApplyContentConversions(
         strListener, getter_AddRefs(listener), nullptr);
 
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     if (listener) {
-      listener->OnStartRequest(request);
+      listener->OnStartRequest(request, nullptr);
 
       if (length) {
         nsCOMPtr<nsIStringInputStream> rawStream =
             do_CreateInstance(NS_STRINGINPUTSTREAM_CONTRACTID);
         if (!rawStream) return NS_ERROR_FAILURE;
 
         rv = rawStream->SetData((const char*)data, length);
         NS_ENSURE_SUCCESS(rv, rv);
 
-        rv = listener->OnDataAvailable(request, rawStream, 0, length);
+        rv = listener->OnDataAvailable(request, nullptr, rawStream, 0, length);
         NS_ENSURE_SUCCESS(rv, rv);
       }
 
-      listener->OnStopRequest(request, NS_OK);
+      listener->OnStopRequest(request, nullptr, NS_OK);
     }
   }
   return rv;
 }
 
 //
 // nsIThreadRetargetableStreamListener methods
 //
--- a/netwerk/test/browser/browser_cross_process_redirect.js
+++ b/netwerk/test/browser/browser_cross_process_redirect.js
@@ -117,23 +117,23 @@ add_task(async function() {
   info("Loading redirected URL");
   // Open the URL in the first process. We expect it to wind up in the second
   // process.
 
   // Define the child listener in the new channel.
   await ContentTask.spawn(browser2, null, async function(arg) {
     function ChannelListener(childListener) { this.childListener = childListener; }
     ChannelListener.prototype = {
-      onStartRequest: function(aRequest) {
+      onStartRequest: function(aRequest, aContext) {
         info("onStartRequest");
         let channel = aRequest.QueryInterface(Ci.nsIChannel);
         Assert.equal(channel.URI.spec, this.childListener.URI, "Make sure the channel has the proper URI");
         Assert.equal(channel.originalURI.spec, this.childListener.originalURI, "Make sure the originalURI is correct");
       },
-      onStopRequest: function(aRequest, aStatusCode) {
+      onStopRequest: function(aRequest, aContext, aStatusCode) {
         info("onStopRequest");
         Assert.equal(aStatusCode, Cr.NS_OK, "Check the status code");
         Assert.equal(this.gotData, true, "Check that the channel received data");
         if (this.childListener.onComplete) {
           this.childListener.onComplete();
         }
         this.childListener.resolve();
       },
--- a/netwerk/test/browser/browser_nsIFormPOSTActionChannel.js
+++ b/netwerk/test/browser/browser_nsIFormPOSTActionChannel.js
@@ -171,17 +171,17 @@ document.getElementById('form').submit()
     stream.setData(data, data.length);
 
     var runnable = {
       run: () => {
         try {
           aListener.onStartRequest(this, null);
         } catch(e) {}
         try {
-          aListener.onDataAvailable(this, stream, 0, stream.available());
+          aListener.onDataAvailable(this, null, stream, 0, stream.available());
         } catch(e) {}
         try {
           aListener.onStopRequest(this, null, Cr.NS_OK);
         } catch(e) {}
       }
     };
     Services.tm.dispatchToMainThread(runnable);
   },
--- a/netwerk/test/httpserver/httpd.js
+++ b/netwerk/test/httpserver/httpd.js
@@ -3714,21 +3714,21 @@ Response.prototype =
     var preamble = preambleData.join("");
 
     var responseHeadPipe = new Pipe(true, false, 0, PR_UINT32_MAX, null);
     responseHeadPipe.outputStream.write(preamble, preamble.length);
 
     var response = this;
     var copyObserver =
       {
-        onStartRequest(request) {
+        onStartRequest(request, cx) {
           dumpn("*** preamble copying started");
         },
 
-        onStopRequest(request, statusCode) {
+        onStopRequest(request, cx, statusCode) {
           dumpn("*** preamble copying complete " +
                 "[status=0x" + statusCode.toString(16) + "]");
 
           if (!Components.isSuccessCode(statusCode)) {
             dumpn("!!! header copying problems: non-success statusCode, " +
                   "ending response");
 
             response.end();
@@ -3765,21 +3765,21 @@ Response.prototype =
       dumpn("*** empty body, response finished");
       this.end();
       return;
     }
 
     var response = this;
     var copyObserver =
       {
-        onStartRequest(request) {
+        onStartRequest(request, context) {
           dumpn("*** onStartRequest");
         },
 
-        onStopRequest(request, statusCode) {
+        onStopRequest(request, cx, statusCode) {
           dumpn("*** onStopRequest [status=0x" + statusCode.toString(16) + "]");
 
           if (statusCode === Cr.NS_BINDING_ABORTED) {
             dumpn("*** terminating copy observer without ending the response");
           } else {
             if (!Components.isSuccessCode(statusCode))
               dumpn("*** WARNING: non-success statusCode in onStopRequest");
 
@@ -3878,17 +3878,17 @@ function WriteThroughCopier(source, sink
   /** Status of this request. */
   this.status = Cr.NS_OK;
 
   /** Arrays of byte strings waiting to be written to output. */
   this._pendingData = [];
 
   // start copying
   try {
-    observer.onStartRequest(this);
+    observer.onStartRequest(this, context);
     this._waitToReadData();
     this._waitForSinkClosure();
   } catch (e) {
     dumpn("!!! error starting copy: " + e +
           ("lineNumber" in e ? ", line " + e.lineNumber : ""));
     dumpn(e.stack);
     this.cancel(Cr.NS_ERROR_UNEXPECTED);
   }
@@ -4241,17 +4241,17 @@ WriteThroughCopier.prototype =
     var self = this;
     var event =
       {
         run() {
           dumpn("*** onStopRequest async callback");
 
           self._completed = true;
           try {
-            self._observer.onStopRequest(self, self.status);
+            self._observer.onStopRequest(self, self._context, self.status);
           } catch (e) {
             NS_ASSERT(false,
                       "how are we throwing an exception here?  we control " +
                       "all the callers!  " + e);
           }
         },
       };
 
--- a/netwerk/test/httpserver/test/head_utils.js
+++ b/netwerk/test/httpserver/test/head_utils.js
@@ -270,53 +270,53 @@ function runHttpTests(testArray, done) {
   /** Stream listener for the channels. */
   var listener =
     {
       /** Current channel being observed by this. */
       _channel: null,
       /** Array of bytes of data in body of response. */
       _data: [],
 
-      onStartRequest(request) {
+      onStartRequest(request, cx) {
         Assert.ok(request === this._channel);
         var ch = request.QueryInterface(Ci.nsIHttpChannel)
                         .QueryInterface(Ci.nsIHttpChannelInternal);
 
         this._data.length = 0;
         try {
           try {
-            testArray[testIndex].onStartRequest(ch);
+            testArray[testIndex].onStartRequest(ch, cx);
           } catch (e) {
             do_report_unexpected_exception(e, "testArray[" + testIndex + "].onStartRequest");
           }
         } catch (e) {
           do_note_exception(e, "!!! swallowing onStartRequest exception so onStopRequest is " +
                 "called...");
         }
       },
-      onDataAvailable(request, inputStream, offset, count) {
+      onDataAvailable(request, cx, inputStream, offset, count) {
         var quantum = 262144; // just above half the argument-count limit
         var bis = makeBIS(inputStream);
         for (var start = 0; start < count; start += quantum) {
           var newData = bis.readByteArray(Math.min(quantum, count - start));
           Array.prototype.push.apply(this._data, newData);
         }
       },
-      onStopRequest(request, status) {
+      onStopRequest(request, cx, status) {
         this._channel = null;
 
         var ch = request.QueryInterface(Ci.nsIHttpChannel)
                         .QueryInterface(Ci.nsIHttpChannelInternal);
 
         // NB: The onStopRequest callback must run before performNextTest here,
         //     because the latter runs the next test's initChannel callback, and
         //     we want one test to be sequentially processed before the next
         //     one.
         try {
-          testArray[testIndex].onStopRequest(ch, status, this._data);
+          testArray[testIndex].onStopRequest(ch, cx, status, this._data);
         } finally {
           try {
             performNextTest();
           } finally {
             do_test_finished();
           }
         }
       },
--- a/netwerk/test/httpserver/test/test_async_response_sending.js
+++ b/netwerk/test/httpserver/test/test_async_response_sending.js
@@ -1469,29 +1469,31 @@ CopyTest.prototype =
    */
   _addToTasks: function _addToTasks(task) {
     this._tasks.push(task);
   },
 
   //
   // see nsIRequestObserver.onStartRequest
   //
-  onStartRequest: function onStartRequest(self) {
+  onStartRequest: function onStartRequest(self, _) {
     dumpn("*** CopyTest.onStartRequest (" + self.name + ")");
 
+    Assert.ok(_ === null);
     Assert.equal(this._receivedData.length, 0);
     Assert.equal(this._lastQuantum.length, 0);
   },
 
   //
   // see nsIRequestObserver.onStopRequest
   //
-  onStopRequest: function onStopRequest(self, status) {
+  onStopRequest: function onStopRequest(self, _, status) {
     dumpn("*** CopyTest.onStopRequest (" + self.name + ", " + status + ")");
 
+    Assert.ok(_ === null);
     this._actualStatus = status;
 
     this._copyingFinished = true;
 
     if (this._allDataWritten) {
       dumpn("*** all data written, continuing with remaining tests...");
       this._testComplete();
     } else {
--- a/netwerk/test/httpserver/test/test_basic_functionality.js
+++ b/netwerk/test/httpserver/test/test_basic_functionality.js
@@ -53,54 +53,54 @@ const HEADER_COUNT = 1000;
 // or invariants for every URL in paths
 function commonCheck(ch) {
   Assert.ok(ch.contentLength > -1);
   Assert.equal(ch.getResponseHeader("connection"), "close");
   Assert.ok(!ch.isNoStoreResponse());
   Assert.ok(!ch.isPrivateResponse());
 }
 
-function start_objHandler(ch) {
+function start_objHandler(ch, cx) {
   commonCheck(ch);
 
   Assert.equal(ch.responseStatus, 200);
   Assert.ok(ch.requestSucceeded);
   Assert.equal(ch.getResponseHeader("content-type"), "text/plain");
   Assert.equal(ch.responseStatusText, "OK");
 
   var reqMin = {}, reqMaj = {}, respMin = {}, respMaj = {};
   ch.getRequestVersion(reqMaj, reqMin);
   ch.getResponseVersion(respMaj, respMin);
   Assert.ok(reqMaj.value == respMaj.value &&
             reqMin.value == respMin.value);
 }
 
-function start_functionHandler(ch) {
+function start_functionHandler(ch, cx) {
   commonCheck(ch);
 
   Assert.equal(ch.responseStatus, 404);
   Assert.ok(!ch.requestSucceeded);
   Assert.equal(ch.getResponseHeader("foopy"), "quux-baz");
   Assert.equal(ch.responseStatusText, "Page Not Found");
 
   var reqMin = {}, reqMaj = {}, respMin = {}, respMaj = {};
   ch.getRequestVersion(reqMaj, reqMin);
   ch.getResponseVersion(respMaj, respMin);
   Assert.ok(reqMaj.value == 1 && reqMin.value == 1);
   Assert.ok(respMaj.value == 1 && respMin.value == 1);
 }
 
-function start_non_existent_path(ch) {
+function start_non_existent_path(ch, cx) {
   commonCheck(ch);
 
   Assert.equal(ch.responseStatus, 404);
   Assert.ok(!ch.requestSucceeded);
 }
 
-function start_lots_of_headers(ch) {
+function start_lots_of_headers(ch, cx) {
   commonCheck(ch);
 
   Assert.equal(ch.responseStatus, 200);
   Assert.ok(ch.requestSucceeded);
 
   for (var i = 0; i < HEADER_COUNT; i++)
     Assert.equal(ch.getResponseHeader("X-Header-" + i), "value " + i);
 }
--- a/netwerk/test/httpserver/test/test_byte_range.js
+++ b/netwerk/test/httpserver/test/test_byte_range.js
@@ -50,192 +50,192 @@ function run_test() {
   var dir = do_get_file("data/ranges/");
   srv.registerDirectory("/", dir);
 
   srv.start(-1);
 
   runHttpTests(tests, testComplete(srv));
 }
 
-function start_normal(ch) {
+function start_normal(ch, cx) {
   Assert.equal(ch.responseStatus, 200);
   Assert.equal(ch.getResponseHeader("Content-Length"), "21");
   Assert.equal(ch.getResponseHeader("Content-Type"), "text/plain");
 }
 
-function stop_normal(ch, status, data) {
+function stop_normal(ch, cx, status, data) {
   Assert.equal(data.length, 21);
   Assert.equal(data[0], 0x54);
   Assert.equal(data[20], 0x0a);
 }
 
 function init_byterange(ch) {
   ch.setRequestHeader("Range", "bytes=10-", false);
 }
 
-function start_byterange(ch) {
+function start_byterange(ch, cx) {
   Assert.equal(ch.responseStatus, 206);
   Assert.equal(ch.getResponseHeader("Content-Length"), "11");
   Assert.equal(ch.getResponseHeader("Content-Type"), "text/plain");
   Assert.equal(ch.getResponseHeader("Content-Range"), "bytes 10-20/21");
 }
 
-function stop_byterange(ch, status, data) {
+function stop_byterange(ch, cx, status, data) {
   Assert.equal(data.length, 11);
   Assert.equal(data[0], 0x64);
   Assert.equal(data[10], 0x0a);
 }
 
 function init_byterange2(ch) {
   ch.setRequestHeader("Range", "bytes=21-", false);
 }
 
-function start_byterange2(ch) {
+function start_byterange2(ch, cx) {
   Assert.equal(ch.responseStatus, 416);
 }
 
 function init_byterange3(ch) {
   ch.setRequestHeader("Range", "bytes=10-15", false);
 }
 
-function start_byterange3(ch) {
+function start_byterange3(ch, cx) {
   Assert.equal(ch.responseStatus, 206);
   Assert.equal(ch.getResponseHeader("Content-Length"), "6");
   Assert.equal(ch.getResponseHeader("Content-Type"), "text/plain");
   Assert.equal(ch.getResponseHeader("Content-Range"), "bytes 10-15/21");
 }
 
-function stop_byterange3(ch, status, data) {
+function stop_byterange3(ch, cx, status, data) {
   Assert.equal(data.length, 6);
   Assert.equal(data[0], 0x64);
   Assert.equal(data[1], 0x20);
   Assert.equal(data[2], 0x62);
   Assert.equal(data[3], 0x65);
   Assert.equal(data[4], 0x20);
   Assert.equal(data[5], 0x73);
 }
 
 function init_byterange4(ch) {
   ch.setRequestHeader("Range", "xbytes=21-", false);
 }
 
-function start_byterange4(ch) {
+function start_byterange4(ch, cx) {
   Assert.equal(ch.responseStatus, 400);
 }
 
 function init_byterange5(ch) {
   ch.setRequestHeader("Range", "bytes=-5", false);
 }
 
-function start_byterange5(ch) {
+function start_byterange5(ch, cx) {
   Assert.equal(ch.responseStatus, 206);
 }
 
-function stop_byterange5(ch, status, data) {
+function stop_byterange5(ch, cx, status, data) {
   Assert.equal(data.length, 5);
   Assert.equal(data[0], 0x65);
   Assert.equal(data[1], 0x65);
   Assert.equal(data[2], 0x6e);
   Assert.equal(data[3], 0x2e);
   Assert.equal(data[4], 0x0a);
 }
 
 function init_byterange6(ch) {
   ch.setRequestHeader("Range", "bytes=15-12", false);
 }
 
-function start_byterange6(ch) {
+function start_byterange6(ch, cx) {
   Assert.equal(ch.responseStatus, 200);
 }
 
-function stop_byterange6(ch, status, data) {
+function stop_byterange6(ch, cx, status, data) {
   Assert.equal(data.length, 21);
   Assert.equal(data[0], 0x54);
   Assert.equal(data[20], 0x0a);
 }
 
 function init_byterange7(ch) {
   ch.setRequestHeader("Range", "bytes=0-5", false);
 }
 
-function start_byterange7(ch) {
+function start_byterange7(ch, cx) {
   Assert.equal(ch.responseStatus, 206);
   Assert.equal(ch.getResponseHeader("Content-Length"), "6");
   Assert.equal(ch.getResponseHeader("Content-Type"), "text/plain");
   Assert.equal(ch.getResponseHeader("Content-Range"), "bytes 0-5/21");
 }
 
-function stop_byterange7(ch, status, data) {
+function stop_byterange7(ch, cx, status, data) {
   Assert.equal(data.length, 6);
   Assert.equal(data[0], 0x54);
   Assert.equal(data[1], 0x68);
   Assert.equal(data[2], 0x69);
   Assert.equal(data[3], 0x73);
   Assert.equal(data[4], 0x20);
   Assert.equal(data[5], 0x73);
 }
 
 function init_byterange8(ch) {
   ch.setRequestHeader("Range", "bytes=20-21", false);
 }
 
-function start_byterange8(ch) {
+function start_byterange8(ch, cx) {
   Assert.equal(ch.responseStatus, 206);
   Assert.equal(ch.getResponseHeader("Content-Range"), "bytes 20-20/21");
 }
 
-function stop_byterange8(ch, status, data) {
+function stop_byterange8(ch, cx, status, data) {
   Assert.equal(data.length, 1);
   Assert.equal(data[0], 0x0a);
 }
 
 function init_byterange9(ch) {
   ch.setRequestHeader("Range", "bytes=020-021", false);
 }
 
-function start_byterange9(ch) {
+function start_byterange9(ch, cx) {
   Assert.equal(ch.responseStatus, 206);
 }
 
-function stop_byterange9(ch, status, data) {
+function stop_byterange9(ch, cx, status, data) {
   Assert.equal(data.length, 1);
   Assert.equal(data[0], 0x0a);
 }
 
 function init_byterange10(ch) {
   ch.setRequestHeader("Range", "bytes=-", false);
 }
 
-function start_byterange10(ch) {
+function start_byterange10(ch, cx) {
   Assert.equal(ch.responseStatus, 400);
 }
 
 function init_byterange11(ch) {
   ch.setRequestHeader("Range", "bytes=-500", false);
 }
 
-function start_byterange11(ch) {
+function start_byterange11(ch, cx) {
   Assert.equal(ch.responseStatus, 206);
 }
 
-function stop_byterange11(ch, status, data) {
+function stop_byterange11(ch, cx, status, data) {
   Assert.equal(data.length, 21);
   Assert.equal(data[0], 0x54);
   Assert.equal(data[20], 0x0a);
 }
 
-function start_byterange12(ch) {
+function start_byterange12(ch, cx) {
   Assert.equal(ch.responseStatus, 200);
   Assert.equal(ch.getResponseHeader("Content-Length"), "0");
 }
 
-function stop_byterange12(ch, status, data) {
+function stop_byterange12(ch, cx, status, data) {
   Assert.equal(data.length, 0);
 }
 
 function init_byterange13(ch) {
   ch.setRequestHeader("Range", "bytes=9999999-", false);
 }
 
-function start_byterange13(ch) {
+function start_byterange13(ch, cx) {
   Assert.equal(ch.responseStatus, 416);
   Assert.equal(ch.getResponseHeader("X-SJS-Header"), "customized");
 }
--- a/netwerk/test/httpserver/test/test_cern_meta.js
+++ b/netwerk/test/httpserver/test/test_cern_meta.js
@@ -35,36 +35,36 @@ function run_test() {
   srv.start(-1);
 
   runHttpTests(tests, testComplete(srv));
 }
 
 
 // TEST DATA
 
-function start_testBoth(ch) {
+function start_testBoth(ch, cx) {
   Assert.equal(ch.responseStatus, 501);
   Assert.equal(ch.responseStatusText, "Unimplemented");
 
   Assert.equal(ch.getResponseHeader("Content-Type"), "text/plain");
 }
 
-function start_test_ctype_override_txt(ch) {
+function start_test_ctype_override_txt(ch, cx) {
   Assert.equal(ch.getResponseHeader("Content-Type"), "text/html");
 }
 
-function start_test_status_override_html(ch) {
+function start_test_status_override_html(ch, cx) {
   Assert.equal(ch.responseStatus, 404);
   Assert.equal(ch.responseStatusText, "Can't Find This");
 }
 
-function start_test_status_override_nodesc_txt(ch) {
+function start_test_status_override_nodesc_txt(ch, cx) {
   Assert.equal(ch.responseStatus, 732);
   Assert.equal(ch.responseStatusText, "");
 }
 
-function start_caret_test_txt_(ch) {
+function start_caret_test_txt_(ch, cx) {
   Assert.equal(ch.responseStatus, 500);
   Assert.equal(ch.responseStatusText, "This Isn't A Server Error");
 
   Assert.equal(ch.getResponseHeader("Foo-RFC"), "3092");
   Assert.equal(ch.getResponseHeader("Shaving-Cream-Atom"), "Illudium Phosdex");
 }
--- a/netwerk/test/httpserver/test/test_default_index_handler.js
+++ b/netwerk/test/httpserver/test/test_default_index_handler.js
@@ -217,21 +217,21 @@ XPCOMUtils.defineLazyGetter(this, "tests
     new Test(BASE_URL + "bar/folder^/", null, start, stopTrailingCaretDirectory),
   ];
 });
 
 // check top-level directory listing
 function start(ch) {
   Assert.equal(ch.getResponseHeader("Content-Type"), "text/html;charset=utf-8");
 }
-function stopRootDirectory(ch, status, data) {
+function stopRootDirectory(ch, cx, status, data) {
   dataCheck(data, BASE_URL, "/", gDirEntries[0]);
 }
 
 // check non-top-level, too
-function stopFooDirectory(ch, status, data) {
+function stopFooDirectory(ch, cx, status, data) {
   dataCheck(data, BASE_URL + "foo/", "/foo/", gDirEntries[1]);
 }
 
 // trailing-caret leaf with hidden files
-function stopTrailingCaretDirectory(ch, status, data) {
+function stopTrailingCaretDirectory(ch, cx, status, data) {
   hiddenDataCheck(data, BASE_URL + "bar/folder^/", "/bar/folder^/");
 }
--- a/netwerk/test/httpserver/test/test_empty_body.js
+++ b/netwerk/test/httpserver/test/test_empty_body.js
@@ -27,17 +27,17 @@ function run_test() {
 
   srv.start(-1);
 
   runHttpTests(tests, testComplete(srv));
 }
 
 // TEST DATA
 
-function ensureEmpty(ch) {
+function ensureEmpty(ch, cx) {
   Assert.ok(ch.contentLength == 0);
 }
 
 // PATH HANDLERS
 
 // /empty-body-unwritten
 function emptyBodyUnwritten(metadata, response) {
   response.setStatusLine("1.1", 200, "OK");
--- a/netwerk/test/httpserver/test/test_errorhandler_exception.js
+++ b/netwerk/test/httpserver/test/test_errorhandler_exception.js
@@ -41,29 +41,29 @@ function checkStatusLine(channel, httpMa
   Assert.equal(channel.responseStatusText, statusText);
 
   var respMaj = {}, respMin = {};
   channel.getResponseVersion(respMaj, respMin);
   Assert.equal(respMaj.value, httpMaxVer);
   Assert.equal(respMin.value, httpMinVer);
 }
 
-function start_throws_exception(ch) {
+function start_throws_exception(ch, cx) {
   checkStatusLine(ch, 1, 1, 500, "Internal Server Error");
 }
 
-function start_nonexistent_404_fails_so_400(ch) {
+function start_nonexistent_404_fails_so_400(ch, cx) {
   checkStatusLine(ch, 1, 1, 400, "Bad Request");
 }
 
-function start_multiple_exceptions_500(ch) {
+function start_multiple_exceptions_500(ch, cx) {
   checkStatusLine(ch, 1, 1, 500, "Internal Server Error");
 }
 
-function succeeded(ch, status, data) {
+function succeeded(ch, cx, status, data) {
   Assert.ok(Components.isSuccessCode(status));
 }
 
 function register400Handler(ch) {
   srv.registerErrorHandler(400, throwsException);
 }
 
 
--- a/netwerk/test/httpserver/test/test_header_array.js
+++ b/netwerk/test/httpserver/test/test_header_array.js
@@ -47,17 +47,17 @@ function pathHandler(request, response) 
 
 XPCOMUtils.defineLazyGetter(this, "tests", function() {
   return [
     new Test("http://localhost:" + srv.identity.primaryPort + "/path-handler",
              null, check),
   ];
 });
 
-function check(ch) {
+function check(ch, cx) {
   var headerValue;
 
   headerValue = ch.getResponseHeader("Proxy-Authenticate");
   Assert.equal(headerValue, "First line 1\nSecond line 1\nThird line 1");
   headerValue = ch.getResponseHeader("WWW-Authenticate");
   Assert.equal(headerValue, "First line 2\nSecond line 2\nThird line 2");
   headerValue = ch.getResponseHeader("X-Single-Header-Merge");
   Assert.equal(headerValue, "Single 1,Single 2");
--- a/netwerk/test/httpserver/test/test_name_scheme.js
+++ b/netwerk/test/httpserver/test/test_name_scheme.js
@@ -59,27 +59,27 @@ function run_test() {
   srv.start(-1);
 
   runHttpTests(tests, testComplete(srv));
 }
 
 
 // TEST DATA
 
-function start_bar_html_(ch) {
+function start_bar_html_(ch, cx) {
   Assert.equal(ch.responseStatus, 200);
 
   Assert.equal(ch.getResponseHeader("Content-Type"), "text/html");
 }
 
-function start_foo_html_(ch) {
+function start_foo_html_(ch, cx) {
   Assert.equal(ch.responseStatus, 404);
 }
 
-function start_normal_file_txt(ch) {
+function start_normal_file_txt(ch, cx) {
   Assert.equal(ch.responseStatus, 200);
   Assert.equal(ch.getResponseHeader("Content-Type"), "text/plain");
 }
 
-function start_folder__file_txt(ch) {
+function start_folder__file_txt(ch, cx) {
   Assert.equal(ch.responseStatus, 200);
   Assert.equal(ch.getResponseHeader("Content-Type"), "text/plain");
 }
--- a/netwerk/test/httpserver/test/test_processasync.js
+++ b/netwerk/test/httpserver/test/test_processasync.js
@@ -52,17 +52,17 @@ function handleSync(request, response) {
   } catch (e) {
     isException(e, Cr.NS_ERROR_UNEXPECTED);
   }
 
   response.setStatusLine(request.httpVersion, 200, "handleSync pass");
 }
 handlers["/handleSync"] = handleSync;
 
-function start_handleSync(ch) {
+function start_handleSync(ch, cx) {
   Assert.equal(ch.responseStatus, 200);
   Assert.equal(ch.responseStatusText, "handleSync pass");
 }
 
 function handleAsync1(request, response) {
   response.setStatusLine(request.httpVersion, 500, "Old status line!");
   response.setHeader("X-Foo", "old value", false);
 
@@ -98,23 +98,23 @@ function handleAsync1(request, response)
     response.write("fugly");
     do_throw("late write() didn't throw");
   } catch (e) {
     isException(e, Cr.NS_ERROR_NOT_AVAILABLE);
   }
 }
 handlers["/handleAsync1"] = handleAsync1;
 
-function start_handleAsync1(ch) {
+function start_handleAsync1(ch, cx) {
   Assert.equal(ch.responseStatus, 200);
   Assert.equal(ch.responseStatusText, "New status line!");
   Assert.equal(ch.getResponseHeader("