Bug 1607984 - P13. Proxy the first http-on-opening-request event to the DocumentChannel. r=mayhemer,necko-reviewers

Some tests rely on this event to start action. The DocumentChannel had no equivalent. We make the ParentProcessDocumentChannel listen to this event and if it matches the nsIChannel currently in use in the DocumentLoadListener than we emit a similar document-on-modify-request event on the DocumentChannel.

Differential Revision: https://phabricator.services.mozilla.com/D70010
This commit is contained in:
Jean-Yves Avenard 2020-04-22 15:16:10 +00:00
Родитель fce4dd9e1f
Коммит a88b9bc558
5 изменённых файлов: 69 добавлений и 8 удалений

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

@ -17,7 +17,6 @@
#include "mozilla/dom/CanonicalBrowsingContext.h"
#include "nsDOMNavigationTiming.h"
#include "nsIInterfaceRequestor.h"
#include "nsIObserver.h"
#include "nsIParentChannel.h"
#include "nsIParentRedirectingChannel.h"
#include "nsIRedirectResultListener.h"

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

@ -7,6 +7,8 @@
#include "ParentProcessDocumentChannel.h"
#include "nsIObserverService.h"
extern mozilla::LazyLogModule gDocumentChannelLog;
#define LOG(fmt) MOZ_LOG(gDocumentChannelLog, mozilla::LogLevel::Verbose, fmt)
@ -14,7 +16,7 @@ namespace mozilla {
namespace net {
NS_IMPL_ISUPPORTS_INHERITED(ParentProcessDocumentChannel, DocumentChannel,
nsIAsyncVerifyRedirectCallback)
nsIAsyncVerifyRedirectCallback, nsIObserver)
ParentProcessDocumentChannel::ParentProcessDocumentChannel(
nsDocShellLoadState* aLoadState, class LoadInfo* aLoadInfo,
@ -95,8 +97,7 @@ ParentProcessDocumentChannel::OnRedirectVerifyCallback(nsresult aResult) {
mLoadGroup = nullptr;
mListener = nullptr;
mCallbacks = nullptr;
mDocumentLoadListener->DocumentChannelBridgeDisconnected();
mDocumentLoadListener = nullptr;
DisconnectDocumentLoadListener();
mPromise.ResolveIfExists(aResult, __func__);
@ -114,6 +115,14 @@ NS_IMETHODIMP ParentProcessDocumentChannel::AsyncOpen(
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;
@ -126,8 +135,7 @@ NS_IMETHODIMP ParentProcessDocumentChannel::AsyncOpen(
->HasValidTransientUserGestureActivation(),
&rv)) {
MOZ_ASSERT(NS_FAILED(rv));
mDocumentLoadListener->DocumentChannelBridgeDisconnected();
mDocumentLoadListener = nullptr;
DisconnectDocumentLoadListener();
return rv;
}
@ -152,6 +160,44 @@ NS_IMETHODIMP ParentProcessDocumentChannel::Cancel(nsresult 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

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

@ -11,12 +11,14 @@
#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,
@ -25,6 +27,7 @@ class ParentProcessDocumentChannel : public DocumentChannel,
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK
NS_DECL_NSIOBSERVER
NS_IMETHOD AsyncOpen(nsIStreamListener* aListener) override;
NS_IMETHOD Cancel(nsresult aStatusCode) override;
@ -38,7 +41,7 @@ class ParentProcessDocumentChannel : public DocumentChannel,
void DisconnectChildListeners(nsresult aStatus,
nsresult aLoadGroupStatus) override {
DocumentChannel::DisconnectChildListeners(aStatus, aLoadGroupStatus);
mDocumentLoadListener = nullptr;
DisconnectDocumentLoadListener();
}
void Delete() override {}
void DeleteIPDL() override {
@ -48,12 +51,14 @@ class ParentProcessDocumentChannel : public DocumentChannel,
private:
virtual ~ParentProcessDocumentChannel();
void DisconnectDocumentLoadListener();
RefPtr<DocumentLoadListener> mDocumentLoadListener;
nsTArray<ipc::Endpoint<extensions::PStreamFilterParent>>
mStreamFilterEndpoints;
MozPromiseHolder<PDocumentChannelParent::RedirectToRealChannelPromise>
mPromise;
bool mRequestObserversCalled = false;
};
} // namespace net

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

@ -386,6 +386,10 @@ 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 an document channel is opened.
* This observer topic is notified when a document channel is opened.
* It is similar to http-on-opening-request.
*/
#define NS_DOCUMENT_ON_OPENING_REQUEST_TOPIC "document-on-opening-request"
@ -134,6 +134,13 @@ 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