зеркало из https://github.com/mozilla/gecko-dev.git
466 строки
12 KiB
C++
466 строки
12 KiB
C++
/* -*- 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/. */
|
|
|
|
// HttpLog.h should generally be included first
|
|
#include "HttpLog.h"
|
|
|
|
#include "HttpBackgroundChannelParent.h"
|
|
|
|
#include "HttpChannelParent.h"
|
|
#include "mozilla/ipc/BackgroundParent.h"
|
|
#include "mozilla/IntegerPrintfMacros.h"
|
|
#include "mozilla/Unused.h"
|
|
#include "nsIBackgroundChannelRegistrar.h"
|
|
#include "nsNetCID.h"
|
|
#include "nsQueryObject.h"
|
|
#include "nsThreadUtils.h"
|
|
|
|
using mozilla::dom::ContentParent;
|
|
using mozilla::ipc::AssertIsInMainProcess;
|
|
using mozilla::ipc::AssertIsOnBackgroundThread;
|
|
using mozilla::ipc::BackgroundParent;
|
|
using mozilla::ipc::IPCResult;
|
|
using mozilla::ipc::IsOnBackgroundThread;
|
|
|
|
namespace mozilla {
|
|
namespace net {
|
|
|
|
/*
|
|
* Helper class for continuing the AsyncOpen procedure on main thread.
|
|
*/
|
|
class ContinueAsyncOpenRunnable final : public Runnable
|
|
{
|
|
public:
|
|
ContinueAsyncOpenRunnable(HttpBackgroundChannelParent* aActor,
|
|
const uint64_t& aChannelId)
|
|
: Runnable("net::ContinueAsyncOpenRunnable")
|
|
, mActor(aActor)
|
|
, mChannelId(aChannelId)
|
|
{
|
|
AssertIsInMainProcess();
|
|
AssertIsOnBackgroundThread();
|
|
MOZ_ASSERT(mActor);
|
|
}
|
|
|
|
NS_IMETHOD Run() override
|
|
{
|
|
LOG(("HttpBackgroundChannelParent::ContinueAsyncOpen [this=%p channelId=%"
|
|
PRIu64 "]\n", mActor.get(), mChannelId));
|
|
AssertIsInMainProcess();
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
nsCOMPtr<nsIBackgroundChannelRegistrar> registrar =
|
|
do_GetService(NS_BACKGROUNDCHANNELREGISTRAR_CONTRACTID);
|
|
MOZ_ASSERT(registrar);
|
|
|
|
registrar->LinkBackgroundChannel(mChannelId, mActor);
|
|
return NS_OK;
|
|
}
|
|
|
|
private:
|
|
RefPtr<HttpBackgroundChannelParent> mActor;
|
|
const uint64_t mChannelId;
|
|
};
|
|
|
|
HttpBackgroundChannelParent::HttpBackgroundChannelParent()
|
|
: mIPCOpened(true)
|
|
, mBgThreadMutex("HttpBackgroundChannelParent::BgThreadMutex")
|
|
{
|
|
AssertIsInMainProcess();
|
|
AssertIsOnBackgroundThread();
|
|
|
|
{
|
|
MutexAutoLock lock(mBgThreadMutex);
|
|
mBackgroundThread = NS_GetCurrentThread();
|
|
}
|
|
}
|
|
|
|
HttpBackgroundChannelParent::~HttpBackgroundChannelParent()
|
|
{
|
|
MOZ_ASSERT(NS_IsMainThread() || IsOnBackgroundThread());
|
|
MOZ_ASSERT(!mIPCOpened);
|
|
}
|
|
|
|
nsresult
|
|
HttpBackgroundChannelParent::Init(const uint64_t& aChannelId)
|
|
{
|
|
LOG(("HttpBackgroundChannelParent::Init [this=%p channelId=%" PRIu64 "]\n",
|
|
this, aChannelId));
|
|
AssertIsInMainProcess();
|
|
AssertIsOnBackgroundThread();
|
|
|
|
RefPtr<ContinueAsyncOpenRunnable> runnable =
|
|
new ContinueAsyncOpenRunnable(this, aChannelId);
|
|
|
|
return NS_DispatchToMainThread(runnable);
|
|
}
|
|
|
|
void
|
|
HttpBackgroundChannelParent::LinkToChannel(HttpChannelParent* aChannelParent)
|
|
{
|
|
LOG(("HttpBackgroundChannelParent::LinkToChannel [this=%p channel=%p]\n",
|
|
this, aChannelParent));
|
|
AssertIsInMainProcess();
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
if (!mIPCOpened) {
|
|
return;
|
|
}
|
|
|
|
mChannelParent = aChannelParent;
|
|
}
|
|
|
|
void
|
|
HttpBackgroundChannelParent::OnChannelClosed()
|
|
{
|
|
LOG(("HttpBackgroundChannelParent::OnChannelClosed [this=%p]\n", this));
|
|
AssertIsInMainProcess();
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
if (!mIPCOpened) {
|
|
return;
|
|
}
|
|
|
|
nsresult rv;
|
|
|
|
{
|
|
MutexAutoLock lock(mBgThreadMutex);
|
|
RefPtr<HttpBackgroundChannelParent> self = this;
|
|
rv = mBackgroundThread->Dispatch(
|
|
NS_NewRunnableFunction(
|
|
"net::HttpBackgroundChannelParent::OnChannelClosed",
|
|
[self]() {
|
|
LOG(("HttpBackgroundChannelParent::DeleteRunnable [this=%p]\n",
|
|
self.get()));
|
|
AssertIsOnBackgroundThread();
|
|
|
|
if (!self->mIPCOpened.compareExchange(true, false)) {
|
|
return;
|
|
}
|
|
|
|
Unused << self->Send__delete__(self);
|
|
}),
|
|
NS_DISPATCH_NORMAL);
|
|
}
|
|
|
|
Unused << NS_WARN_IF(NS_FAILED(rv));
|
|
}
|
|
|
|
bool
|
|
HttpBackgroundChannelParent::OnStartRequestSent()
|
|
{
|
|
LOG(("HttpBackgroundChannelParent::OnStartRequestSent [this=%p]\n", this));
|
|
AssertIsInMainProcess();
|
|
|
|
if (NS_WARN_IF(!mIPCOpened)) {
|
|
return false;
|
|
}
|
|
|
|
if (!IsOnBackgroundThread()) {
|
|
MutexAutoLock lock(mBgThreadMutex);
|
|
nsresult rv = mBackgroundThread->Dispatch(
|
|
NewRunnableMethod("net::HttpBackgroundChannelParent::OnStartRequestSent",
|
|
this,
|
|
&HttpBackgroundChannelParent::OnStartRequestSent),
|
|
NS_DISPATCH_NORMAL);
|
|
|
|
MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
|
|
|
|
return NS_SUCCEEDED(rv);
|
|
}
|
|
|
|
return SendOnStartRequestSent();
|
|
}
|
|
|
|
bool
|
|
HttpBackgroundChannelParent::OnTransportAndData(
|
|
const nsresult& aChannelStatus,
|
|
const nsresult& aTransportStatus,
|
|
const uint64_t& aOffset,
|
|
const uint32_t& aCount,
|
|
const nsCString& aData)
|
|
{
|
|
LOG(("HttpBackgroundChannelParent::OnTransportAndData [this=%p]\n", this));
|
|
AssertIsInMainProcess();
|
|
|
|
if (NS_WARN_IF(!mIPCOpened)) {
|
|
return false;
|
|
}
|
|
|
|
if (!IsOnBackgroundThread()) {
|
|
MutexAutoLock lock(mBgThreadMutex);
|
|
nsresult rv = mBackgroundThread->Dispatch(
|
|
NewRunnableMethod<const nsresult,
|
|
const nsresult,
|
|
const uint64_t,
|
|
const uint32_t,
|
|
const nsCString>(
|
|
"net::HttpBackgroundChannelParent::OnTransportAndData",
|
|
this,
|
|
&HttpBackgroundChannelParent::OnTransportAndData,
|
|
aChannelStatus,
|
|
aTransportStatus,
|
|
aOffset,
|
|
aCount,
|
|
aData),
|
|
NS_DISPATCH_NORMAL);
|
|
|
|
MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
|
|
|
|
return NS_SUCCEEDED(rv);
|
|
}
|
|
|
|
return SendOnTransportAndData(aChannelStatus, aTransportStatus,
|
|
aOffset, aCount, aData);
|
|
}
|
|
|
|
bool
|
|
HttpBackgroundChannelParent::OnStopRequest(const nsresult& aChannelStatus,
|
|
const ResourceTimingStruct& aTiming)
|
|
{
|
|
LOG(("HttpBackgroundChannelParent::OnStopRequest [this=%p "
|
|
"status=%" PRIx32 "]\n", this, static_cast<uint32_t>(aChannelStatus)));
|
|
AssertIsInMainProcess();
|
|
|
|
if (NS_WARN_IF(!mIPCOpened)) {
|
|
return false;
|
|
}
|
|
|
|
if (!IsOnBackgroundThread()) {
|
|
MutexAutoLock lock(mBgThreadMutex);
|
|
nsresult rv = mBackgroundThread->Dispatch(
|
|
NewRunnableMethod<const nsresult, const ResourceTimingStruct>(
|
|
"net::HttpBackgroundChannelParent::OnStopRequest",
|
|
this,
|
|
&HttpBackgroundChannelParent::OnStopRequest,
|
|
aChannelStatus,
|
|
aTiming),
|
|
NS_DISPATCH_NORMAL);
|
|
|
|
MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
|
|
|
|
return NS_SUCCEEDED(rv);
|
|
}
|
|
|
|
return SendOnStopRequest(aChannelStatus, aTiming);
|
|
}
|
|
|
|
bool
|
|
HttpBackgroundChannelParent::OnProgress(const int64_t& aProgress,
|
|
const int64_t& aProgressMax)
|
|
{
|
|
LOG(("HttpBackgroundChannelParent::OnProgress [this=%p progress=%" PRId64
|
|
" max=%" PRId64 "]\n", this, aProgress, aProgressMax));
|
|
AssertIsInMainProcess();
|
|
|
|
if (NS_WARN_IF(!mIPCOpened)) {
|
|
return false;
|
|
}
|
|
|
|
if (!IsOnBackgroundThread()) {
|
|
MutexAutoLock lock(mBgThreadMutex);
|
|
nsresult rv = mBackgroundThread->Dispatch(
|
|
NewRunnableMethod<const int64_t, const int64_t>(
|
|
"net::HttpBackgroundChannelParent::OnProgress",
|
|
this,
|
|
&HttpBackgroundChannelParent::OnProgress,
|
|
aProgress,
|
|
aProgressMax),
|
|
NS_DISPATCH_NORMAL);
|
|
|
|
MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
|
|
|
|
return NS_SUCCEEDED(rv);
|
|
}
|
|
|
|
return SendOnProgress(aProgress, aProgressMax);
|
|
}
|
|
|
|
bool
|
|
HttpBackgroundChannelParent::OnStatus(const nsresult& aStatus)
|
|
{
|
|
LOG(("HttpBackgroundChannelParent::OnStatus [this=%p stauts=%" PRIx32
|
|
"]\n", this, static_cast<uint32_t>(aStatus)));
|
|
AssertIsInMainProcess();
|
|
|
|
if (NS_WARN_IF(!mIPCOpened)) {
|
|
return false;
|
|
}
|
|
|
|
if (!IsOnBackgroundThread()) {
|
|
MutexAutoLock lock(mBgThreadMutex);
|
|
nsresult rv = mBackgroundThread->Dispatch(
|
|
NewRunnableMethod<const nsresult>(
|
|
"net::HttpBackgroundChannelParent::OnStatus",
|
|
this,
|
|
&HttpBackgroundChannelParent::OnStatus,
|
|
aStatus),
|
|
NS_DISPATCH_NORMAL);
|
|
|
|
MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
|
|
|
|
return NS_SUCCEEDED(rv);
|
|
}
|
|
|
|
return SendOnStatus(aStatus);
|
|
}
|
|
|
|
bool
|
|
HttpBackgroundChannelParent::OnDiversion()
|
|
{
|
|
LOG(("HttpBackgroundChannelParent::OnDiversion [this=%p]\n", this));
|
|
AssertIsInMainProcess();
|
|
|
|
if (NS_WARN_IF(!mIPCOpened)) {
|
|
return false;
|
|
}
|
|
|
|
if (!IsOnBackgroundThread()) {
|
|
MutexAutoLock lock(mBgThreadMutex);
|
|
nsresult rv = mBackgroundThread->Dispatch(
|
|
NewRunnableMethod("net::HttpBackgroundChannelParent::OnDiversion",
|
|
this,
|
|
&HttpBackgroundChannelParent::OnDiversion),
|
|
NS_DISPATCH_NORMAL);
|
|
|
|
MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
|
|
|
|
return NS_SUCCEEDED(rv);
|
|
}
|
|
|
|
if (!SendFlushedForDiversion()) {
|
|
return false;
|
|
}
|
|
|
|
// The listener chain should now be setup; tell HttpChannelChild to divert
|
|
// the OnDataAvailables and OnStopRequest to associated HttpChannelParent.
|
|
if (!SendDivertMessages()) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
HttpBackgroundChannelParent::OnNotifyTrackingProtectionDisabled()
|
|
{
|
|
LOG(("HttpBackgroundChannelParent::OnNotifyTrackingProtectionDisabled [this=%p]\n", this));
|
|
AssertIsInMainProcess();
|
|
|
|
if (NS_WARN_IF(!mIPCOpened)) {
|
|
return false;
|
|
}
|
|
|
|
if (!IsOnBackgroundThread()) {
|
|
MutexAutoLock lock(mBgThreadMutex);
|
|
nsresult rv = mBackgroundThread->Dispatch(
|
|
NewRunnableMethod(
|
|
"net::HttpBackgroundChannelParent::OnNotifyTrackingProtectionDisabled",
|
|
this,
|
|
&HttpBackgroundChannelParent::OnNotifyTrackingProtectionDisabled),
|
|
NS_DISPATCH_NORMAL);
|
|
|
|
MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
|
|
|
|
return NS_SUCCEEDED(rv);
|
|
}
|
|
|
|
return SendNotifyTrackingProtectionDisabled();
|
|
}
|
|
|
|
bool
|
|
HttpBackgroundChannelParent::OnNotifyTrackingResource()
|
|
{
|
|
LOG(("HttpBackgroundChannelParent::OnNotifyTrackingResource [this=%p]\n", this));
|
|
AssertIsInMainProcess();
|
|
|
|
if (NS_WARN_IF(!mIPCOpened)) {
|
|
return false;
|
|
}
|
|
|
|
if (!IsOnBackgroundThread()) {
|
|
MutexAutoLock lock(mBgThreadMutex);
|
|
nsresult rv = mBackgroundThread->Dispatch(
|
|
NewRunnableMethod(
|
|
"net::HttpBackgroundChannelParent::OnNotifyTrackingResource",
|
|
this,
|
|
&HttpBackgroundChannelParent::OnNotifyTrackingResource),
|
|
NS_DISPATCH_NORMAL);
|
|
|
|
MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
|
|
|
|
return NS_SUCCEEDED(rv);
|
|
}
|
|
|
|
return SendNotifyTrackingResource();
|
|
}
|
|
|
|
bool
|
|
HttpBackgroundChannelParent::OnSetClassifierMatchedInfo(
|
|
const nsACString& aList,
|
|
const nsACString& aProvider,
|
|
const nsACString& aPrefix)
|
|
{
|
|
LOG(("HttpBackgroundChannelParent::OnSetClassifierMatchedInfo [this=%p]\n", this));
|
|
AssertIsInMainProcess();
|
|
|
|
if (NS_WARN_IF(!mIPCOpened)) {
|
|
return false;
|
|
}
|
|
|
|
if (!IsOnBackgroundThread()) {
|
|
MutexAutoLock lock(mBgThreadMutex);
|
|
nsresult rv = mBackgroundThread->Dispatch(
|
|
NewRunnableMethod<const nsCString, const nsCString, const nsCString>(
|
|
"net::HttpBackgroundChannelParent::OnSetClassifierMatchedInfo",
|
|
this,
|
|
&HttpBackgroundChannelParent::OnSetClassifierMatchedInfo,
|
|
aList,
|
|
aProvider,
|
|
aPrefix),
|
|
NS_DISPATCH_NORMAL);
|
|
|
|
MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
|
|
|
|
return NS_SUCCEEDED(rv);
|
|
}
|
|
|
|
ClassifierInfo info;
|
|
info.list() = aList;
|
|
info.prefix() = aPrefix;
|
|
info.provider() = aProvider;
|
|
|
|
return SendSetClassifierMatchedInfo(info);
|
|
}
|
|
|
|
void
|
|
HttpBackgroundChannelParent::ActorDestroy(ActorDestroyReason aWhy)
|
|
{
|
|
LOG(("HttpBackgroundChannelParent::ActorDestroy [this=%p]\n", this));
|
|
AssertIsInMainProcess();
|
|
AssertIsOnBackgroundThread();
|
|
|
|
mIPCOpened = false;
|
|
|
|
RefPtr<HttpBackgroundChannelParent> self = this;
|
|
DebugOnly<nsresult> rv = NS_DispatchToMainThread(NS_NewRunnableFunction(
|
|
"net::HttpBackgroundChannelParent::ActorDestroy", [self]() {
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
RefPtr<HttpChannelParent> channelParent =
|
|
self->mChannelParent.forget();
|
|
|
|
if (channelParent) {
|
|
channelParent->OnBackgroundParentDestroyed();
|
|
}
|
|
}));
|
|
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
|
}
|
|
|
|
} // namespace net
|
|
} // namespace mozilla
|