Bug 1637648 - P3: Forward observer notifications to socket process for nsHttpHandler r=dragana

Differential Revision: https://phabricator.services.mozilla.com/D77307
This commit is contained in:
Kershaw Chang 2020-06-23 11:11:29 +00:00
Родитель 87c26faa97
Коммит 62b5c4afb8
10 изменённых файлов: 111 добавлений и 128 удалений

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

@ -33,41 +33,21 @@ void HttpConnectionMgrChild::ActorDestroy(ActorDestroyReason aWhy) {
}
mozilla::ipc::IPCResult
HttpConnectionMgrChild::RecvDoShiftReloadConnectionCleanup(
const Maybe<HttpConnectionInfoCloneArgs>& aArgs) {
nsresult rv;
if (aArgs) {
RefPtr<nsHttpConnectionInfo> cinfo =
nsHttpConnectionInfo::DeserializeHttpConnectionInfoCloneArgs(
aArgs.ref());
rv = mConnMgr->DoShiftReloadConnectionCleanup(cinfo);
} else {
rv = mConnMgr->DoShiftReloadConnectionCleanup(nullptr);
}
HttpConnectionMgrChild::RecvDoShiftReloadConnectionCleanupWithConnInfo(
const HttpConnectionInfoCloneArgs& aArgs) {
RefPtr<nsHttpConnectionInfo> cinfo =
nsHttpConnectionInfo::DeserializeHttpConnectionInfoCloneArgs(aArgs);
nsresult rv = mConnMgr->DoShiftReloadConnectionCleanupWithConnInfo(cinfo);
if (NS_FAILED(rv)) {
LOG(
("HttpConnectionMgrChild::RecvDoShiftReloadConnectionCleanup failed "
("HttpConnectionMgrChild::DoShiftReloadConnectionCleanupWithConnInfo "
"failed "
"(%08x)\n",
static_cast<uint32_t>(rv)));
}
return IPC_OK();
}
mozilla::ipc::IPCResult HttpConnectionMgrChild::RecvPruneDeadConnections() {
nsresult rv = mConnMgr->PruneDeadConnections();
if (NS_FAILED(rv)) {
LOG(("HttpConnectionMgrChild::RecvPruneDeadConnections failed (%08x)\n",
static_cast<uint32_t>(rv)));
}
return IPC_OK();
}
mozilla::ipc::IPCResult
HttpConnectionMgrChild::RecvAbortAndCloseAllConnections() {
mConnMgr->AbortAndCloseAllConnections(0, nullptr);
return IPC_OK();
}
mozilla::ipc::IPCResult
HttpConnectionMgrChild::RecvUpdateCurrentTopLevelOuterContentWindowId(
const uint64_t& aWindowId) {
@ -120,20 +100,6 @@ mozilla::ipc::IPCResult HttpConnectionMgrChild::RecvCancelTransaction(
return IPC_OK();
}
mozilla::ipc::IPCResult HttpConnectionMgrChild::RecvVerifyTraffic() {
nsresult rv = mConnMgr->VerifyTraffic();
if (NS_FAILED(rv)) {
LOG(("HttpConnectionMgrChild::RecvVerifyTraffic failed (%08x)\n",
static_cast<uint32_t>(rv)));
}
return IPC_OK();
}
mozilla::ipc::IPCResult HttpConnectionMgrChild::RecvClearConnectionHistory() {
Unused << mConnMgr->ClearConnectionHistory();
return IPC_OK();
}
namespace {
class SpeculativeConnectionOverrider final

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

@ -21,10 +21,8 @@ class HttpConnectionMgrChild final : public PHttpConnectionMgrChild {
explicit HttpConnectionMgrChild();
void ActorDestroy(ActorDestroyReason aWhy) override;
mozilla::ipc::IPCResult RecvDoShiftReloadConnectionCleanup(
const Maybe<HttpConnectionInfoCloneArgs>& aArgs);
mozilla::ipc::IPCResult RecvPruneDeadConnections();
mozilla::ipc::IPCResult RecvAbortAndCloseAllConnections();
mozilla::ipc::IPCResult RecvDoShiftReloadConnectionCleanupWithConnInfo(
const HttpConnectionInfoCloneArgs& aArgs);
mozilla::ipc::IPCResult RecvUpdateCurrentTopLevelOuterContentWindowId(
const uint64_t& aWindowId);
mozilla::ipc::IPCResult RecvAddTransaction(PHttpTransactionChild* aTrans,
@ -38,8 +36,6 @@ class HttpConnectionMgrChild final : public PHttpConnectionMgrChild {
PHttpTransactionChild* aTrans, const uint32_t& aClassOfService);
mozilla::ipc::IPCResult RecvCancelTransaction(PHttpTransactionChild* aTrans,
const nsresult& aReason);
mozilla::ipc::IPCResult RecvVerifyTraffic();
mozilla::ipc::IPCResult RecvClearConnectionHistory();
mozilla::ipc::IPCResult RecvSpeculativeConnect(
HttpConnectionInfoCloneArgs aConnInfo,
Maybe<SpeculativeConnectionOverriderArgs> aOverriderArgs, uint32_t aCaps,

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

@ -56,33 +56,39 @@ nsresult HttpConnectionMgrParent::UpdateRequestTokenBucket(
return NS_OK;
}
nsresult HttpConnectionMgrParent::DoShiftReloadConnectionCleanup(
nsresult HttpConnectionMgrParent::DoShiftReloadConnectionCleanup() {
// Do nothing here. DoShiftReloadConnectionCleanup() will be triggered by
// observer notification or pref change in socket process.
return NS_OK;
}
nsresult HttpConnectionMgrParent::DoShiftReloadConnectionCleanupWithConnInfo(
nsHttpConnectionInfo* aCi) {
Maybe<HttpConnectionInfoCloneArgs> optionArgs;
if (aCi) {
optionArgs.emplace();
nsHttpConnectionInfo::SerializeHttpConnectionInfo(aCi, optionArgs.ref());
if (!aCi) {
return NS_ERROR_INVALID_ARG;
}
HttpConnectionInfoCloneArgs connInfoArgs;
nsHttpConnectionInfo::SerializeHttpConnectionInfo(aCi, connInfoArgs);
RefPtr<HttpConnectionMgrParent> self = this;
auto task = [self, optionArgs{std::move(optionArgs)}]() {
Unused << self->SendDoShiftReloadConnectionCleanup(optionArgs);
auto task = [self, connInfoArgs{std::move(connInfoArgs)}]() {
Unused << self->SendDoShiftReloadConnectionCleanupWithConnInfo(
connInfoArgs);
};
gIOService->CallOrWaitForSocketProcess(std::move(task));
return NS_OK;
}
nsresult HttpConnectionMgrParent::PruneDeadConnections() {
RefPtr<HttpConnectionMgrParent> self = this;
auto task = [self]() { Unused << self->SendPruneDeadConnections(); };
gIOService->CallOrWaitForSocketProcess(std::move(task));
// Do nothing here. PruneDeadConnections() will be triggered by
// observer notification or pref change in socket process.
return NS_OK;
}
void HttpConnectionMgrParent::AbortAndCloseAllConnections(int32_t, ARefBase*) {
RefPtr<HttpConnectionMgrParent> self = this;
auto task = [self]() { Unused << self->SendAbortAndCloseAllConnections(); };
gIOService->CallOrWaitForSocketProcess(std::move(task));
// Do nothing here. AbortAndCloseAllConnections() will be triggered by
// observer notification in socket process.
}
nsresult HttpConnectionMgrParent::UpdateParam(nsParamName name,
@ -228,9 +234,8 @@ nsresult HttpConnectionMgrParent::SpeculativeConnect(
}
nsresult HttpConnectionMgrParent::VerifyTraffic() {
RefPtr<HttpConnectionMgrParent> self = this;
auto task = [self]() { Unused << self->SendVerifyTraffic(); };
gIOService->CallOrWaitForSocketProcess(std::move(task));
// Do nothing here. VerifyTraffic() will be triggered by observer notification
// in socket process.
return NS_OK;
}
@ -239,9 +244,8 @@ void HttpConnectionMgrParent::BlacklistSpdy(const nsHttpConnectionInfo* ci) {
}
nsresult HttpConnectionMgrParent::ClearConnectionHistory() {
RefPtr<HttpConnectionMgrParent> self = this;
auto task = [self]() { Unused << self->SendClearConnectionHistory(); };
gIOService->CallOrWaitForSocketProcess(std::move(task));
// Do nothing here. ClearConnectionHistory() will be triggered by
// observer notification in socket process.
return NS_OK;
}

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

@ -73,9 +73,12 @@ class HttpConnectionMgrShell : public nsISupports {
EventTokenBucket* aBucket) = 0;
// Close all idle persistent connections and prevent any active connections
// from being reused. Optional connection info resets CI specific
// from being reused.
[[nodiscard]] virtual nsresult DoShiftReloadConnectionCleanup() = 0;
// Like DoShiftReloadConnectionCleanup() above, but also resets CI specific
// information such as Happy Eyeballs history.
[[nodiscard]] virtual nsresult DoShiftReloadConnectionCleanup(
[[nodiscard]] virtual nsresult DoShiftReloadConnectionCleanupWithConnInfo(
nsHttpConnectionInfo*) = 0;
// called to force the connection manager to prune its list of idle
@ -185,8 +188,9 @@ NS_DEFINE_STATIC_IID_ACCESSOR(HttpConnectionMgrShell,
virtual nsresult Shutdown() override; \
virtual nsresult UpdateRequestTokenBucket(EventTokenBucket* aBucket) \
override; \
virtual nsresult DoShiftReloadConnectionCleanup(nsHttpConnectionInfo*) \
override; \
virtual nsresult DoShiftReloadConnectionCleanup() override; \
virtual nsresult DoShiftReloadConnectionCleanupWithConnInfo( \
nsHttpConnectionInfo*) override; \
virtual nsresult PruneDeadConnections() override; \
virtual void AbortAndCloseAllConnections(int32_t, ARefBase*) override; \
virtual nsresult UpdateParam(nsParamName name, uint16_t value) override; \

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

@ -21,9 +21,7 @@ async refcounted protocol PHttpConnectionMgr
child:
async __delete__();
async DoShiftReloadConnectionCleanup(HttpConnectionInfoCloneArgs? aArgs);
async PruneDeadConnections();
async AbortAndCloseAllConnections();
async DoShiftReloadConnectionCleanupWithConnInfo(HttpConnectionInfoCloneArgs aArgs);
async UpdateCurrentTopLevelOuterContentWindowId(uint64_t aWindowId);
async AddTransaction(PHttpTransaction aTrans, int32_t aPriority);
async AddTransactionWithStickyConn(PHttpTransaction aTrans, int32_t aPriority,
@ -32,8 +30,6 @@ child:
async UpdateClassOfServiceOnTransaction(PHttpTransaction aTrans,
uint32_t aClassOfService);
async CancelTransaction(PHttpTransaction aTrans, nsresult aReason);
async VerifyTraffic();
async ClearConnectionHistory();
async SpeculativeConnect(HttpConnectionInfoCloneArgs aConnInfo,
SpeculativeConnectionOverriderArgs? aOverriderArgs,
uint32_t aCaps, PAltSvcTransaction? aTrans);

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

@ -476,13 +476,13 @@ nsresult TRRServiceChannel::BeginConnect() {
// just the initial document resets the whole pool
if (mLoadFlags & LOAD_INITIAL_DOCUMENT_URI) {
gHttpHandler->AltServiceCache()->ClearAltServiceMappings();
rv = gHttpHandler->ConnMgr()->DoShiftReloadConnectionCleanup(
rv = gHttpHandler->ConnMgr()->DoShiftReloadConnectionCleanupWithConnInfo(
mConnectionInfo);
if (NS_FAILED(rv)) {
LOG(
("TRRServiceChannel::BeginConnect "
"DoShiftReloadConnectionCleanup failed: %08x [this=%p]",
static_cast<uint32_t>(rv), this));
LOG((
"TRRServiceChannel::BeginConnect "
"DoShiftReloadConnectionCleanupWithConnInfo failed: %08x [this=%p]",
static_cast<uint32_t>(rv), this));
}
}
}

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

@ -6903,12 +6903,13 @@ nsresult nsHttpChannel::BeginConnect() {
// just the initial document resets the whole pool
if (mLoadFlags & LOAD_INITIAL_DOCUMENT_URI) {
gHttpHandler->AltServiceCache()->ClearAltServiceMappings();
rv = gHttpHandler->DoShiftReloadConnectionCleanup(mConnectionInfo);
rv = gHttpHandler->DoShiftReloadConnectionCleanupWithConnInfo(
mConnectionInfo);
if (NS_FAILED(rv)) {
LOG(
("nsHttpChannel::BeginConnect "
"DoShiftReloadConnectionCleanup failed: %08x [this=%p]",
static_cast<uint32_t>(rv), this));
LOG((
"nsHttpChannel::BeginConnect "
"DoShiftReloadConnectionCleanupWithConnInfo failed: %08x [this=%p]",
static_cast<uint32_t>(rv), this));
}
}
}

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

@ -452,12 +452,18 @@ nsresult nsHttpConnectionMgr::VerifyTraffic() {
return PostEvent(&nsHttpConnectionMgr::OnMsgVerifyTraffic);
}
nsresult nsHttpConnectionMgr::DoShiftReloadConnectionCleanup(
nsresult nsHttpConnectionMgr::DoShiftReloadConnectionCleanup() {
return PostEvent(&nsHttpConnectionMgr::OnMsgDoShiftReloadConnectionCleanup, 0,
nullptr);
}
nsresult nsHttpConnectionMgr::DoShiftReloadConnectionCleanupWithConnInfo(
nsHttpConnectionInfo* aCI) {
RefPtr<nsHttpConnectionInfo> ci;
if (aCI) {
ci = aCI->Clone();
if (!aCI) {
return NS_ERROR_INVALID_ARG;
}
RefPtr<nsHttpConnectionInfo> ci = aCI->Clone();
return PostEvent(&nsHttpConnectionMgr::OnMsgDoShiftReloadConnectionCleanup, 0,
ci);
}

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

@ -547,7 +547,8 @@ nsresult nsHttpHandler::Init() {
static_cast<nsISupports*>(static_cast<void*>(this)),
NS_HTTP_STARTUP_TOPIC);
nsCOMPtr<nsIObserverService> obsService = services::GetObserverService();
nsCOMPtr<nsIObserverService> obsService =
static_cast<nsIObserverService*>(gIOService);
if (obsService) {
// register the handler object as a weak callback as we don't need to worry
// about shutdown ordering.
@ -1136,7 +1137,7 @@ void nsHttpHandler::PrefsChanged(const char* pref) {
if (MULTI_PREF_CHANGED(SECURITY_PREFIX)) {
LOG(("nsHttpHandler::PrefsChanged Security Pref Changed %s\n", pref));
if (mConnMgr) {
rv = mConnMgr->DoShiftReloadConnectionCleanup(nullptr);
rv = mConnMgr->DoShiftReloadConnectionCleanup();
if (NS_FAILED(rv)) {
LOG(
("nsHttpHandler::PrefsChanged "
@ -2285,23 +2286,27 @@ nsHttpHandler::Observe(nsISupports* subject, const char* topic,
// depend on this value.
mSessionStartTime = NowInSeconds();
if (!StaticPrefs::privacy_donottrackheader_enabled()) {
Telemetry::Accumulate(Telemetry::DNT_USAGE, 2);
} else {
Telemetry::Accumulate(Telemetry::DNT_USAGE, 1);
}
// Since nsHttpHandler::Observe() is also called in socket process, we don't
// want to do telemetry twice.
if (XRE_IsParentProcess()) {
if (!StaticPrefs::privacy_donottrackheader_enabled()) {
Telemetry::Accumulate(Telemetry::DNT_USAGE, 2);
} else {
Telemetry::Accumulate(Telemetry::DNT_USAGE, 1);
}
if (UseFastOpen()) {
Telemetry::Accumulate(Telemetry::TCP_FAST_OPEN_STATUS, 0);
} else if (!mFastOpenSupported) {
Telemetry::Accumulate(Telemetry::TCP_FAST_OPEN_STATUS, 1);
} else if (!mUseFastOpen) {
Telemetry::Accumulate(Telemetry::TCP_FAST_OPEN_STATUS, 2);
} else if (mFastOpenConsecutiveFailureCounter >=
mFastOpenConsecutiveFailureLimit) {
Telemetry::Accumulate(Telemetry::TCP_FAST_OPEN_STATUS, 3);
} else {
Telemetry::Accumulate(Telemetry::TCP_FAST_OPEN_STATUS, 4);
if (UseFastOpen()) {
Telemetry::Accumulate(Telemetry::TCP_FAST_OPEN_STATUS, 0);
} else if (!mFastOpenSupported) {
Telemetry::Accumulate(Telemetry::TCP_FAST_OPEN_STATUS, 1);
} else if (!mUseFastOpen) {
Telemetry::Accumulate(Telemetry::TCP_FAST_OPEN_STATUS, 2);
} else if (mFastOpenConsecutiveFailureCounter >=
mFastOpenConsecutiveFailureLimit) {
Telemetry::Accumulate(Telemetry::TCP_FAST_OPEN_STATUS, 3);
} else {
Telemetry::Accumulate(Telemetry::TCP_FAST_OPEN_STATUS, 4);
}
}
} else if (!strcmp(topic, "profile-change-net-restore")) {
// initialize connection manager
@ -2325,7 +2330,7 @@ nsHttpHandler::Observe(nsISupports* subject, const char* topic,
}
} else if (!strcmp(topic, "net:prune-all-connections")) {
if (mConnMgr) {
rv = mConnMgr->DoShiftReloadConnectionCleanup(nullptr);
rv = mConnMgr->DoShiftReloadConnectionCleanup();
if (NS_FAILED(rv)) {
LOG((" DoShiftReloadConnectionCleanup failed (%08x)\n",
static_cast<uint32_t>(rv)));
@ -2350,9 +2355,9 @@ nsHttpHandler::Observe(nsISupports* subject, const char* topic,
} else if (!strcmp(topic, "browser:purge-session-history")) {
if (mConnMgr) {
Unused << mConnMgr->ClearConnectionHistory();
if (mAltSvcCache) {
mAltSvcCache->ClearAltServiceMappings();
}
}
if (mAltSvcCache) {
mAltSvcCache->ClearAltServiceMappings();
}
} else if (!strcmp(topic, NS_NETWORK_LINK_TOPIC)) {
nsAutoCString converted = NS_ConvertUTF16toUTF8(data);
@ -2373,26 +2378,29 @@ nsHttpHandler::Observe(nsISupports* subject, const char* topic,
// going to the background on android means we should close
// down idle connections for power conservation
if (mConnMgr) {
rv = mConnMgr->DoShiftReloadConnectionCleanup(nullptr);
rv = mConnMgr->DoShiftReloadConnectionCleanup();
if (NS_FAILED(rv)) {
LOG((" DoShiftReloadConnectionCleanup failed (%08x)\n",
static_cast<uint32_t>(rv)));
}
}
} else if (!strcmp(topic, "net:current-toplevel-outer-content-windowid")) {
nsCOMPtr<nsISupportsPRUint64> wrapper = do_QueryInterface(subject);
MOZ_RELEASE_ASSERT(wrapper);
// The window id will be updated by HttpConnectionMgrParent.
if (XRE_IsParentProcess()) {
nsCOMPtr<nsISupportsPRUint64> wrapper = do_QueryInterface(subject);
MOZ_RELEASE_ASSERT(wrapper);
uint64_t windowId = 0;
wrapper->GetData(&windowId);
MOZ_ASSERT(windowId);
uint64_t windowId = 0;
wrapper->GetData(&windowId);
MOZ_ASSERT(windowId);
static uint64_t sCurrentTopLevelOuterContentWindowId = 0;
if (sCurrentTopLevelOuterContentWindowId != windowId) {
sCurrentTopLevelOuterContentWindowId = windowId;
if (mConnMgr) {
mConnMgr->UpdateCurrentTopLevelOuterContentWindowId(
sCurrentTopLevelOuterContentWindowId);
static uint64_t sCurrentTopLevelOuterContentWindowId = 0;
if (sCurrentTopLevelOuterContentWindowId != windowId) {
sCurrentTopLevelOuterContentWindowId = windowId;
if (mConnMgr) {
mConnMgr->UpdateCurrentTopLevelOuterContentWindowId(
sCurrentTopLevelOuterContentWindowId);
}
}
}
} else if (!strcmp(topic, "captive-portal-login") ||
@ -2451,8 +2459,8 @@ static bool CanEnableSpeculativeConnect() {
void nsHttpHandler::MaybeEnableSpeculativeConnect() {
MOZ_ASSERT(NS_IsMainThread(), "Main thread only");
// We don't need to and can't check this in the child process.
if (IsNeckoChild()) {
// We don't need to and can't check this in the child and socket process.
if (!XRE_IsParentProcess()) {
return;
}
@ -2870,9 +2878,10 @@ nsresult nsHttpHandler::CompleteUpgrade(
return mConnMgr->CompleteUpgrade(aTrans, aUpgradeListener);
}
nsresult nsHttpHandler::DoShiftReloadConnectionCleanup(
nsresult nsHttpHandler::DoShiftReloadConnectionCleanupWithConnInfo(
nsHttpConnectionInfo* aCi) {
return mConnMgr->DoShiftReloadConnectionCleanup(aCi);
MOZ_ASSERT(aCi);
return mConnMgr->DoShiftReloadConnectionCleanupWithConnInfo(aCi);
}
void nsHttpHandler::ClearHostMapping(nsHttpConnectionInfo* aConnInfo) {

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

@ -485,7 +485,8 @@ class nsHttpHandler final : public nsIHttpProtocolHandler,
nsresult CompleteUpgrade(HttpTransactionShell* aTrans,
nsIHttpUpgradeListener* aUpgradeListener);
nsresult DoShiftReloadConnectionCleanup(nsHttpConnectionInfo* aCI = nullptr);
nsresult DoShiftReloadConnectionCleanupWithConnInfo(
nsHttpConnectionInfo* aCI);
private:
nsHttpHandler();