Backed out 16 changesets (bug 1607984) for multiple test failures e.g test timeouts on a CLOSED TREE

Backed out changeset 4509808243f5 (bug 1607984)
Backed out changeset 0cb21bedf65f (bug 1607984)
Backed out changeset 4e5d89f68293 (bug 1607984)
Backed out changeset 0c0169ed4f04 (bug 1607984)
Backed out changeset ce527a6ffba4 (bug 1607984)
Backed out changeset 63175f596762 (bug 1607984)
Backed out changeset 107be8f3737d (bug 1607984)
Backed out changeset d7600d4d3528 (bug 1607984)
Backed out changeset e11b1b0ecfbf (bug 1607984)
Backed out changeset bed3f6bee79e (bug 1607984)
Backed out changeset abe692da4556 (bug 1607984)
Backed out changeset e02b12515d60 (bug 1607984)
Backed out changeset 7a2ef225a41e (bug 1607984)
Backed out changeset c173bde5106b (bug 1607984)
Backed out changeset dc8b37e10dc7 (bug 1607984)
Backed out changeset 09a651daf344 (bug 1607984)
This commit is contained in:
Andreea Pavel 2020-04-23 03:47:24 +03:00
Родитель 4d15b0fd2e
Коммит cac786a35c
28 изменённых файлов: 281 добавлений и 799 удалений

Просмотреть файл

@ -135,11 +135,6 @@ function openBrowserWindowIntl() {
function startBrowserTests() {
if (gBrowserContext.startURL) {
// Make sure the window is the one loading our URL.
if (currentBrowser().contentWindow.location != gBrowserContext.startURL) {
setTimeout(startBrowserTests, 0);
return;
}
// wait for load
addA11yLoadEvent(gBrowserContext.testFunc, currentBrowser().contentWindow);
} else {

Просмотреть файл

@ -228,9 +228,6 @@ var whitelist = [
// Referenced from the screenshots webextension
{ file: "resource://app/localization/en-US/browser/screenshots.ftl" },
// services/sync/modules/bridged_engine.js
{ file: "resource://services-sync/bridged_engine.js" },
];
if (AppConstants.NIGHTLY_BUILD && AppConstants.platform != "win") {
@ -272,6 +269,8 @@ for (let entry of ignorableWhitelist) {
if (!isDevtools) {
// services/sync/modules/main.js
whitelist.add("resource://services-sync/service.js");
// services/sync/modules/bridged_engine.js
whitelist.add("resource://services-sync/bridged_engine.js");
// services/sync/modules/service.js
for (let module of [
"addons.js",

Просмотреть файл

@ -12,28 +12,9 @@ add_task(async function setup() {
});
add_task(async function test_open_preferences() {
// We want to make sure we visit about:preferences#privacy-logins , as that is
// what causes us to scroll to and highlight the "logins" section. However,
// about:preferences will redirect the URL, so the eventual load event will happen
// on about:preferences#privacy . The `wantLoad` parameter we pass to
// `waitForNewTab` needs to take this into account:
let seenFirstURL = false;
let promiseNewTab = BrowserTestUtils.waitForNewTab(
gBrowser,
url => {
if (url == "about:preferences#privacy-logins") {
seenFirstURL = true;
return true;
} else if (url == "about:preferences#privacy") {
ok(
seenFirstURL,
"Must have seen an onLocationChange notification for the privacy-logins hash"
);
return true;
}
return false;
},
true
"about:preferences#privacy-logins"
);
let browser = gBrowser.selectedBrowser;

Просмотреть файл

@ -195,7 +195,6 @@ nsDSURIContentListener::DoContent(const nsACString& aContentType,
if (NS_FAILED(rv)) {
// we don't know how to handle the content
nsCOMPtr<nsIStreamListener> forget = dont_AddRef(*aContentHandler);
*aContentHandler = nullptr;
return rv;
}

Просмотреть файл

@ -73,8 +73,9 @@
#include "mozilla/dom/nsCSPContext.h"
#include "mozilla/dom/LoadURIOptionsBinding.h"
#include "mozilla/dom/JSWindowActorChild.h"
#include "nsSHEntry.h"
#include "mozilla/net/DocumentChannel.h"
#include "nsSHEntry.h"
#include "mozilla/net/DocumentChannelChild.h"
#include "mozilla/net/UrlClassifierFeatureFactory.h"
#include "ReferrerInfo.h"
@ -5712,8 +5713,7 @@ void nsDocShell::OnRedirectStateChange(nsIChannel* aOldChannel,
// of redirects handled in the parent process.
// Query the full redirect chain directly, so that we can add history
// entries for them.
RefPtr<DocumentChannel> docChannel = do_QueryObject(aOldChannel);
if (docChannel) {
if (RefPtr<DocumentChannel> docChannel = do_QueryObject(aOldChannel)) {
nsCOMPtr<nsIURI> previousURI;
uint32_t previousFlags = 0;
docChannel->GetLastVisit(getter_AddRefs(previousURI), &previousFlags);
@ -5761,7 +5761,7 @@ void nsDocShell::OnRedirectStateChange(nsIChannel* aOldChannel,
// check if the new load should go through the application cache.
nsCOMPtr<nsIApplicationCacheChannel> appCacheChannel =
do_QueryInterface(aNewChannel);
if (appCacheChannel && !docChannel) {
if (appCacheChannel) {
if (GeckoProcessType_Default != XRE_GetProcessType()) {
// Permission will be checked in the parent process.
appCacheChannel->SetChooseApplicationCache(true);
@ -9188,6 +9188,23 @@ static bool IsConsideredSameOriginForUIR(nsIPrincipal* aTriggeringPrincipal,
return NS_OK;
}
// Changes here should also be made in
// E10SUtils.documentChannelPermittedForURI().
static bool URIUsesDocChannel(nsIURI* aURI) {
if (SchemeIsJavascript(aURI) || NS_IsAboutBlank(aURI)) {
return false;
}
nsCString spec = aURI->GetSpecOrDefault();
if (spec.EqualsLiteral("about:printpreview") ||
spec.EqualsLiteral("about:crashcontent")) {
return false;
}
return true;
}
/* static */ bool nsDocShell::CreateAndConfigureRealChannelForLoadState(
BrowsingContext* aBrowsingContext, nsDocShellLoadState* aLoadState,
LoadInfo* aLoadInfo, nsIInterfaceRequestor* aCallbacks,
@ -9588,9 +9605,8 @@ nsresult nsDocShell::DoURILoad(nsDocShellLoadState* aLoadState,
// If we have a pending channel, use the channel we've already created here.
// We don't need to set up load flags for our channel, as it has already been
// created.
if (nsCOMPtr<nsIChannel> channel =
aLoadState->GetPendingRedirectedChannel()) {
nsCOMPtr<nsIChannel> channel = aLoadState->GetPendingRedirectedChannel();
if (channel) {
MOZ_ASSERT(!aLoadState->HasLoadFlags(INTERNAL_LOAD_FLAGS_IS_SRCDOC),
"pending channel for srcdoc load?");
@ -9759,11 +9775,20 @@ nsresult nsDocShell::DoURILoad(nsDocShellLoadState* aLoadState,
cacheKey = mOSHE->GetCacheKey();
}
nsCOMPtr<nsIChannel> channel;
if (DocumentChannel::CanUseDocumentChannel(aLoadState)) {
channel = DocumentChannel::CreateDocumentChannel(aLoadState, loadInfo,
loadFlags, this, cacheKey);
MOZ_ASSERT(channel);
// We want to use DocumentChannel if we're using a supported scheme. Sandboxed
// srcdoc loads break due to failing assertions after changing processes, and
// non-sandboxed srcdoc loads need to share the same principal object as their
// outer document (and must load in the same process), which breaks if we
// serialize to the parent process.
bool canUseDocumentChannel =
!aLoadState->HasLoadFlags(INTERNAL_LOAD_FLAGS_IS_SRCDOC) &&
URIUsesDocChannel(aLoadState->URI());
if (StaticPrefs::browser_tabs_documentchannel() && XRE_IsContentProcess() &&
canUseDocumentChannel) {
channel =
new DocumentChannelChild(aLoadState, loadInfo, loadFlags, cacheKey);
channel->SetNotificationCallbacks(this);
} else if (!CreateAndConfigureRealChannelForLoadState(
mBrowsingContext, aLoadState, loadInfo, this, this,
GetOriginAttributes(), loadFlags, cacheKey, rv,

Просмотреть файл

@ -95,7 +95,7 @@ var RequestWatcher = {
// We may also see, eg, chrome://global/skin/icons/resizer.svg, so
// skip chrome:// URLs too.
if (req.name.startsWith("about:") || req.name.startsWith("resource:") ||
req.name.startsWith("chrome:") || req.name.startsWith("documentchannel:")) {
req.name.startsWith("chrome:")) {
return;
}
is(req.loadFlags & TEST_FLAGS, TEST_FLAGS, "request " + req.name + " has the expected flags");

Просмотреть файл

@ -1,91 +1,67 @@
<!DOCTYPE html>
<!DOCTYPE HTML>
<html>
<!--
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1339722
-->
<head>
<meta charset="utf-8" />
<title>Test for Bug 1339722</title>
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://global/skin" />
<link
rel="stylesheet"
type="text/css"
href="chrome://mochikit/content/tests/SimpleTest/test.css"
/>
<script type="application/javascript">
/**
* Test for Bug 1339722
* 1. Wait for "http-on-modify-request" or document-on-modify-request for the
* iframe load.
* 2. In the observer, access it's window proxy to trigger DOMWindowCreated.
* 3. In the event handler, delete the iframe so that the frameloader would be
* destroyed in the middle of ReallyStartLoading.
* 4. Verify that it doesn't crash.
**/
<head>
<meta charset="utf-8">
<title>Test for Bug 1339722</title>
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://global/skin"/>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
<script type="application/javascript">
const { Services } = ChromeUtils.import(
"resource://gre/modules/Services.jsm"
);
// This topic used to be http-on-useragent-request, but that got removed in
// bug 1513574. on-modify-request is called around the same time, and should
// behave similarly.
const TOPIC = SpecialPowers.getBoolPref("browser.tabs.documentchannel")
? "document-on-modify-request"
: "http-on-modify-request";
let win;
const observe = (subject, topic, data) => {
info("Got " + topic);
Services.obs.removeObserver(observe, TOPIC);
/**
* Test for Bug 1339722
* 1. Wait for "http-on-modify-request" for the iframe load.
* 2. In the observer, access it's window proxy to trigger DOMWindowCreated.
* 3. In the event handler, delete the iframe so that the frameloader would be
* destoryed in the middle of ReallyStartLoading.
* 4. Verify that it doesn't crash.
**/
// Query window proxy so it triggers DOMWindowCreated.
let channel;
try {
// We need to QI nsIHttpChannel in order to load the interface's
// methods / attributes for later code that could assume we are dealing
// with a nsIHttpChannel.
channel = subject.QueryInterface(Ci.nsIHttpChannel);
} catch (e) {
channel = subject.QueryInterface(Ci.nsIIdentChannel);
}
win = channel.notificationCallbacks.getInterface(Ci.mozIDOMWindowProxy);
};
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
Services.obs.addObserver(observe, TOPIC);
// This topic used to be http-on-useragent-request, but that got removed in
// bug 1513574. on-modify-request is called around the same time, and should
// behave similarly.
const TOPIC = "http-on-modify-request";
let win;
Services.obs.addObserver({
observe(subject, topic, data) {
info("Got " + topic);
Services.obs.removeObserver(this, TOPIC);
let docShell = SpecialPowers.wrap(window).docShell;
docShell.chromeEventHandler.addEventListener(
"DOMWindowCreated",
function handler(e) {
info("Got DOMWindowCreated");
let iframe = document.getElementById("testFrame");
is(e.target, iframe.contentDocument, "verify event target");
// Query window proxy so it triggers DOMWindowCreated.
let channel = subject.QueryInterface(Ci.nsIHttpChannel);
win = channel.notificationCallbacks.getInterface(Ci.mozIDOMWindowProxy);
},
}, TOPIC);
// Remove the iframe to cause frameloader destroy.
iframe.remove();
setTimeout(($) => {
ok(!document.getElementById("testFrame"), "verify iframe removed");
SimpleTest.finish();
}, 0);
},
{ once: true }
);
let docShell = SpecialPowers.wrap(window).docShell;
docShell.chromeEventHandler.addEventListener("DOMWindowCreated", function handler(e) {
let iframe = document.getElementById("testFrame");
is(e.target, iframe.contentDocument, "verify event target");
SimpleTest.waitForExplicitFinish();
</script>
</head>
<body>
<a
target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=1339722"
>Mozilla Bug 1339722</a
>
<p id="display"></p>
<div id="content" style="display: none;"></div>
<pre id="test">
// Remove the iframe to cause frameloader destroy.
iframe.remove();
setTimeout($ => {
ok(!document.getElementById("testFrame"), "verify iframe removed");
SimpleTest.finish();
}, 0);
}, {once: true});
SimpleTest.waitForExplicitFinish();
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1339722">Mozilla Bug 1339722</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<div id="frameContainer">
<iframe id="testFrame" src="http://www.example.com"></iframe>
</div>
</pre>
</body>
</body>
</html>

Просмотреть файл

@ -997,6 +997,7 @@ nsJARChannel::OnStartRequest(nsIRequest* req) {
mRequest = req;
nsresult rv = mListener->OnStartRequest(this);
mRequest = nullptr;
if (NS_FAILED(rv)) {
return rv;
}
@ -1037,7 +1038,6 @@ nsJARChannel::OnStopRequest(nsIRequest* req, nsresult status) {
if (mLoadGroup) mLoadGroup->RemoveRequest(this, nullptr, status);
mRequest = nullptr;
mPump = nullptr;
mIsPending = false;

Просмотреть файл

@ -979,15 +979,6 @@
value: true
mirror: always
- name: browser.tabs.documentchannel.ppdc
type: bool
#if defined(ANDROID)
value: false # Disabled due to reftest start failures.
#else
value: true
#endif
mirror: always
- name: browser.tabs.remote.desktopbehavior
type: bool
value: false

Просмотреть файл

@ -47,7 +47,6 @@ class ADocumentChannelBridge {
uint32_t aRedirectFlags, uint32_t aLoadFlags) = 0;
// Returns the process id that this bridge is connected to.
// If 0 indicates that the load is started from the parent process.
virtual base::ProcessId OtherPid() const = 0;
protected:

Просмотреть файл

@ -10,24 +10,20 @@
#include "SerializedLoadContext.h"
#include "mozIThirdPartyUtil.h"
#include "mozilla/LoadInfo.h"
#include "mozilla/StaticPrefs_browser.h"
#include "mozilla/dom/BrowserChild.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/nsCSPContext.h"
#include "mozilla/extensions/StreamFilterParent.h"
#include "mozilla/ipc/IPCStreamUtils.h"
#include "mozilla/ipc/URIUtils.h"
#include "mozilla/net/DocumentChannelChild.h"
#include "mozilla/net/HttpChannelChild.h"
#include "mozilla/net/NeckoChild.h"
#include "mozilla/net/ParentProcessDocumentChannel.h"
#include "mozilla/net/UrlClassifierCommon.h"
#include "nsContentSecurityManager.h"
#include "nsDocShell.h"
#include "nsDocShellLoadState.h"
#include "nsHttpHandler.h"
#include "nsIInputStreamChannel.h"
#include "nsNetUtil.h"
#include "nsQueryObject.h"
#include "nsSerializationHelper.h"
#include "nsStreamListenerWrapper.h"
@ -52,7 +48,6 @@ NS_IMPL_RELEASE(DocumentChannel)
NS_INTERFACE_MAP_BEGIN(DocumentChannel)
NS_INTERFACE_MAP_ENTRY(nsIRequest)
NS_INTERFACE_MAP_ENTRY(nsIChannel)
NS_INTERFACE_MAP_ENTRY(nsIIdentChannel)
NS_INTERFACE_MAP_ENTRY(nsITraceableChannel)
NS_INTERFACE_MAP_ENTRY_CONCRETE(DocumentChannel)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIRequest)
@ -81,48 +76,6 @@ DocumentChannel::AsyncOpen(nsIStreamListener* aListener) {
return NS_ERROR_NOT_IMPLEMENTED;
}
void DocumentChannel::ShutdownListeners(nsresult aStatusCode) {
LOG(("DocumentChannel ShutdownListeners [this=%p, status=%" PRIx32 "]", this,
static_cast<uint32_t>(aStatusCode)));
mStatus = aStatusCode;
nsCOMPtr<nsIStreamListener> listener = mListener;
if (listener) {
listener->OnStartRequest(this);
}
mIsPending = false;
listener = mListener; // it might have changed!
if (listener) {
listener->OnStopRequest(this, aStatusCode);
}
mListener = nullptr;
mCallbacks = nullptr;
if (mLoadGroup) {
mLoadGroup->RemoveRequest(this, nullptr, aStatusCode);
mLoadGroup = nullptr;
}
DeleteIPDL();
}
void DocumentChannel::DisconnectChildListeners(
const nsresult& aStatus, const nsresult& aLoadGroupStatus) {
MOZ_ASSERT(NS_FAILED(aStatus));
mStatus = aLoadGroupStatus;
// Make sure we remove from the load group before
// setting mStatus, as existing tests expect the
// status to be successful when we disconnect.
if (mLoadGroup) {
mLoadGroup->RemoveRequest(this, nullptr, aStatus);
mLoadGroup = nullptr;
}
ShutdownListeners(aStatus);
}
nsDocShell* DocumentChannel::GetDocShell() {
nsCOMPtr<nsILoadContext> loadContext;
NS_QueryNotificationCallbacks(this, loadContext);
@ -139,53 +92,6 @@ nsDocShell* DocumentChannel::GetDocShell() {
return nsDocShell::Cast(docshell);
}
// Changes here should also be made in
// E10SUtils.documentChannelPermittedForURI().
static bool URIUsesDocChannel(nsIURI* aURI) {
if (SchemeIsJavascript(aURI) || NS_IsAboutBlank(aURI)) {
return false;
}
nsCString spec = aURI->GetSpecOrDefault();
return !spec.EqualsLiteral("about:printpreview") &&
!spec.EqualsLiteral("about:crashcontent");
}
/* static */
already_AddRefed<DocumentChannel> DocumentChannel::CreateDocumentChannel(
nsDocShellLoadState* aLoadState, class LoadInfo* aLoadInfo,
nsLoadFlags aLoadFlags, nsIInterfaceRequestor* aNotificationCallbacks,
uint32_t aCacheKey) {
RefPtr<DocumentChannel> channel;
if (XRE_IsContentProcess()) {
channel =
new DocumentChannelChild(aLoadState, aLoadInfo, aLoadFlags, aCacheKey);
} else {
channel = new ParentProcessDocumentChannel(aLoadState, aLoadInfo,
aLoadFlags, aCacheKey);
}
channel->SetNotificationCallbacks(aNotificationCallbacks);
return channel.forget();
}
bool DocumentChannel::CanUseDocumentChannel(nsDocShellLoadState* aLoadState) {
MOZ_ASSERT(aLoadState);
if (XRE_IsParentProcess() &&
!StaticPrefs::browser_tabs_documentchannel_ppdc()) {
return false;
}
// We want to use DocumentChannel if we're using a supported scheme. Sandboxed
// srcdoc loads break due to failing assertions after changing processes, and
// non-sandboxed srcdoc loads need to share the same principal object as their
// outer document (and must load in the same process), which breaks if we
// serialize to the parent process.
return StaticPrefs::browser_tabs_documentchannel() &&
!aLoadState->HasLoadFlags(nsDocShell::INTERNAL_LOAD_FLAGS_IS_SRCDOC) &&
URIUsesDocChannel(aLoadState->URI());
}
//-----------------------------------------------------------------------------
// DocumentChannel::nsITraceableChannel
//-----------------------------------------------------------------------------
@ -193,8 +99,6 @@ bool DocumentChannel::CanUseDocumentChannel(nsDocShellLoadState* aLoadState) {
NS_IMETHODIMP
DocumentChannel::SetNewListener(nsIStreamListener* aListener,
nsIStreamListener** _retval) {
LOG(("DocumentChannel SetNewListener [this=%p, aListener=%p]", this,
aListener));
NS_ENSURE_ARG_POINTER(aListener);
nsCOMPtr<nsIStreamListener> wrapper = new nsStreamListenerWrapper(mListener);

Просмотреть файл

@ -8,12 +8,12 @@
#ifndef mozilla_net_DocumentChannel_h
#define mozilla_net_DocumentChannel_h
#include "mozilla/dom/ClientInfo.h"
#include "mozilla/net/NeckoChannelParams.h"
#include "mozilla/net/PDocumentChannelChild.h"
#include "nsDOMNavigationTiming.h"
#include "nsIChannel.h"
#include "nsIChildChannel.h"
#include "nsITraceableChannel.h"
#include "mozilla/dom/ClientInfo.h"
#define DOCUMENT_CHANNEL_IID \
{ \
@ -45,6 +45,9 @@ class DocumentChannel : public nsIIdentChannel, public nsITraceableChannel {
NS_DECLARE_STATIC_IID_ACCESSOR(DOCUMENT_CHANNEL_IID)
DocumentChannel(nsDocShellLoadState* aLoadState, class LoadInfo* aLoadInfo,
nsLoadFlags aLoadFlags, uint32_t aCacheKey);
const nsTArray<DocumentChannelRedirect>& GetRedirectChain() const {
return mRedirects;
}
@ -62,28 +65,7 @@ class DocumentChannel : public nsIIdentChannel, public nsITraceableChannel {
mInitialClientInfo = aInfo;
}
/**
* Will create the appropriate document channel:
* Either a DocumentChannelChild if called from the content process or
* a ParentProcessDocumentChannel if called from the parent process.
* This operation is infallible.
*/
static already_AddRefed<DocumentChannel> CreateDocumentChannel(
nsDocShellLoadState* aLoadState, class LoadInfo* aLoadInfo,
nsLoadFlags aLoadFlags, nsIInterfaceRequestor* aNotificationCallbacks,
uint32_t aCacheKey);
static bool CanUseDocumentChannel(nsDocShellLoadState* aLoadState);
protected:
DocumentChannel(nsDocShellLoadState* aLoadState, class LoadInfo* aLoadInfo,
nsLoadFlags aLoadFlags, uint32_t aCacheKey);
void ShutdownListeners(nsresult aStatusCode);
void DisconnectChildListeners(const nsresult& aStatus,
const nsresult& aLoadGroupStatus);
virtual void DeleteIPDL() {}
nsDocShell* GetDocShell();
virtual ~DocumentChannel() = default;

Просмотреть файл

@ -128,9 +128,48 @@ IPCResult DocumentChannelChild::RecvFailedAsyncOpen(
return IPC_OK();
}
void DocumentChannelChild::ShutdownListeners(nsresult aStatusCode) {
LOG(("DocumentChannelChild ShutdownListeners [this=%p, status=%" PRIx32 "]",
this, static_cast<uint32_t>(aStatusCode)));
mStatus = aStatusCode;
nsCOMPtr<nsIStreamListener> l = mListener;
if (l) {
l->OnStartRequest(this);
}
mIsPending = false;
l = mListener; // it might have changed!
if (l) {
l->OnStopRequest(this, aStatusCode);
}
mListener = nullptr;
mCallbacks = nullptr;
if (mLoadGroup) {
mLoadGroup->RemoveRequest(this, nullptr, aStatusCode);
mLoadGroup = nullptr;
}
if (CanSend()) {
Send__delete__(this);
}
}
IPCResult DocumentChannelChild::RecvDisconnectChildListeners(
const nsresult& aStatus, const nsresult& aLoadGroupStatus) {
DisconnectChildListeners(aStatus, aLoadGroupStatus);
MOZ_ASSERT(NS_FAILED(aStatus));
mStatus = aLoadGroupStatus;
// Make sure we remove from the load group before
// setting mStatus, as existing tests expect the
// status to be successful when we disconnect.
if (mLoadGroup) {
mLoadGroup->RemoveRequest(this, nullptr, aStatus);
mLoadGroup = nullptr;
}
ShutdownListeners(aStatus);
return IPC_OK();
}

Просмотреть файл

@ -48,11 +48,7 @@ class DocumentChannelChild final : public DocumentChannel,
RedirectToRealChannelResolver&& aResolve);
private:
void DeleteIPDL() override {
if (CanSend()) {
Send__delete__(this);
}
}
void ShutdownListeners(nsresult aStatusCode);
~DocumentChannelChild();

Просмотреть файл

@ -13,8 +13,7 @@
namespace mozilla {
namespace dom {
class CanonicalBrowsingContext;
class BrowserParent;
} // namespace dom
}
namespace net {
/**
@ -62,7 +61,7 @@ class DocumentChannelParent final : public ADocumentChannelBridge,
}
}
ProcessId OtherPid() const override { return IProtocol::OtherPid(); }
virtual ProcessId OtherPid() const override { return IProtocol::OtherPid(); }
RefPtr<PDocumentChannelParent::RedirectToRealChannelPromise>
RedirectToRealChannel(
@ -70,7 +69,7 @@ class DocumentChannelParent final : public ADocumentChannelBridge,
aStreamFilterEndpoints,
uint32_t aRedirectFlags, uint32_t aLoadFlags) override;
virtual ~DocumentChannelParent();
~DocumentChannelParent();
RefPtr<DocumentLoadListener> mParent;
};

Просмотреть файл

@ -6,36 +6,44 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "DocumentLoadListener.h"
#include "mozilla/AntiTrackingUtils.h"
#include "mozilla/ContentBlockingAllowList.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/LoadInfo.h"
#include "mozilla/MozPromiseInlines.h" // For MozPromise::FromDomPromise
#include "mozilla/StaticPrefs_security.h"
#include "mozilla/dom/CanonicalBrowsingContext.h"
#include "mozilla/dom/ClientChannelHelper.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/ContentProcessManager.h"
#include "mozilla/dom/WindowGlobalParent.h"
#include "mozilla/dom/ipc/IdType.h"
#include "mozilla/dom/ServiceWorkerManager.h"
#include "mozilla/net/CookieJarSettings.h"
#include "mozilla/net/HttpChannelParent.h"
#include "mozilla/net/RedirectChannelRegistrar.h"
#include "mozilla/net/UrlClassifierCommon.h"
#include "nsContentSecurityUtils.h"
#include "nsDocShell.h"
#include "nsDocShellLoadState.h"
#include "nsExternalHelperAppService.h"
#include "nsContentSecurityUtils.h"
#include "nsHttpChannel.h"
#include "nsISecureBrowserUI.h"
#include "nsRedirectHistoryEntry.h"
#include "nsSerializationHelper.h"
#include "nsIPrompt.h"
#include "nsIWindowWatcher.h"
#include "nsIURIContentListener.h"
#include "nsWebNavigationInfo.h"
#include "nsURILoader.h"
#include "nsIStreamConverterService.h"
#include "nsExternalHelperAppService.h"
#include "nsCExternalHandlerService.h"
#include "nsMimeTypes.h"
#include "nsIViewSourceChannel.h"
#include "nsIOService.h"
#include "mozilla/dom/WindowGlobalParent.h"
#include "mozilla/StaticPrefs_security.h"
#include "nsICookieService.h"
#include "nsIBrowser.h"
#include "nsIE10SUtils.h"
#include "nsIStreamConverterService.h"
#include "nsIViewSourceChannel.h"
#include "nsImportModule.h"
#include "nsMimeTypes.h"
#include "nsRedirectHistoryEntry.h"
#include "nsURILoader.h"
#include "nsWebNavigationInfo.h"
#ifdef ANDROID
# include "mozilla/widget/nsWindow.h"
@ -240,24 +248,17 @@ NS_INTERFACE_MAP_END
DocumentLoadListener::DocumentLoadListener(
CanonicalBrowsingContext* aBrowsingContext, nsILoadContext* aLoadContext,
ADocumentChannelBridge* aBridge)
: mDocumentChannelBridge(aBridge), mLoadContext(aLoadContext) {
: mLoadContext(aLoadContext) {
LOG(("DocumentLoadListener ctor [this=%p]", this));
mParentChannelListener = new ParentChannelListener(
this, aBrowsingContext, aLoadContext->UsePrivateBrowsing());
mDocumentChannelBridge = aBridge;
}
DocumentLoadListener::~DocumentLoadListener() {
LOG(("DocumentLoadListener dtor [this=%p]", this));
}
net::LastVisitInfo DocumentLoadListener::LastVisitInfo() const {
nsCOMPtr<nsIURI> previousURI;
uint32_t previousFlags = 0;
nsDocShell::ExtractLastVisit(mChannel, getter_AddRefs(previousURI),
&previousFlags);
return net::LastVisitInfo{previousURI, previousFlags};
}
already_AddRefed<LoadInfo> DocumentLoadListener::CreateLoadInfo(
CanonicalBrowsingContext* aBrowsingContext, nsDocShellLoadState* aLoadState,
uint64_t aOuterWindowId) {
@ -431,8 +432,8 @@ bool DocumentLoadListener::Open(
// OnStart/StopRequest with itself. We don't need this, and instead
// we want the original request so that we get different ones for
// each part of a multipart channel.
nsCOMPtr<nsIViewSourceChannel> viewSourceChannel;
if (OtherPid() && (viewSourceChannel = do_QueryInterface(mChannel))) {
if (nsCOMPtr<nsIViewSourceChannel> viewSourceChannel =
do_QueryInterface(mChannel)) {
viewSourceChannel->SetReplaceRequest(false);
}
@ -561,11 +562,6 @@ void DocumentLoadListener::RedirectToRealChannelFinished(nsresult aRv) {
return;
}
if (!mRedirectChannelId) {
FinishReplacementChannelSetup(true);
return;
}
// Wait for background channel ready on target channel
nsCOMPtr<nsIRedirectChannelRegistrar> redirectReg =
RedirectChannelRegistrar::GetOrCreate();
@ -604,48 +600,42 @@ void DocumentLoadListener::FinishReplacementChannelSetup(bool aSucceeded) {
("DocumentLoadListener FinishReplacementChannelSetup [this=%p, "
"aSucceeded=%d]",
this, aSucceeded));
nsresult rv;
if (mDoingProcessSwitch) {
DisconnectChildListeners(NS_BINDING_ABORTED, NS_BINDING_ABORTED);
}
if (!mRedirectChannelId) {
if (!aSucceeded) {
mChannel->Resume();
return;
}
ApplyPendingFunctions(mChannel);
// ResumeSuspendedChannel will be called later as RedirectToRealChannel
// continues, so we can return early.
return;
}
nsCOMPtr<nsIRedirectChannelRegistrar> registrar =
RedirectChannelRegistrar::GetOrCreate();
MOZ_ASSERT(registrar);
nsCOMPtr<nsIParentChannel> redirectChannel;
nsresult rv = registrar->GetParentChannel(mRedirectChannelId,
getter_AddRefs(redirectChannel));
if (NS_FAILED(rv) || !redirectChannel) {
// Redirect might get canceled before we got AsyncOnChannelRedirect
nsCOMPtr<nsIChannel> newChannel;
rv = registrar->GetRegisteredChannel(mRedirectChannelId,
getter_AddRefs(newChannel));
MOZ_ASSERT(newChannel, "Already registered channel not found");
if (mRedirectChannelId) {
nsCOMPtr<nsIRedirectChannelRegistrar> registrar =
RedirectChannelRegistrar::GetOrCreate();
MOZ_ASSERT(registrar);
if (NS_SUCCEEDED(rv)) {
newChannel->Cancel(NS_BINDING_ABORTED);
}
if (!redirectChannel) {
aSucceeded = false;
rv = registrar->GetParentChannel(mRedirectChannelId,
getter_AddRefs(redirectChannel));
if (NS_FAILED(rv) || !redirectChannel) {
// Redirect might get canceled before we got AsyncOnChannelRedirect
nsCOMPtr<nsIChannel> newChannel;
rv = registrar->GetRegisteredChannel(mRedirectChannelId,
getter_AddRefs(newChannel));
MOZ_ASSERT(newChannel, "Already registered channel not found");
if (NS_SUCCEEDED(rv)) {
newChannel->Cancel(NS_BINDING_ABORTED);
}
}
// Release all previously registered channels, they are no longer needed to
// be kept in the registrar from this moment.
registrar->DeregisterChannels(mRedirectChannelId);
mRedirectChannelId = 0;
}
if (!redirectChannel) {
aSucceeded = false;
}
// Release all previously registered channels, they are no longer needed to
// be kept in the registrar from this moment.
registrar->DeregisterChannels(mRedirectChannelId);
mRedirectChannelId = 0;
if (!aSucceeded) {
if (redirectChannel) {
redirectChannel->Delete();
@ -658,85 +648,36 @@ void DocumentLoadListener::FinishReplacementChannelSetup(bool aSucceeded) {
!SameCOMIdentity(redirectChannel, static_cast<nsIParentChannel*>(this)));
Delete();
if (!mIsFinished) {
mParentChannelListener->SetListenerAfterRedirect(redirectChannel);
}
redirectChannel->SetParentListener(mParentChannelListener);
ApplyPendingFunctions(redirectChannel);
ResumeSuspendedChannel(redirectChannel);
}
void DocumentLoadListener::ApplyPendingFunctions(nsISupports* aChannel) const {
// We stored the values from all nsIParentChannel functions called since we
// couldn't handle them. Copy them across to the real channel since it
// should know what to do.
nsCOMPtr<nsIParentChannel> parentChannel = do_QueryInterface(aChannel);
if (parentChannel) {
for (auto& variant : mIParentChannelFunctions) {
variant.match(
[parentChannel](const nsIHttpChannel::FlashPluginState& aState) {
parentChannel->NotifyFlashPluginStateChanged(aState);
},
[parentChannel](const ClassifierMatchedInfoParams& aParams) {
parentChannel->SetClassifierMatchedInfo(
aParams.mList, aParams.mProvider, aParams.mFullHash);
},
[parentChannel](const ClassifierMatchedTrackingInfoParams& aParams) {
parentChannel->SetClassifierMatchedTrackingInfo(
aParams.mLists, aParams.mFullHashes);
},
[parentChannel](const ClassificationFlagsParams& aParams) {
parentChannel->NotifyClassificationFlags(
aParams.mClassificationFlags, aParams.mIsThirdParty);
});
}
} else {
for (auto& variant : mIParentChannelFunctions) {
variant.match(
[&](const nsIHttpChannel::FlashPluginState& aState) {
// For now, only HttpChannel use this attribute.
RefPtr<HttpBaseChannel> httpChannel = do_QueryObject(aChannel);
if (httpChannel) {
httpChannel->SetFlashPluginState(aState);
}
},
[&](const ClassifierMatchedInfoParams& aParams) {
nsCOMPtr<nsIClassifiedChannel> classifiedChannel =
do_QueryInterface(aChannel);
if (classifiedChannel) {
classifiedChannel->SetMatchedInfo(
aParams.mList, aParams.mProvider, aParams.mFullHash);
}
},
[&](const ClassifierMatchedTrackingInfoParams& aParams) {
nsCOMPtr<nsIClassifiedChannel> classifiedChannel =
do_QueryInterface(aChannel);
if (classifiedChannel) {
nsTArray<nsCString> lists, fullhashes;
for (const nsACString& token : aParams.mLists.Split(',')) {
lists.AppendElement(token);
}
for (const nsACString& token : aParams.mFullHashes.Split(',')) {
fullhashes.AppendElement(token);
}
classifiedChannel->SetMatchedTrackingInfo(lists, fullhashes);
}
},
[&](const ClassificationFlagsParams& aParams) {
UrlClassifierCommon::SetClassificationFlagsHelper(
static_cast<nsIChannel*>(aChannel),
aParams.mClassificationFlags, aParams.mIsThirdParty);
});
}
// couldn't handle them. Copy them across to the real channel since it should
// know what to do.
for (auto& variant : mIParentChannelFunctions) {
variant.match(
[redirectChannel](const nsIHttpChannel::FlashPluginState& aState) {
redirectChannel->NotifyFlashPluginStateChanged(aState);
},
[redirectChannel](const ClassifierMatchedInfoParams& aParams) {
redirectChannel->SetClassifierMatchedInfo(
aParams.mList, aParams.mProvider, aParams.mFullHash);
},
[redirectChannel](const ClassifierMatchedTrackingInfoParams& aParams) {
redirectChannel->SetClassifierMatchedTrackingInfo(
aParams.mLists, aParams.mFullHashes);
},
[redirectChannel](const ClassificationFlagsParams& aParams) {
redirectChannel->NotifyClassificationFlags(
aParams.mClassificationFlags, aParams.mIsThirdParty);
});
}
RefPtr<HttpChannelSecurityWarningReporter> reporter;
if (RefPtr<HttpChannelParent> httpParent = do_QueryObject(aChannel)) {
reporter = httpParent;
} else if (RefPtr<nsHttpChannel> httpChannel = do_QueryObject(aChannel)) {
reporter = httpChannel->GetWarningReporter();
}
if (reporter) {
RefPtr<HttpChannelParent> httpParent = do_QueryObject(redirectChannel);
if (httpParent) {
RefPtr<HttpChannelSecurityWarningReporter> reporter = httpParent;
for (auto& variant : mSecurityWarningFunctions) {
variant.match(
[reporter](const ReportSecurityMessageParams& aParams) {
@ -754,9 +695,11 @@ void DocumentLoadListener::ApplyPendingFunctions(nsISupports* aChannel) const {
});
}
}
ResumeSuspendedChannel(redirectChannel);
}
bool DocumentLoadListener::ResumeSuspendedChannel(
void DocumentLoadListener::ResumeSuspendedChannel(
nsIStreamListener* aListener) {
LOG(("DocumentLoadListener ResumeSuspendedChannel [this=%p]", this));
RefPtr<nsHttpChannel> httpChannel = do_QueryObject(mChannel);
@ -764,18 +707,11 @@ bool DocumentLoadListener::ResumeSuspendedChannel(
httpChannel->SetApplyConversion(mOldApplyConversion);
}
if (!mIsFinished) {
mParentChannelListener->SetListenerAfterRedirect(aListener);
}
// If we failed to suspend the channel, then we might have received
// some messages while the redirected was being handled.
// Manually send them on now.
nsTArray<StreamListenerFunction> streamListenerFunctions =
std::move(mStreamListenerFunctions);
if (!aListener) {
streamListenerFunctions.Clear();
}
nsresult rv = NS_OK;
for (auto& variant : streamListenerFunctions) {
variant.match(
@ -831,12 +767,11 @@ bool DocumentLoadListener::ResumeSuspendedChannel(
"Should not have added new stream listener function!");
mChannel->Resume();
return !mIsFinished;
}
void DocumentLoadListener::SerializeRedirectData(
RedirectToRealChannelArgs& aArgs, bool aIsCrossProcess,
uint32_t aRedirectFlags, uint32_t aLoadFlags) const {
uint32_t aRedirectFlags, uint32_t aLoadFlags) {
// Use the original URI of the current channel, as this is what
// we'll use to construct the channel in the content process.
aArgs.uri() = mChannelCreationURI;
@ -854,7 +789,7 @@ void DocumentLoadListener::SerializeRedirectData(
nsCOMPtr<nsIPrincipal> principalToInherit;
channelLoadInfo->GetPrincipalToInherit(getter_AddRefs(principalToInherit));
const RefPtr<nsHttpChannel> baseChannel = do_QueryObject(mChannel.get());
RefPtr<nsHttpChannel> baseChannel = do_QueryObject(mChannel);
nsCOMPtr<nsILoadInfo> redirectLoadInfo;
if (baseChannel) {
redirectLoadInfo = baseChannel->CloneLoadInfoForRedirect(
@ -886,6 +821,12 @@ void DocumentLoadListener::SerializeRedirectData(
redirectLoadInfo->SetReservedClientInfo(*reservedClientInfo);
}
// Register the new channel and obtain id for it
nsCOMPtr<nsIRedirectChannelRegistrar> registrar =
RedirectChannelRegistrar::GetOrCreate();
MOZ_ASSERT(registrar);
nsresult rv = registrar->RegisterChannel(mChannel, &mRedirectChannelId);
NS_ENSURE_SUCCESS_VOID(rv);
aArgs.registrarId() = mRedirectChannelId;
MOZ_ALWAYS_SUCCEEDS(
@ -917,7 +858,7 @@ void DocumentLoadListener::SerializeRedirectData(
}
uint32_t contentDispositionTemp;
nsresult rv = mChannel->GetContentDisposition(&contentDispositionTemp);
rv = mChannel->GetContentDisposition(&contentDispositionTemp);
if (NS_SUCCEEDED(rv)) {
aArgs.contentDisposition() = Some(contentDispositionTemp);
}
@ -932,8 +873,12 @@ void DocumentLoadListener::SerializeRedirectData(
aArgs.redirectFlags() = aRedirectFlags;
aArgs.redirects() = mRedirects;
aArgs.redirectIdentifier() = mCrossProcessRedirectIdentifier;
aArgs.properties() = do_QueryObject(mChannel.get());
aArgs.lastVisitInfo() = LastVisitInfo();
aArgs.properties() = do_QueryObject(mChannel);
nsCOMPtr<nsIURI> previousURI;
uint32_t previousFlags = 0;
nsDocShell::ExtractLastVisit(mChannel, getter_AddRefs(previousURI),
&previousFlags);
aArgs.lastVisitInfo() = LastVisitInfo{previousURI, previousFlags};
aArgs.srcdocData() = mSrcdocData;
aArgs.baseUri() = mBaseURI;
aArgs.loadStateLoadFlags() = mLoadStateLoadFlags;
@ -1139,22 +1084,6 @@ DocumentLoadListener::RedirectToRealChannel(
nsTArray<ParentEndpoint>&& aStreamFilterEndpoints) {
LOG(("DocumentLoadListener RedirectToRealChannel [this=%p]", this));
// Register the new channel and obtain id for it
nsCOMPtr<nsIRedirectChannelRegistrar> registrar =
RedirectChannelRegistrar::GetOrCreate();
MOZ_ASSERT(registrar);
MOZ_ALWAYS_SUCCEEDS(
registrar->RegisterChannel(mChannel, &mRedirectChannelId));
if (aDestinationProcess || OtherPid()) {
// Register the new channel and obtain id for it
nsCOMPtr<nsIRedirectChannelRegistrar> registrar =
RedirectChannelRegistrar::GetOrCreate();
MOZ_ASSERT(registrar);
MOZ_ALWAYS_SUCCEEDS(
registrar->RegisterChannel(mChannel, &mRedirectChannelId));
}
if (aDestinationProcess) {
dom::ContentParent* cp =
dom::ContentProcessManager::GetSingleton()->GetContentProcessById(
@ -1492,13 +1421,16 @@ NS_IMETHODIMP
DocumentLoadListener::AsyncOnChannelRedirect(
nsIChannel* aOldChannel, nsIChannel* aNewChannel, uint32_t aFlags,
nsIAsyncVerifyRedirectCallback* aCallback) {
LOG(("DocumentLoadListener AsyncOnChannelRedirect [this=%p, aFlags=%" PRIx32
"]",
this, aFlags));
// We generally don't want to notify the content process about redirects,
// so just update our channel and tell the callback that we're good to go.
mChannel = aNewChannel;
// We need the original URI of the current channel to use to open the real
// channel in the content process. Unfortunately we overwrite the original
// uri of the new channel with the original pre-redirect URI, so grab
// a copy of it now.
aNewChannel->GetOriginalURI(getter_AddRefs(mChannelCreationURI));
// Since we're redirecting away from aOldChannel, we should check if it
// had a COOP mismatch, since we want the final result for this to
// include the state of all channels we redirected through.
@ -1511,10 +1443,6 @@ DocumentLoadListener::AsyncOnChannelRedirect(
// We don't need to confirm internal redirects or record any
// history for them, so just immediately verify and return.
if (aFlags & nsIChannelEventSink::REDIRECT_INTERNAL) {
LOG(
("DocumentLoadListener AsyncOnChannelRedirect [this=%p] "
"flags=REDIRECT_INTERNAL",
this));
aCallback->OnRedirectVerifyCallback(NS_OK);
return NS_OK;
} else {
@ -1527,21 +1455,11 @@ DocumentLoadListener::AsyncOnChannelRedirect(
mRedirects.AppendElement(DocumentChannelRedirect{
oldURI, aFlags, responseStatus, net::ChannelIsPost(aOldChannel)});
}
LOG(
("DocumentLoadListener AsyncOnChannelRedirect [this=%p] "
"mRedirects=%" PRIx32,
this, uint32_t(mRedirects.Length())));
if (!mDocumentChannelBridge) {
return NS_BINDING_ABORTED;
}
// We need the original URI of the current channel to use to open the real
// channel in the content process. Unfortunately we overwrite the original
// uri of the new channel with the original pre-redirect URI, so grab
// a copy of it now.
aNewChannel->GetOriginalURI(getter_AddRefs(mChannelCreationURI));
// Clear out our nsIParentChannel functions, since a normal parent
// channel would actually redirect and not have those values on the new one.
// We expect the URI classifier to run on the redirected channel with
@ -1612,14 +1530,14 @@ DocumentLoadListener::AsyncOnChannelRedirect(
// This method returns the cached result of running the Cross-Origin-Opener
// policy compare algorithm by calling ComputeCrossOriginOpenerPolicyMismatch
bool DocumentLoadListener::HasCrossOriginOpenerPolicyMismatch() const {
bool DocumentLoadListener::HasCrossOriginOpenerPolicyMismatch() {
// If we found a COOP mismatch on an earlier channel and then
// redirected away from that, we should use that result.
if (mHasCrossOriginOpenerPolicyMismatch) {
return true;
}
RefPtr<nsHttpChannel> httpChannel = do_QueryObject(mChannel.get());
RefPtr<nsHttpChannel> httpChannel = do_QueryObject(mChannel);
if (!httpChannel) {
// Not an nsHttpChannel assume it's okay to switch.
return false;

Просмотреть файл

@ -17,6 +17,7 @@
#include "mozilla/dom/CanonicalBrowsingContext.h"
#include "nsDOMNavigationTiming.h"
#include "nsIInterfaceRequestor.h"
#include "nsIObserver.h"
#include "nsIParentChannel.h"
#include "nsIParentRedirectingChannel.h"
#include "nsIRedirectResultListener.h"
@ -113,15 +114,12 @@ class DocumentLoadListener : public nsIInterfaceRequestor,
// This helper resumes the underlying channel again, and manually
// forwards any nsIStreamListener messages that arrived while we
// were suspended (which might have failed).
// Returns true if the channel was finished before we could resume it.
bool ResumeSuspendedChannel(nsIStreamListener* aListener);
void ResumeSuspendedChannel(nsIStreamListener* aListener);
NS_DECLARE_STATIC_IID_ACCESSOR(DOCUMENT_LOAD_LISTENER_IID)
void Cancel(const nsresult& status);
nsIChannel* GetChannel() const { return mChannel; }
nsresult ReportSecurityMessage(const nsAString& aMessageTag,
const nsAString& aMessageCategory) override {
ReportSecurityMessageParams params;
@ -177,13 +175,7 @@ class DocumentLoadListener : public nsIInterfaceRequestor,
// in the content process into the RedirectToRealChannelArgs struct.
void SerializeRedirectData(RedirectToRealChannelArgs& aArgs,
bool aIsCrossProcess, uint32_t aRedirectFlags,
uint32_t aLoadFlags) const;
const nsTArray<DocumentChannelRedirect>& Redirects() const {
return mRedirects;
}
net::LastVisitInfo LastVisitInfo() const;
uint32_t aLoadFlags);
protected:
virtual ~DocumentLoadListener();
@ -223,8 +215,7 @@ class DocumentLoadListener : public nsIInterfaceRequestor,
dom::CanonicalBrowsingContext* aBrowsingContext,
nsDocShellLoadState* aLoadState, uint64_t aOuterWindowId);
bool HasCrossOriginOpenerPolicyMismatch() const;
void ApplyPendingFunctions(nsISupports* aChannel) const;
bool HasCrossOriginOpenerPolicyMismatch();
// This defines a variant that describes all the attribute setters (and their
// parameters) from nsIParentChannel

Просмотреть файл

@ -1,204 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et tw=80 : */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ParentProcessDocumentChannel.h"
#include "nsIObserverService.h"
extern mozilla::LazyLogModule gDocumentChannelLog;
#define LOG(fmt) MOZ_LOG(gDocumentChannelLog, mozilla::LogLevel::Verbose, fmt)
namespace mozilla {
namespace net {
NS_IMPL_ISUPPORTS_INHERITED(ParentProcessDocumentChannel, DocumentChannel,
nsIAsyncVerifyRedirectCallback, nsIObserver)
ParentProcessDocumentChannel::ParentProcessDocumentChannel(
nsDocShellLoadState* aLoadState, class LoadInfo* aLoadInfo,
nsLoadFlags aLoadFlags, uint32_t aCacheKey)
: DocumentChannel(aLoadState, aLoadInfo, aLoadFlags, aCacheKey) {
LOG(("ParentProcessDocumentChannel ctor [this=%p]", this));
}
ParentProcessDocumentChannel::~ParentProcessDocumentChannel() {
LOG(("ParentProcessDocumentChannel dtor [this=%p]", this));
}
RefPtr<PDocumentChannelParent::RedirectToRealChannelPromise>
ParentProcessDocumentChannel::RedirectToRealChannel(
nsTArray<ipc::Endpoint<extensions::PStreamFilterParent>>&&
aStreamFilterEndpoints,
uint32_t aRedirectFlags, uint32_t aLoadFlags) {
LOG(("ParentProcessDocumentChannel RedirectToRealChannel [this=%p]", this));
nsCOMPtr<nsIChannel> channel = mDocumentLoadListener->GetChannel();
channel->SetLoadFlags(aLoadFlags);
channel->SetNotificationCallbacks(mCallbacks);
if (mLoadGroup) {
channel->SetLoadGroup(mLoadGroup);
}
mLastVisitInfo = mDocumentLoadListener->LastVisitInfo();
mRedirects = mDocumentLoadListener->Redirects();
mStreamFilterEndpoints = std::move(aStreamFilterEndpoints);
RefPtr<PDocumentChannelParent::RedirectToRealChannelPromise> p =
mPromise.Ensure(__func__);
nsresult rv =
gHttpHandler->AsyncOnChannelRedirect(this, channel, aRedirectFlags);
if (NS_FAILED(rv)) {
OnRedirectVerifyCallback(rv);
}
return p;
}
NS_IMETHODIMP
ParentProcessDocumentChannel::OnRedirectVerifyCallback(nsresult aResult) {
LOG(
("ParentProcessDocumentChannel OnRedirectVerifyCallback [this=%p "
"aResult=%d]",
this, int(aResult)));
MOZ_ASSERT(mDocumentLoadListener);
if (NS_FAILED(aResult)) {
Cancel(aResult);
} else if (mCanceled && NS_SUCCEEDED(aResult)) {
aResult = NS_BINDING_ABORTED;
} else {
const nsCOMPtr<nsIChannel> channel = mDocumentLoadListener->GetChannel();
mLoadGroup->AddRequest(channel, nullptr);
// Adding the channel to the loadgroup could have triggered a status
// change with an observer being called destroying the docShell, resulting
// in the PPDC to be canceled.
if (!mCanceled) {
mLoadGroup->RemoveRequest(this, nullptr, NS_BINDING_REDIRECTED);
for (auto& endpoint : mStreamFilterEndpoints) {
extensions::StreamFilterParent::Attach(channel, std::move(endpoint));
}
if (!mDocumentLoadListener->ResumeSuspendedChannel(mListener)) {
// We added ourselves to the load group, but attempting
// to resume has notified us that the channel is already
// finished. Better remove ourselves from the loadgroup
// again.
nsresult status = NS_OK;
channel->GetStatus(&status);
mLoadGroup->RemoveRequest(channel, nullptr, status);
}
}
}
mLoadGroup = nullptr;
mListener = nullptr;
mCallbacks = nullptr;
DisconnectDocumentLoadListener();
mPromise.ResolveIfExists(aResult, __func__);
return NS_OK;
}
NS_IMETHODIMP ParentProcessDocumentChannel::AsyncOpen(
nsIStreamListener* aListener) {
LOG(("ParentProcessDocumentChannel AsyncOpen [this=%p]", this));
nsCOMPtr<nsILoadContext> loadContext;
NS_QueryNotificationCallbacks(this, loadContext);
mDocumentLoadListener = new DocumentLoadListener(
GetDocShell()->GetBrowsingContext()->Canonical(), loadContext, this);
LOG(("Created PPDocumentChannel with listener=%p",
mDocumentLoadListener.get()));
// Add observers.
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
if (observerService) {
MOZ_ALWAYS_SUCCEEDS(observerService->AddObserver(
this, NS_HTTP_ON_MODIFY_REQUEST_TOPIC, false));
}
gHttpHandler->OnOpeningDocumentRequest(this);
nsresult rv = NS_OK;
Maybe<dom::ClientInfo> initialClientInfo = mInitialClientInfo;
if (!mDocumentLoadListener->Open(
mLoadState, mLoadFlags, mCacheKey, mChannelId, mAsyncOpenTime,
mTiming, std::move(initialClientInfo), mLoadInfo->GetOuterWindowID(),
GetDocShell()
->GetBrowsingContext()
->HasValidTransientUserGestureActivation(),
&rv)) {
MOZ_ASSERT(NS_FAILED(rv));
DisconnectDocumentLoadListener();
return rv;
}
mListener = aListener;
if (mLoadGroup) {
mLoadGroup->AddRequest(this, nullptr);
}
return NS_OK;
}
NS_IMETHODIMP ParentProcessDocumentChannel::Cancel(nsresult aStatus) {
LOG(("ParentProcessDocumentChannel Cancel [this=%p]", this));
if (mCanceled) {
return NS_OK;
}
mCanceled = true;
mDocumentLoadListener->Cancel(aStatus);
ShutdownListeners(aStatus);
return NS_OK;
}
void ParentProcessDocumentChannel::DisconnectDocumentLoadListener() {
if (nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService()) {
observerService->RemoveObserver(this, NS_HTTP_ON_MODIFY_REQUEST_TOPIC);
}
mDocumentLoadListener->DocumentChannelBridgeDisconnected();
mDocumentLoadListener = nullptr;
}
////////////////////////////////////////////////////////////////////////////////
// nsIObserver
NS_IMETHODIMP
ParentProcessDocumentChannel::Observe(nsISupports* aSubject, const char* aTopic,
const char16_t* aData) {
MOZ_ASSERT(NS_IsMainThread());
if (mRequestObserversCalled) {
// We have already emitted the event, we don't want to emit it again.
// We only care about forwarding the first NS_HTTP_ON_MODIFY_REQUEST_TOPIC
// encountered.
return NS_OK;
}
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aSubject);
if (!channel || mDocumentLoadListener->GetChannel() != channel) {
// Not a channel we are interested with.
return NS_OK;
}
LOG(("DocumentChannelParent Observe [this=%p aChannel=%p]", this,
channel.get()));
if (!nsCRT::strcmp(aTopic, NS_HTTP_ON_MODIFY_REQUEST_TOPIC)) {
mRequestObserversCalled = true;
gHttpHandler->OnModifyDocumentRequest(this);
}
return NS_OK;
}
} // namespace net
} // namespace mozilla
#undef LOG

Просмотреть файл

@ -1,67 +0,0 @@
/* vim: set sw=2 ts=8 et tw=80 : */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_net_ParentProcessDocumentChannel_h
#define mozilla_net_ParentProcessDocumentChannel_h
#include "ProtocolUtils.h"
#include "mozilla/net/ADocumentChannelBridge.h"
#include "mozilla/net/DocumentChannel.h"
#include "mozilla/net/DocumentLoadListener.h"
#include "nsIObserver.h"
namespace mozilla {
namespace net {
class ParentProcessDocumentChannel : public DocumentChannel,
public nsIAsyncVerifyRedirectCallback,
public nsIObserver,
public ADocumentChannelBridge {
public:
ParentProcessDocumentChannel(nsDocShellLoadState* aLoadState,
class LoadInfo* aLoadInfo,
nsLoadFlags aLoadFlags, uint32_t aCacheKey);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK
NS_DECL_NSIOBSERVER
NS_IMETHOD AsyncOpen(nsIStreamListener* aListener) override;
NS_IMETHOD Cancel(nsresult aStatusCode) override;
RefPtr<PDocumentChannelParent::RedirectToRealChannelPromise>
RedirectToRealChannel(
nsTArray<ipc::Endpoint<extensions::PStreamFilterParent>>&&
aStreamFilterEndpoints,
uint32_t aRedirectFlags, uint32_t aLoadFlags) override;
void DisconnectChildListeners(nsresult aStatus,
nsresult aLoadGroupStatus) override {
DocumentChannel::DisconnectChildListeners(aStatus, aLoadGroupStatus);
DisconnectDocumentLoadListener();
}
void Delete() override {}
void DeleteIPDL() override {
mPromise.ResolveIfExists(NS_BINDING_ABORTED, __func__);
}
base::ProcessId OtherPid() const override { return 0; }
private:
virtual ~ParentProcessDocumentChannel();
void DisconnectDocumentLoadListener();
RefPtr<DocumentLoadListener> mDocumentLoadListener;
nsTArray<ipc::Endpoint<extensions::PStreamFilterParent>>
mStreamFilterEndpoints;
MozPromiseHolder<PDocumentChannelParent::RedirectToRealChannelPromise>
mPromise;
bool mRequestObserversCalled = false;
};
} // namespace net
} // namespace mozilla
#endif // mozilla_net_ParentProcessDocumentChannel_h

Просмотреть файл

@ -5,13 +5,12 @@
#include "SocketProcessImpl.h"
#include "ProcessUtils.h"
#include "base/command_line.h"
#include "base/shared_memory.h"
#include "base/string_util.h"
#include "mozilla/ipc/IOThreadChild.h"
#include "mozilla/BackgroundHangMonitor.h"
#include "mozilla/Preferences.h"
#include "mozilla/ipc/IOThreadChild.h"
#if defined(OS_WIN) && defined(MOZ_SANDBOX)
# include "mozilla/sandboxTarget.h"
@ -90,7 +89,7 @@ bool SocketProcessImpl::Init(int aArgc, char* aArgv[]) {
}
}
ipc::SharedPreferenceDeserializer deserializer;
SharedPreferenceDeserializer deserializer;
if (!deserializer.DeserializeFromSharedMemory(prefsHandle, prefMapHandle,
prefsLen, prefMapSize)) {
return false;

Просмотреть файл

@ -18,7 +18,6 @@ EXPORTS.mozilla.net += [
'NeckoMessageUtils.h',
'NeckoParent.h',
'NeckoTargetHolder.h',
'ParentProcessDocumentChannel.h',
'SocketProcessBridgeChild.h',
'SocketProcessBridgeParent.h',
'SocketProcessChild.h',
@ -39,7 +38,6 @@ UNIFIED_SOURCES += [
'NeckoCommon.cpp',
'NeckoParent.cpp',
'NeckoTargetHolder.cpp',
'ParentProcessDocumentChannel.cpp',
'SocketProcessBridgeChild.cpp',
'SocketProcessBridgeParent.cpp',
'SocketProcessChild.cpp',

Просмотреть файл

@ -70,7 +70,6 @@ NS_INTERFACE_MAP_BEGIN(ParentChannelListener)
NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
NS_INTERFACE_MAP_ENTRY(nsIMultiPartChannelListener)
NS_INTERFACE_MAP_ENTRY(nsINetworkInterceptController)
NS_INTERFACE_MAP_ENTRY(nsIThreadRetargetableStreamListener)
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIAuthPromptProvider, mBrowsingContext)
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIRemoteWindowContext, mBrowsingContext)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIInterfaceRequestor)
@ -447,22 +446,5 @@ ParentChannelListener::GetUsePrivateBrowsing(bool* aUsePrivateBrowsing) {
return NS_OK;
}
//-----------------------------------------------------------------------------
// ParentChannelListener::nsIThreadRetargetableStreamListener
//
NS_IMETHODIMP
ParentChannelListener::CheckListenerChain() {
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIThreadRetargetableStreamListener> listener =
do_QueryInterface(mNextListener);
if (!listener) {
return NS_ERROR_NO_INTERFACE;
}
return listener->CheckListenerChain();
}
} // namespace net
} // namespace mozilla

Просмотреть файл

@ -8,14 +8,14 @@
#ifndef mozilla_net_ParentChannelListener_h
#define mozilla_net_ParentChannelListener_h
#include "mozilla/dom/CanonicalBrowsingContext.h"
#include "nsIAuthPromptProvider.h"
#include "nsIInterfaceRequestor.h"
#include "nsIMultiPartChannel.h"
#include "nsINetworkInterceptController.h"
#include "nsIRemoteWindowContext.h"
#include "nsIStreamListener.h"
#include "nsIThreadRetargetableStreamListener.h"
#include "nsIMultiPartChannel.h"
#include "nsIRemoteWindowContext.h"
#include "mozilla/dom/CanonicalBrowsingContext.h"
#include "mozilla/dom/CanonicalBrowsingContext.h"
namespace mozilla {
namespace net {
@ -35,7 +35,6 @@ class ParentChannelListener final : public nsIInterfaceRequestor,
public nsIStreamListener,
public nsIMultiPartChannelListener,
public nsINetworkInterceptController,
public nsIThreadRetargetableStreamListener,
private nsIAuthPromptProvider,
private nsIRemoteWindowContext {
public:
@ -47,7 +46,6 @@ class ParentChannelListener final : public nsIInterfaceRequestor,
NS_DECL_NSINETWORKINTERCEPTCONTROLLER
NS_DECL_NSIAUTHPROMPTPROVIDER
NS_DECL_NSIREMOTEWINDOWCONTEXT
NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
NS_DECLARE_STATIC_IID_ACCESSOR(PARENT_CHANNEL_LISTENER)

Просмотреть файл

@ -386,10 +386,6 @@ class nsHttpHandler final : public nsIHttpProtocolHandler,
NotifyObservers(chan, NS_HTTP_ON_MODIFY_REQUEST_TOPIC);
}
void OnModifyDocumentRequest(nsIIdentChannel* chan) {
NotifyObservers(chan, NS_DOCUMENT_ON_MODIFY_REQUEST_TOPIC);
}
// Called by the channel before writing a request
void OnStopRequest(nsIHttpChannel* chan) {
NotifyObservers(chan, NS_HTTP_ON_STOP_REQUEST_TOPIC);

Просмотреть файл

@ -121,7 +121,7 @@ interface nsIHttpProtocolHandler : nsIProxiedProtocolHandler
#define NS_HTTP_ON_OPENING_REQUEST_TOPIC "http-on-opening-request"
/**
* This observer topic is notified when a document channel is opened.
* This observer topic is notified when an document channel is opened.
* It is similar to http-on-opening-request.
*/
#define NS_DOCUMENT_ON_OPENING_REQUEST_TOPIC "document-on-opening-request"
@ -134,13 +134,6 @@ interface nsIHttpProtocolHandler : nsIProxiedProtocolHandler
*/
#define NS_HTTP_ON_MODIFY_REQUEST_TOPIC "http-on-modify-request"
/**
* Before an HTTP request is sent to the server via a document channel this
* observer topic is notified.
* It is similar to http-on-modify-request.
*/
#define NS_DOCUMENT_ON_MODIFY_REQUEST_TOPIC "document-on-modify-request"
/**
* Before an HTTP connection to the server is created, this observer topic is
* notified. This observer happens after HSTS upgrades, etc. are set, providing

Просмотреть файл

@ -340,6 +340,31 @@ nsresult UrlClassifierCommon::CreatePairwiseWhiteListURI(nsIChannel* aChannel,
namespace {
void SetClassificationFlagsHelper(nsIChannel* aChannel,
uint32_t aClassificationFlags,
bool aIsThirdParty) {
MOZ_ASSERT(aChannel);
nsCOMPtr<nsIParentChannel> parentChannel;
NS_QueryNotificationCallbacks(aChannel, parentChannel);
if (parentChannel) {
// This channel is a parent-process proxy for a child process
// request. We should notify the child process as well.
parentChannel->NotifyClassificationFlags(aClassificationFlags,
aIsThirdParty);
}
RefPtr<HttpBaseChannel> httpChannel = do_QueryObject(aChannel);
if (httpChannel) {
httpChannel->AddClassificationFlags(aClassificationFlags, aIsThirdParty);
}
RefPtr<ClassifierDummyChannel> dummyChannel = do_QueryObject(aChannel);
if (dummyChannel) {
dummyChannel->AddClassificationFlags(aClassificationFlags, aIsThirdParty);
}
}
void LowerPriorityHelper(nsIChannel* aChannel) {
MOZ_ASSERT(aChannel);
@ -388,31 +413,6 @@ void LowerPriorityHelper(nsIChannel* aChannel) {
} // namespace
// static
void UrlClassifierCommon::SetClassificationFlagsHelper(
nsIChannel* aChannel, uint32_t aClassificationFlags, bool aIsThirdParty) {
MOZ_ASSERT(aChannel);
nsCOMPtr<nsIParentChannel> parentChannel;
NS_QueryNotificationCallbacks(aChannel, parentChannel);
if (parentChannel) {
// This channel is a parent-process proxy for a child process
// request. We should notify the child process as well.
parentChannel->NotifyClassificationFlags(aClassificationFlags,
aIsThirdParty);
}
RefPtr<HttpBaseChannel> httpChannel = do_QueryObject(aChannel);
if (httpChannel) {
httpChannel->AddClassificationFlags(aClassificationFlags, aIsThirdParty);
}
RefPtr<ClassifierDummyChannel> dummyChannel = do_QueryObject(aChannel);
if (dummyChannel) {
dummyChannel->AddClassificationFlags(aClassificationFlags, aIsThirdParty);
}
}
// static
void UrlClassifierCommon::AnnotateChannel(nsIChannel* aChannel,
uint32_t aClassificationFlags,

Просмотреть файл

@ -79,10 +79,6 @@ class UrlClassifierCommon final {
static bool IsPassiveContent(nsIChannel* aChannel);
static void SetClassificationFlagsHelper(nsIChannel* aChannel,
uint32_t aClassificationFlags,
bool aIsThirdParty);
private:
static uint32_t TableToClassificationFlag(
const nsACString& aTable, const std::vector<ClassificationData>& aData);

Просмотреть файл

@ -22,8 +22,6 @@ add_task(async function() {
browser.runtime.onMessage.addListener((msg, sender) => {
browser.test.sendMessage("received-page", { msg, sender });
});
// Let them know we're done loading the page.
browser.test.sendMessage("page-ready");
},
"page.html": `<!DOCTYPE html><meta charset="utf-8"><script src="page.js"></script>`,
},
@ -39,7 +37,6 @@ add_task(async function() {
});
await Promise.all([extension1.startup(), extension2.startup()]);
await extension1.awaitMessage("page-ready");
// Check that a message was sent within extension1.
async function checkLocalMessage(msg) {