зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1015466 - Part 3, PHttpBackgroundChannel lifecycle management. r=mayhemer
PHttpBackgroundChannel is created by content process because PBackground IPDL can only be initiated from content process. The background channel deletion is controlled by chrome process while PHttpChannel is going to be closed or canceled. BackgroundChannelRegistrar is introduced for pairing HttpChannelParent and HttpBackgroundChannelParent since they are created over different IPDL asynchronously. nsIParentRedirectingChannel.continueVerification is introduced to asynchronously wait for background channel to be established on the new channel during the Redirect2Verify phase. MozReview-Commit-ID: 41l8ivan8iA --HG-- extra : rebase_source : b8b6d7e7c037efaa9fc13df14191205c603e833a
This commit is contained in:
Родитель
ccfe1721d6
Коммит
e7a014adc4
|
@ -33,6 +33,7 @@
|
|||
#include "mozilla/ipc/PChildToParentStreamChild.h"
|
||||
#include "mozilla/ipc/PParentToChildStreamChild.h"
|
||||
#include "mozilla/layout/VsyncChild.h"
|
||||
#include "mozilla/net/HttpBackgroundChannelChild.h"
|
||||
#include "mozilla/net/PUDPSocketChild.h"
|
||||
#include "mozilla/dom/network/UDPSocketChild.h"
|
||||
#include "mozilla/dom/WebAuthnTransactionChild.h"
|
||||
|
@ -569,8 +570,11 @@ BackgroundChildImpl::AllocPHttpBackgroundChannelChild(const uint64_t& aChannelId
|
|||
bool
|
||||
BackgroundChildImpl::DeallocPHttpBackgroundChannelChild(PHttpBackgroundChannelChild* aActor)
|
||||
{
|
||||
MOZ_ASSERT(aActor);
|
||||
// TODO
|
||||
// The reference is increased in BackgroundChannelCreateCallback::ActorCreated
|
||||
// of HttpBackgroundChannelChild.cpp. We should decrease it after IPC
|
||||
// destroyed.
|
||||
RefPtr<net::HttpBackgroundChannelChild> child =
|
||||
dont_AddRef(static_cast<net::HttpBackgroundChannelChild*>(aActor));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -879,7 +879,11 @@ BackgroundParentImpl::AllocPHttpBackgroundChannelParent(const uint64_t& aChannel
|
|||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
return new net::HttpBackgroundChannelParent();
|
||||
RefPtr<net::HttpBackgroundChannelParent> actor =
|
||||
new net::HttpBackgroundChannelParent();
|
||||
|
||||
// hold extra refcount for IPDL
|
||||
return actor.forget().take();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
|
@ -891,7 +895,13 @@ BackgroundParentImpl::RecvPHttpBackgroundChannelConstructor(
|
|||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
//TODO
|
||||
net::HttpBackgroundChannelParent* aParent =
|
||||
static_cast<net::HttpBackgroundChannelParent*>(aActor);
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(aParent->Init(aChannelId)))) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
@ -903,7 +913,10 @@ BackgroundParentImpl::DeallocPHttpBackgroundChannelParent(
|
|||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
//TODO
|
||||
// release extra refcount hold by AllocPHttpBackgroundChannelParent
|
||||
RefPtr<net::HttpBackgroundChannelParent> actor =
|
||||
dont_AddRef(static_cast<net::HttpBackgroundChannelParent*>(aActor));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,20 @@ interface nsITabParent;
|
|||
interface nsIChannel;
|
||||
interface nsIAsyncVerifyRedirectCallback;
|
||||
|
||||
[builtinclass, uuid(01987690-48cf-45de-bae3-e143c2adc2a8)]
|
||||
interface nsIAsyncVerifyRedirectReadyCallback : nsISupports
|
||||
{
|
||||
/**
|
||||
* Asynchronous callback when redirected channel finishes the preparation for
|
||||
* completing the verification procedure.
|
||||
*
|
||||
* @param result
|
||||
* SUCCEEDED if preparation for redirection verification succceed.
|
||||
* If FAILED the redirection must be aborted.
|
||||
*/
|
||||
void readyToVerify(in nsresult result);
|
||||
};
|
||||
|
||||
/**
|
||||
* Implemented by chrome side of IPC protocols that support redirect responses.
|
||||
*/
|
||||
|
@ -33,6 +47,17 @@ interface nsIParentRedirectingChannel : nsIParentChannel
|
|||
in uint32_t redirectFlags,
|
||||
in nsIAsyncVerifyRedirectCallback callback);
|
||||
|
||||
/**
|
||||
* Called to new channel when the original channel got Redirect2Verify
|
||||
* response from child. Callback will be invoked when the new channel
|
||||
* finishes the preparation for Redirect2Verify and can be called immediately.
|
||||
*
|
||||
* @param callback
|
||||
* redirect ready callback, will be called when redirect verification
|
||||
* procedure can proceed.
|
||||
*/
|
||||
void continueVerification(in nsIAsyncVerifyRedirectReadyCallback callback);
|
||||
|
||||
/**
|
||||
* Called after we are done with redirecting process and we know if to
|
||||
* redirect or not. Forward the redirect result to the child process. From
|
||||
|
|
|
@ -637,6 +637,18 @@
|
|||
{0x97, 0xa7, 0x06, 0xaf, 0x5e, 0x6d, 0x84, 0xc4} \
|
||||
}
|
||||
|
||||
// Background channel registrar used for pairing HttpChannelParent
|
||||
// and its background channel
|
||||
#define NS_BACKGROUNDCHANNELREGISTRAR_CONTRACTID \
|
||||
"@mozilla.org/network/background-channel-registrar;1"
|
||||
#define NS_BACKGROUNDCHANNELREGISTRAR_CID \
|
||||
{ /* 6907788a-17cc-4c2a-a7c5-59ad2d9cc079 */ \
|
||||
0x6907788a, \
|
||||
0x17cc, \
|
||||
0x4c2a, \
|
||||
{ 0xa7, 0xc5, 0x59, 0xad, 0x2d, 0x9c, 0xc0, 0x79} \
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* netwerk/protocol/ftp/ classes
|
||||
*/
|
||||
|
|
|
@ -267,6 +267,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsFtpProtocolHandler, Init)
|
|||
#include "nsHttpNTLMAuth.h"
|
||||
#include "nsHttpActivityDistributor.h"
|
||||
#include "ThrottleQueue.h"
|
||||
#include "BackgroundChannelRegistrar.h"
|
||||
#undef LOG
|
||||
#undef LOG_ENABLED
|
||||
namespace mozilla {
|
||||
|
@ -280,6 +281,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsHttpActivityDistributor)
|
|||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsHttpBasicAuth)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsHttpDigestAuth)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(ThrottleQueue)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(BackgroundChannelRegistrar)
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
#endif // !NECKO_PROTOCOL_http
|
||||
|
@ -805,6 +807,7 @@ NS_DEFINE_NAMED_CID(NS_HTTPAUTHMANAGER_CID);
|
|||
NS_DEFINE_NAMED_CID(NS_HTTPCHANNELAUTHPROVIDER_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_HTTPACTIVITYDISTRIBUTOR_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_THROTTLEQUEUE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_BACKGROUNDCHANNELREGISTRAR_CID);
|
||||
#endif // !NECKO_PROTOCOL_http
|
||||
#ifdef NECKO_PROTOCOL_ftp
|
||||
NS_DEFINE_NAMED_CID(NS_FTPPROTOCOLHANDLER_CID);
|
||||
|
@ -956,6 +959,7 @@ static const mozilla::Module::CIDEntry kNeckoCIDs[] = {
|
|||
{ &kNS_HTTPCHANNELAUTHPROVIDER_CID, false, nullptr, mozilla::net::nsHttpChannelAuthProviderConstructor },
|
||||
{ &kNS_HTTPACTIVITYDISTRIBUTOR_CID, false, nullptr, mozilla::net::nsHttpActivityDistributorConstructor },
|
||||
{ &kNS_THROTTLEQUEUE_CID, false, nullptr, mozilla::net::ThrottleQueueConstructor },
|
||||
{ &kNS_BACKGROUNDCHANNELREGISTRAR_CID, false, nullptr, mozilla::net::BackgroundChannelRegistrarConstructor },
|
||||
#endif // !NECKO_PROTOCOL_http
|
||||
#ifdef NECKO_PROTOCOL_ftp
|
||||
{ &kNS_FTPPROTOCOLHANDLER_CID, false, nullptr, nsFtpProtocolHandlerConstructor },
|
||||
|
@ -1117,6 +1121,7 @@ static const mozilla::Module::ContractIDEntry kNeckoContracts[] = {
|
|||
{ NS_HTTPCHANNELAUTHPROVIDER_CONTRACTID, &kNS_HTTPCHANNELAUTHPROVIDER_CID },
|
||||
{ NS_HTTPACTIVITYDISTRIBUTOR_CONTRACTID, &kNS_HTTPACTIVITYDISTRIBUTOR_CID },
|
||||
{ NS_THROTTLEQUEUE_CONTRACTID, &kNS_THROTTLEQUEUE_CID },
|
||||
{ NS_BACKGROUNDCHANNELREGISTRAR_CONTRACTID, &kNS_BACKGROUNDCHANNELREGISTRAR_CID },
|
||||
#endif // !NECKO_PROTOCOL_http
|
||||
#ifdef NECKO_PROTOCOL_ftp
|
||||
{ NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "ftp", &kNS_FTPPROTOCOLHANDLER_CID },
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 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 "BackgroundChannelRegistrar.h"
|
||||
|
||||
#include "HttpBackgroundChannelParent.h"
|
||||
#include "HttpChannelParent.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
NS_IMPL_ISUPPORTS(BackgroundChannelRegistrar, nsIBackgroundChannelRegistrar)
|
||||
|
||||
BackgroundChannelRegistrar::BackgroundChannelRegistrar()
|
||||
{
|
||||
// BackgroundChannelRegistrar is a main-thread-only object.
|
||||
// All the operations should be run on main thread.
|
||||
// It should be used on chrome process only.
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
}
|
||||
|
||||
BackgroundChannelRegistrar::~BackgroundChannelRegistrar()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
}
|
||||
|
||||
void
|
||||
BackgroundChannelRegistrar::NotifyChannelLinked(
|
||||
HttpChannelParent* aChannelParent,
|
||||
HttpBackgroundChannelParent* aBgParent)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aChannelParent);
|
||||
MOZ_ASSERT(aBgParent);
|
||||
|
||||
aBgParent->LinkToChannel(aChannelParent);
|
||||
aChannelParent->OnBackgroundParentReady(aBgParent);
|
||||
}
|
||||
|
||||
// nsIBackgroundChannelRegistrar
|
||||
void
|
||||
BackgroundChannelRegistrar::DeleteChannel(uint64_t aKey)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mChannels.Remove(aKey);
|
||||
mBgChannels.Remove(aKey);
|
||||
}
|
||||
|
||||
void
|
||||
BackgroundChannelRegistrar::LinkHttpChannel(
|
||||
uint64_t aKey,
|
||||
HttpChannelParent* aChannel)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aChannel);
|
||||
|
||||
RefPtr<HttpBackgroundChannelParent> bgParent;
|
||||
bool found = mBgChannels.Remove(aKey, getter_AddRefs(bgParent));
|
||||
|
||||
if (!found) {
|
||||
mChannels.Put(aKey, aChannel);
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(bgParent);
|
||||
NotifyChannelLinked(aChannel, bgParent);
|
||||
}
|
||||
|
||||
void
|
||||
BackgroundChannelRegistrar::LinkBackgroundChannel(
|
||||
uint64_t aKey,
|
||||
HttpBackgroundChannelParent* aBgChannel)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aBgChannel);
|
||||
|
||||
RefPtr<HttpChannelParent> parent;
|
||||
bool found = mChannels.Remove(aKey, getter_AddRefs(parent));
|
||||
|
||||
if (!found) {
|
||||
mBgChannels.Put(aKey, aBgChannel);
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(parent);
|
||||
NotifyChannelLinked(parent, aBgChannel);
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,52 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 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_BackgroundChannelRegistrar_h__
|
||||
#define mozilla_net_BackgroundChannelRegistrar_h__
|
||||
|
||||
#include "nsIBackgroundChannelRegistrar.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
class HttpBackgroundChannelParent;
|
||||
class HttpChannelParent;
|
||||
|
||||
class BackgroundChannelRegistrar final : public nsIBackgroundChannelRegistrar
|
||||
{
|
||||
typedef nsRefPtrHashtable<nsUint64HashKey, HttpChannelParent>
|
||||
ChannelHashtable;
|
||||
typedef nsRefPtrHashtable<nsUint64HashKey, HttpBackgroundChannelParent>
|
||||
BackgroundChannelHashtable;
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIBACKGROUNDCHANNELREGISTRAR
|
||||
|
||||
explicit BackgroundChannelRegistrar();
|
||||
|
||||
private:
|
||||
virtual ~BackgroundChannelRegistrar();
|
||||
|
||||
// A helper function for BackgroundChannelRegistrar itself to callback
|
||||
// HttpChannelParent and HttpBackgroundChannelParent when both objects are
|
||||
// ready. aChannelParent and aBgParent is the pair of HttpChannelParent and
|
||||
// HttpBackgroundChannelParent that should be linked together.
|
||||
void NotifyChannelLinked(HttpChannelParent* aChannelParent,
|
||||
HttpBackgroundChannelParent* aBgParent);
|
||||
|
||||
// Store unlinked HttpChannelParent objects.
|
||||
ChannelHashtable mChannels;
|
||||
|
||||
// Store unlinked HttpBackgroundChannelParent objects.
|
||||
BackgroundChannelHashtable mBgChannels;
|
||||
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_net_BackgroundChannelRegistrar_h__
|
|
@ -5,13 +5,82 @@
|
|||
* 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 "HttpBackgroundChannelChild.h"
|
||||
|
||||
#include "HttpChannelChild.h"
|
||||
#include "MainThreadUtils.h"
|
||||
#include "mozilla/ipc/BackgroundChild.h"
|
||||
#include "mozilla/ipc/PBackgroundChild.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "nsIIPCBackgroundChildCreateCallback.h"
|
||||
|
||||
using mozilla::ipc::BackgroundChild;
|
||||
using mozilla::ipc::IPCResult;
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
// Callbacks for PBackgroundChild creation
|
||||
class BackgroundChannelCreateCallback final
|
||||
: public nsIIPCBackgroundChildCreateCallback
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIIPCBACKGROUNDCHILDCREATECALLBACK
|
||||
|
||||
explicit BackgroundChannelCreateCallback(HttpBackgroundChannelChild* aBgChild)
|
||||
: mBgChild(aBgChild)
|
||||
{
|
||||
MOZ_ASSERT(aBgChild);
|
||||
}
|
||||
|
||||
private:
|
||||
virtual ~BackgroundChannelCreateCallback() { }
|
||||
|
||||
RefPtr<HttpBackgroundChannelChild> mBgChild;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(BackgroundChannelCreateCallback,
|
||||
nsIIPCBackgroundChildCreateCallback)
|
||||
|
||||
void
|
||||
BackgroundChannelCreateCallback::ActorCreated(PBackgroundChild* aActor)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aActor);
|
||||
MOZ_ASSERT(mBgChild);
|
||||
|
||||
if (!mBgChild->mChannelChild) {
|
||||
// HttpChannelChild is closed during PBackground creation,
|
||||
// abort the rest of steps.
|
||||
return;
|
||||
}
|
||||
|
||||
const uint64_t channelId = mBgChild->mChannelChild->ChannelId();
|
||||
if (!aActor->SendPHttpBackgroundChannelConstructor(mBgChild,
|
||||
channelId)) {
|
||||
ActorFailed();
|
||||
return;
|
||||
}
|
||||
|
||||
// hold extra reference for IPDL
|
||||
RefPtr<HttpBackgroundChannelChild> child = mBgChild;
|
||||
Unused << child.forget().take();
|
||||
}
|
||||
|
||||
void
|
||||
BackgroundChannelCreateCallback::ActorFailed()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mBgChild);
|
||||
|
||||
mBgChild->OnBackgroundChannelCreationFailed();
|
||||
}
|
||||
|
||||
// HttpBackgroundChannelChild
|
||||
HttpBackgroundChannelChild::HttpBackgroundChannelChild()
|
||||
{
|
||||
}
|
||||
|
@ -20,6 +89,60 @@ HttpBackgroundChannelChild::~HttpBackgroundChannelChild()
|
|||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
HttpBackgroundChannelChild::Init(HttpChannelChild* aChannelChild)
|
||||
{
|
||||
LOG(("HttpBackgroundChannelChild::Init [this=%p httpChannel=%p channelId=%"
|
||||
PRIu64 "]\n", this, aChannelChild, aChannelChild->ChannelId()));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
NS_ENSURE_ARG(aChannelChild);
|
||||
|
||||
mChannelChild = aChannelChild;
|
||||
|
||||
if (NS_WARN_IF(!CreateBackgroundChannel())) {
|
||||
mChannelChild = nullptr;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
HttpBackgroundChannelChild::OnChannelClosed()
|
||||
{
|
||||
LOG(("HttpBackgroundChannelChild::OnChannelClosed [this=%p]\n", this));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// HttpChannelChild is not going to handle any incoming message.
|
||||
mChannelChild = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
HttpBackgroundChannelChild::OnBackgroundChannelCreationFailed()
|
||||
{
|
||||
LOG(("HttpBackgroundChannelChild::OnBackgroundChannelCreationFailed"
|
||||
" [this=%p]\n", this));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (mChannelChild) {
|
||||
RefPtr<HttpChannelChild> channelChild = mChannelChild.forget();
|
||||
channelChild->FailedAsyncOpen(NS_ERROR_UNEXPECTED);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
HttpBackgroundChannelChild::CreateBackgroundChannel()
|
||||
{
|
||||
LOG(("HttpBackgroundChannelChild::CreateBackgroundChannel [this=%p]\n", this));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
RefPtr<BackgroundChannelCreateCallback> callback =
|
||||
new BackgroundChannelCreateCallback(this);
|
||||
|
||||
return BackgroundChild::GetOrCreateForCurrentThread(callback);
|
||||
}
|
||||
|
||||
// PHttpBackgroundChannelChild
|
||||
IPCResult
|
||||
HttpBackgroundChannelChild::RecvOnStartRequestSent()
|
||||
{
|
||||
|
@ -73,6 +196,13 @@ HttpBackgroundChannelChild::RecvDivertMessages()
|
|||
void
|
||||
HttpBackgroundChannelChild::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
LOG(("HttpBackgroundChannelChild::ActorDestroy[this=%p]\n", this));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (mChannelChild) {
|
||||
RefPtr<HttpChannelChild> channelChild = mChannelChild.forget();
|
||||
channelChild->OnBackgroundChildDestroyed();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
|
|
|
@ -15,12 +15,26 @@ using mozilla::ipc::IPCResult;
|
|||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
class HttpChannelChild;
|
||||
|
||||
class HttpBackgroundChannelChild final : public PHttpBackgroundChannelChild
|
||||
{
|
||||
friend class BackgroundChannelCreateCallback;
|
||||
public:
|
||||
explicit HttpBackgroundChannelChild();
|
||||
|
||||
virtual ~HttpBackgroundChannelChild();
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(HttpBackgroundChannelChild)
|
||||
|
||||
// Associate this background channel with a HttpChannelChild and
|
||||
// initiate the createion of the PBackground IPC channel.
|
||||
nsresult Init(HttpChannelChild* aChannelChild);
|
||||
|
||||
// Callback while the associated HttpChannelChild is not going to
|
||||
// handle any incoming messages over background channel.
|
||||
void OnChannelClosed();
|
||||
|
||||
// Callback while failed to create PBackground IPC channel.
|
||||
void OnBackgroundChannelCreationFailed();
|
||||
|
||||
protected:
|
||||
IPCResult RecvOnTransportAndData(const nsresult& aChannelStatus,
|
||||
|
@ -44,6 +58,19 @@ protected:
|
|||
IPCResult RecvOnStartRequestSent() override;
|
||||
|
||||
void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
private:
|
||||
virtual ~HttpBackgroundChannelChild();
|
||||
|
||||
// Initiate the creation of the PBckground IPC channel.
|
||||
// Return false if failed.
|
||||
bool CreateBackgroundChannel();
|
||||
|
||||
// Associated HttpChannelChild for handling the channel events.
|
||||
// Will be removed while failed to create background channel,
|
||||
// destruction of the background channel, or explicitly dissociation
|
||||
// via OnChannelClosed callback.
|
||||
RefPtr<HttpChannelChild> mChannelChild;
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
|
|
|
@ -5,24 +5,159 @@
|
|||
* 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/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 {
|
||||
|
||||
HttpBackgroundChannelParent::HttpBackgroundChannelParent()
|
||||
/*
|
||||
* Helper class for continuing the AsyncOpen procedure on main thread.
|
||||
*/
|
||||
class ContinueAsyncOpenRunnable final : public Runnable
|
||||
{
|
||||
public:
|
||||
ContinueAsyncOpenRunnable(HttpBackgroundChannelParent* aActor,
|
||||
const uint64_t& aChannelId)
|
||||
: 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)
|
||||
, mBackgroundThread(NS_GetCurrentThread())
|
||||
{
|
||||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
}
|
||||
|
||||
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());
|
||||
|
||||
MOZ_DIAGNOSTIC_ASSERT(mIPCOpened);
|
||||
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;
|
||||
|
||||
RefPtr<HttpBackgroundChannelParent> self = this;
|
||||
rv = mBackgroundThread->Dispatch(NS_NewRunnableFunction([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));
|
||||
}
|
||||
|
||||
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([self]() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
RefPtr<HttpChannelParent> channelParent =
|
||||
self->mChannelParent.forget();
|
||||
|
||||
if (channelParent) {
|
||||
channelParent->OnBackgroundParentDestroyed();
|
||||
}
|
||||
}));
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
|
|
|
@ -9,19 +9,48 @@
|
|||
#define mozilla_net_HttpBackgroundChannelParent_h
|
||||
|
||||
#include "mozilla/net/PHttpBackgroundChannelParent.h"
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "nsID.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
|
||||
class nsIEventTarget;
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
class HttpChannelParent;
|
||||
|
||||
class HttpBackgroundChannelParent final : public PHttpBackgroundChannelParent
|
||||
{
|
||||
public:
|
||||
explicit HttpBackgroundChannelParent();
|
||||
|
||||
virtual ~HttpBackgroundChannelParent();
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(HttpBackgroundChannelParent)
|
||||
|
||||
// Try to find associated HttpChannelParent with the same
|
||||
// channel Id.
|
||||
nsresult Init(const uint64_t& aChannelId);
|
||||
|
||||
// Callbacks for BackgroundChannelRegistrar to notify
|
||||
// the associated HttpChannelParent is found.
|
||||
void LinkToChannel(HttpChannelParent* aChannelParent);
|
||||
|
||||
// Callbacks for HttpChannelParent to close the background
|
||||
// IPC channel.
|
||||
void OnChannelClosed();
|
||||
|
||||
protected:
|
||||
void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
private:
|
||||
virtual ~HttpBackgroundChannelParent();
|
||||
|
||||
Atomic<bool> mIPCOpened;
|
||||
|
||||
nsCOMPtr<nsIEventTarget> mBackgroundThread;
|
||||
|
||||
// associated HttpChannelParent for generating the channel events
|
||||
RefPtr<HttpChannelParent> mChannelParent;
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
|
|
|
@ -364,6 +364,11 @@ public: /* Necko internal use only... */
|
|||
mIsTrackingResource = true;
|
||||
}
|
||||
|
||||
const uint64_t& ChannelId() const
|
||||
{
|
||||
return mChannelId;
|
||||
}
|
||||
|
||||
protected:
|
||||
// Handle notifying listener, removing from loadgroup if request failed.
|
||||
void DoNotifyListener();
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "mozilla/net/HttpChannelChild.h"
|
||||
|
||||
#include "AltDataOutputStreamChild.h"
|
||||
#include "HttpBackgroundChannelChild.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsChannelClassifier.h"
|
||||
|
@ -272,6 +273,26 @@ HttpChannelChild::ReleaseIPDLReference()
|
|||
Release();
|
||||
}
|
||||
|
||||
void
|
||||
HttpChannelChild::OnBackgroundChildReady(HttpBackgroundChannelChild* aBgChild)
|
||||
{
|
||||
LOG(("HttpChannelChild::OnBackgroundChildReady [this=%p, bgChild=%p]\n",
|
||||
this, aBgChild));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mBgChild);
|
||||
|
||||
MOZ_ASSERT(mBgChild == aBgChild);
|
||||
}
|
||||
|
||||
void
|
||||
HttpChannelChild::OnBackgroundChildDestroyed()
|
||||
{
|
||||
LOG(("HttpChannelChild::OnBackgroundChildDestroyed [this=%p]\n", this));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mBgChild = nullptr;
|
||||
}
|
||||
|
||||
class AssociateApplicationCacheEvent : public ChannelEvent
|
||||
{
|
||||
public:
|
||||
|
@ -1030,6 +1051,8 @@ HttpChannelChild::OnStopRequest(const nsresult& channelStatus,
|
|||
// DoOnStopRequest() calls ReleaseListeners()
|
||||
}
|
||||
|
||||
CleanupBackgroundChannel();
|
||||
|
||||
// DocumentChannelCleanup actually nulls out mCacheEntry in the parent, which
|
||||
// we might need later to open the Alt-Data output stream, so just return here
|
||||
if (!mPreferredCachedAltDataType.IsEmpty()) {
|
||||
|
@ -1252,6 +1275,9 @@ void
|
|||
HttpChannelChild::HandleAsyncAbort()
|
||||
{
|
||||
HttpAsyncAborter<HttpChannelChild>::HandleAsyncAbort();
|
||||
|
||||
// Ignore all the messages from background channel after channel aborted.
|
||||
CleanupBackgroundChannel();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1259,6 +1285,14 @@ HttpChannelChild::FailedAsyncOpen(const nsresult& status)
|
|||
{
|
||||
LOG(("HttpChannelChild::FailedAsyncOpen [this=%p status=%" PRIx32 "]\n",
|
||||
this, static_cast<uint32_t>(status)));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// Might be called twice in race condition in theory.
|
||||
// (one by RecvFailedAsyncOpen, another by
|
||||
// HttpBackgroundChannelChild::ActorFailed)
|
||||
if (NS_WARN_IF(NS_FAILED(mStatus))) {
|
||||
return;
|
||||
}
|
||||
|
||||
mStatus = status;
|
||||
|
||||
|
@ -1270,6 +1304,27 @@ HttpChannelChild::FailedAsyncOpen(const nsresult& status)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
HttpChannelChild::CleanupBackgroundChannel()
|
||||
{
|
||||
LOG(("HttpChannelChild::CleanupBackgroundChannel [this=%p]\n", this));
|
||||
|
||||
if (!mBgChild) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<HttpBackgroundChannelChild> bgChild = mBgChild.forget();
|
||||
|
||||
if (!NS_IsMainThread()) {
|
||||
SystemGroup::Dispatch(
|
||||
"HttpChannelChild::CleanupBackgroundChannel",
|
||||
TaskCategory::Other,
|
||||
NewRunnableMethod(bgChild, &HttpBackgroundChannelChild::OnChannelClosed));
|
||||
} else {
|
||||
bgChild->OnChannelClosed();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HttpChannelChild::DoNotifyListenerCleanup()
|
||||
{
|
||||
|
@ -1835,6 +1890,20 @@ HttpChannelChild::ConnectParent(uint32_t registrarId)
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
{
|
||||
MOZ_ASSERT(!mBgChild);
|
||||
|
||||
RefPtr<HttpBackgroundChannelChild> bgChild =
|
||||
new HttpBackgroundChannelChild();
|
||||
|
||||
nsresult rv = bgChild->Init(this);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
mBgChild = bgChild.forget();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -2463,6 +2532,26 @@ HttpChannelChild::ContinueAsyncOpen()
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
{
|
||||
// Service worker might use the same HttpChannelChild to do async open
|
||||
// twice. Need to disconnect with previous background channel before
|
||||
// creating the new one.
|
||||
if (mBgChild) {
|
||||
RefPtr<HttpBackgroundChannelChild> prevBgChild = mBgChild.forget();
|
||||
prevBgChild->OnChannelClosed();
|
||||
}
|
||||
|
||||
RefPtr<HttpBackgroundChannelChild> bgChild =
|
||||
new HttpBackgroundChannelChild();
|
||||
|
||||
rv = bgChild->Init(this);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
mBgChild = bgChild.forget();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ class nsInputStreamPump;
|
|||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
class HttpBackgroundChannelChild;
|
||||
class InterceptedChannelContent;
|
||||
class InterceptStreamListener;
|
||||
|
||||
|
@ -117,6 +118,11 @@ public:
|
|||
|
||||
void OnCopyComplete(nsresult aStatus) override;
|
||||
|
||||
// Callback while background channel is ready.
|
||||
void OnBackgroundChildReady(HttpBackgroundChannelChild* aBgChild);
|
||||
// Callback while background channel is destroyed.
|
||||
void OnBackgroundChildDestroyed();
|
||||
|
||||
protected:
|
||||
mozilla::ipc::IPCResult RecvOnStartRequest(const nsresult& channelStatus,
|
||||
const nsHttpResponseHead& responseHead,
|
||||
|
@ -312,6 +318,12 @@ private:
|
|||
// is synthesized.
|
||||
bool mSuspendParentAfterSynthesizeResponse;
|
||||
|
||||
RefPtr<HttpBackgroundChannelChild> mBgChild;
|
||||
|
||||
// Remove the association with background channel after OnStopRequest
|
||||
// or AsyncAbort.
|
||||
void CleanupBackgroundChannel();
|
||||
|
||||
// Needed to call AsyncOpen in FinishInterceptedRedirect
|
||||
nsCOMPtr<nsIStreamListener> mInterceptedRedirectListener;
|
||||
nsCOMPtr<nsISupports> mInterceptedRedirectContext;
|
||||
|
@ -403,6 +415,7 @@ private:
|
|||
friend class HttpAsyncAborter<HttpChannelChild>;
|
||||
friend class InterceptStreamListener;
|
||||
friend class InterceptedChannelContent;
|
||||
friend class HttpBackgroundChannelChild;
|
||||
};
|
||||
|
||||
// A stream listener interposed between the nsInputStreamPump used for intercepted channels
|
||||
|
|
|
@ -10,16 +10,21 @@
|
|||
#include "mozilla/ipc/FileDescriptorSetParent.h"
|
||||
#include "mozilla/ipc/IPCStreamUtils.h"
|
||||
#include "mozilla/net/HttpChannelParent.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/TabParent.h"
|
||||
#include "mozilla/net/NeckoParent.h"
|
||||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "HttpBackgroundChannelParent.h"
|
||||
#include "HttpChannelParentListener.h"
|
||||
#include "nsHttpHandler.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsISupportsPriority.h"
|
||||
#include "nsIAuthPromptProvider.h"
|
||||
#include "nsIBackgroundChannelRegistrar.h"
|
||||
#include "nsSerializationHelper.h"
|
||||
#include "nsISerializable.h"
|
||||
#include "nsIAssociatedContentSecurity.h"
|
||||
|
@ -38,6 +43,7 @@
|
|||
#include "nsCORSListenerProxy.h"
|
||||
#include "nsIIPCSerializableInputStream.h"
|
||||
#include "nsIPrompt.h"
|
||||
#include "nsIRedirectChannelRegistrar.h"
|
||||
#include "nsIWindowWatcher.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsStreamUtils.h"
|
||||
|
@ -45,7 +51,6 @@
|
|||
#include "nsIStorageStream.h"
|
||||
#include "nsQueryObject.h"
|
||||
#include "nsIURIClassifier.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
|
||||
using mozilla::BasePrincipal;
|
||||
using namespace mozilla::dom;
|
||||
|
@ -59,7 +64,6 @@ HttpChannelParent::HttpChannelParent(const PBrowserOrId& iframeEmbedding,
|
|||
PBOverrideStatus aOverrideStatus)
|
||||
: mIPCClosed(false)
|
||||
, mIgnoreProgress(false)
|
||||
, mSentRedirect1Begin(false)
|
||||
, mSentRedirect1BeginFailed(false)
|
||||
, mReceivedRedirect2Verify(false)
|
||||
, mPBOverride(aOverrideStatus)
|
||||
|
@ -94,6 +98,7 @@ HttpChannelParent::HttpChannelParent(const PBrowserOrId& iframeEmbedding,
|
|||
HttpChannelParent::~HttpChannelParent()
|
||||
{
|
||||
LOG(("Destroying HttpChannelParent [this=%p]\n", this));
|
||||
CleanupBackgroundChannel();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -109,6 +114,8 @@ HttpChannelParent::ActorDestroy(ActorDestroyReason why)
|
|||
if (mParentListener) {
|
||||
mParentListener->ClearInterceptedChannel();
|
||||
}
|
||||
|
||||
CleanupBackgroundChannel();
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -154,6 +161,101 @@ HttpChannelParent::Init(const HttpChannelCreationArgs& aArgs)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
HttpChannelParent::TryInvokeAsyncOpen(nsresult aRv)
|
||||
{
|
||||
LOG(("HttpChannelParent::TryInvokeAsyncOpen [this=%p barrier=%u rv=%" PRIx32
|
||||
"]\n", this, mAsyncOpenBarrier, static_cast<uint32_t>(aRv)));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// TryInvokeAsyncOpen is called more than we expected.
|
||||
// Assert in nightly build but ignore it in release channel.
|
||||
MOZ_DIAGNOSTIC_ASSERT(mAsyncOpenBarrier > 0);
|
||||
if (NS_WARN_IF(!mAsyncOpenBarrier)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (--mAsyncOpenBarrier > 0 && NS_SUCCEEDED(aRv)) {
|
||||
// Need to wait for more events.
|
||||
return;
|
||||
}
|
||||
|
||||
InvokeAsyncOpen(aRv);
|
||||
}
|
||||
|
||||
void
|
||||
HttpChannelParent::OnBackgroundParentReady(
|
||||
HttpBackgroundChannelParent* aBgParent)
|
||||
{
|
||||
LOG(("HttpChannelParent::OnBackgroundParentReady [this=%p bgParent=%p]\n",
|
||||
this, aBgParent));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!mBgParent);
|
||||
|
||||
mBgParent = aBgParent;
|
||||
|
||||
mPromise.ResolveIfExists(true, __func__);
|
||||
}
|
||||
|
||||
void
|
||||
HttpChannelParent::OnBackgroundParentDestroyed()
|
||||
{
|
||||
LOG(("HttpChannelParent::OnBackgroundParentDestroyed [this=%p]\n", this));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!mPromise.IsEmpty()) {
|
||||
MOZ_ASSERT(!mBgParent);
|
||||
mPromise.Reject(NS_ERROR_FAILURE, __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mBgParent) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Background channel is closed unexpectly, abort PHttpChannel operation.
|
||||
mBgParent = nullptr;
|
||||
Delete();
|
||||
}
|
||||
|
||||
void
|
||||
HttpChannelParent::CleanupBackgroundChannel()
|
||||
{
|
||||
LOG(("HttpChannelParent::CleanupBackgroundChannel [this=%p bgParent=%p]\n",
|
||||
this, mBgParent.get()));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (mBgParent) {
|
||||
RefPtr<HttpBackgroundChannelParent> bgParent = mBgParent.forget();
|
||||
bgParent->OnChannelClosed();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mPromise.IsEmpty()) {
|
||||
mRequest.DisconnectIfExists();
|
||||
mPromise.Reject(NS_ERROR_FAILURE, __func__);
|
||||
|
||||
if (!mChannel) {
|
||||
return;
|
||||
}
|
||||
|
||||
// This HttpChannelParent might still have a reference from
|
||||
// BackgroundChannelRegistrar.
|
||||
nsCOMPtr<nsIBackgroundChannelRegistrar> registrar =
|
||||
do_GetService(NS_BACKGROUNDCHANNELREGISTRAR_CONTRACTID);
|
||||
MOZ_ASSERT(registrar);
|
||||
|
||||
registrar->DeleteChannel(mChannel->ChannelId());
|
||||
|
||||
// If mAsyncOpenBarrier is greater than zero, it means AsyncOpen procedure
|
||||
// is still on going. we need to abort AsyncOpen with failure to destroy
|
||||
// PHttpChannel actor.
|
||||
if (mAsyncOpenBarrier) {
|
||||
TryInvokeAsyncOpen(NS_ERROR_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// HttpChannelParent::nsISupports
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -169,6 +271,7 @@ NS_INTERFACE_MAP_BEGIN(HttpChannelParent)
|
|||
NS_INTERFACE_MAP_ENTRY(nsIAuthPromptProvider)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIParentRedirectingChannel)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDeprecationWarner)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIAsyncVerifyRedirectReadyCallback)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIParentRedirectingChannel)
|
||||
if (aIID.Equals(NS_GET_IID(HttpChannelParent))) {
|
||||
foundInterface = static_cast<nsIInterfaceRequestor*>(this);
|
||||
|
@ -254,6 +357,10 @@ HttpChannelParent::AsyncOpenFailed(nsresult aRv)
|
|||
void
|
||||
HttpChannelParent::InvokeAsyncOpen(nsresult rv)
|
||||
{
|
||||
LOG(("HttpChannelParent::InvokeAsyncOpen [this=%p rv=%" PRIx32 "]\n",
|
||||
this, static_cast<uint32_t>(rv)));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
AsyncOpenFailed(rv);
|
||||
return;
|
||||
|
@ -292,7 +399,7 @@ public:
|
|||
NS_IMETHOD Run()
|
||||
{
|
||||
RefPtr<HttpChannelParent> channel = do_QueryObject(mChannel.get());
|
||||
channel->InvokeAsyncOpen(mStatus);
|
||||
channel->TryInvokeAsyncOpen(mStatus);
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
@ -459,7 +566,6 @@ HttpChannelParent::DoAsyncOpen( const URIParams& aURI,
|
|||
httpChannel->SetCorsPreflightParameters(args.unsafeHeaders());
|
||||
}
|
||||
|
||||
bool delayAsyncOpen = false;
|
||||
nsCOMPtr<nsIInputStream> stream = DeserializeIPCStream(uploadStream);
|
||||
if (stream) {
|
||||
// FIXME: The fast path of using the existing stream currently only applies to streams
|
||||
|
@ -467,7 +573,8 @@ HttpChannelParent::DoAsyncOpen( const URIParams& aURI,
|
|||
// Once bug 1294446 and bug 1294450 are fixed it is worth revisiting this heuristic.
|
||||
nsCOMPtr<nsIIPCSerializableInputStream> completeStream = do_QueryInterface(stream);
|
||||
if (!completeStream) {
|
||||
delayAsyncOpen = true;
|
||||
// Wait for completion of async copying IPC upload stream to a local input stream.
|
||||
++mAsyncOpenBarrier;
|
||||
|
||||
// buffer size matches PChildToParentStream transfer size.
|
||||
const uint32_t kBufferSize = 32768;
|
||||
|
@ -626,13 +733,49 @@ HttpChannelParent::DoAsyncOpen( const URIParams& aURI,
|
|||
|
||||
mSuspendAfterSynthesizeResponse = aSuspendAfterSynthesizeResponse;
|
||||
|
||||
if (!delayAsyncOpen) {
|
||||
InvokeAsyncOpen(NS_OK);
|
||||
}
|
||||
MOZ_ASSERT(!mBgParent);
|
||||
MOZ_ASSERT(mPromise.IsEmpty());
|
||||
// Wait for HttpBackgrounChannel to continue the async open procedure.
|
||||
++mAsyncOpenBarrier;
|
||||
RefPtr<GenericPromise> promise = WaitForBgParent();
|
||||
RefPtr<HttpChannelParent> self = this;
|
||||
promise->Then(AbstractThread::MainThread(), __func__,
|
||||
[self]() {
|
||||
self->mRequest.Complete();
|
||||
self->TryInvokeAsyncOpen(NS_OK);
|
||||
},
|
||||
[self](nsresult aStatus) {
|
||||
self->mRequest.Complete();
|
||||
self->TryInvokeAsyncOpen(aStatus);
|
||||
})
|
||||
->Track(mRequest);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
already_AddRefed<GenericPromise>
|
||||
HttpChannelParent::WaitForBgParent()
|
||||
{
|
||||
LOG(("HttpChannelParent::WaitForBgParent [this=%p]\n", this));
|
||||
MOZ_ASSERT(!mBgParent);
|
||||
MOZ_ASSERT(mChannel);
|
||||
|
||||
|
||||
nsCOMPtr<nsIBackgroundChannelRegistrar> registrar =
|
||||
do_GetService(NS_BACKGROUNDCHANNELREGISTRAR_CONTRACTID);
|
||||
MOZ_ASSERT(registrar);
|
||||
registrar->LinkHttpChannel(mChannel->ChannelId(), this);
|
||||
|
||||
if (mBgParent) {
|
||||
already_AddRefed<GenericPromise> promise = mPromise.Ensure(__func__);
|
||||
// resolve promise immediatedly if bg channel is ready.
|
||||
mPromise.Resolve(true, __func__);
|
||||
return promise;
|
||||
}
|
||||
|
||||
return mPromise.Ensure(__func__);;
|
||||
}
|
||||
|
||||
bool
|
||||
HttpChannelParent::ConnectChannel(const uint32_t& registrarId, const bool& shouldIntercept)
|
||||
{
|
||||
|
@ -673,6 +816,20 @@ HttpChannelParent::ConnectChannel(const uint32_t& registrarId, const bool& shoul
|
|||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!mBgParent);
|
||||
MOZ_ASSERT(mPromise.IsEmpty());
|
||||
// Waiting for background channel
|
||||
RefPtr<GenericPromise> promise = WaitForBgParent();
|
||||
RefPtr<HttpChannelParent> self = this;
|
||||
promise->Then(AbstractThread::MainThread(), __func__,
|
||||
[self]() {
|
||||
self->mRequest.Complete();
|
||||
},
|
||||
[self](const nsresult& aResult) {
|
||||
NS_ERROR("failed to establish the background channel");
|
||||
self->mRequest.Complete();
|
||||
})
|
||||
->Track(mRequest);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -829,15 +986,89 @@ HttpChannelParent::RecvRedirect2Verify(const nsresult& result,
|
|||
}
|
||||
}
|
||||
|
||||
// Continue the verification procedure if child has veto the redirection.
|
||||
if (NS_FAILED(result)) {
|
||||
ContinueRedirect2Verify(result);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
// Wait for background channel ready on target channel
|
||||
nsCOMPtr<nsIRedirectChannelRegistrar> redirectReg =
|
||||
do_GetService(NS_REDIRECTCHANNELREGISTRAR_CONTRACTID);
|
||||
MOZ_ASSERT(redirectReg);
|
||||
|
||||
nsCOMPtr<nsIParentChannel> redirectParentChannel;
|
||||
rv = redirectReg->GetParentChannel(mRedirectRegistrarId,
|
||||
getter_AddRefs(redirectParentChannel));
|
||||
MOZ_ASSERT(redirectParentChannel);
|
||||
if (!redirectParentChannel) {
|
||||
ContinueRedirect2Verify(rv);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIParentRedirectingChannel> redirectedParent =
|
||||
do_QueryInterface(redirectParentChannel);
|
||||
if (!redirectedParent) {
|
||||
// Continue verification procedure if redirecting to non-Http protocol
|
||||
ContinueRedirect2Verify(result);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
// Ask redirected channel if verification can proceed.
|
||||
// ContinueRedirect2Verify will be invoked when redirected channel is ready.
|
||||
redirectedParent->ContinueVerification(this);
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
// from nsIParentRedirectingChannel
|
||||
NS_IMETHODIMP
|
||||
HttpChannelParent::ContinueVerification(nsIAsyncVerifyRedirectReadyCallback* aCallback)
|
||||
{
|
||||
LOG(("HttpChannelParent::ContinueVerification [this=%p callback=%p]\n",
|
||||
this, aCallback));
|
||||
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aCallback);
|
||||
|
||||
// Continue the verification procedure if background channel is ready.
|
||||
if (mBgParent) {
|
||||
aCallback->ReadyToVerify(NS_OK);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// ConnectChannel must be received before Redirect2Verify.
|
||||
MOZ_ASSERT(!mPromise.IsEmpty());
|
||||
|
||||
// Otherwise, wait for the background channel.
|
||||
RefPtr<GenericPromise> promise = WaitForBgParent();
|
||||
nsCOMPtr<nsIAsyncVerifyRedirectReadyCallback> callback = aCallback;
|
||||
promise->Then(AbstractThread::MainThread(), __func__,
|
||||
[callback]() {
|
||||
callback->ReadyToVerify(NS_OK);
|
||||
},
|
||||
[callback](const nsresult& aResult) {
|
||||
NS_ERROR("failed to establish the background channel");
|
||||
callback->ReadyToVerify(aResult);
|
||||
});
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
HttpChannelParent::ContinueRedirect2Verify(const nsresult& aResult)
|
||||
{
|
||||
LOG(("HttpChannelParent::ContinueRedirect2Verify [this=%p result=%" PRIx32 "]\n",
|
||||
this, static_cast<uint32_t>(aResult)));
|
||||
|
||||
if (!mRedirectCallback) {
|
||||
// This should according the logic never happen, log the situation.
|
||||
if (mReceivedRedirect2Verify)
|
||||
LOG(("RecvRedirect2Verify[%p]: Duplicate fire", this));
|
||||
if (mSentRedirect1BeginFailed)
|
||||
LOG(("RecvRedirect2Verify[%p]: Send to child failed", this));
|
||||
if (mSentRedirect1Begin && NS_FAILED(result))
|
||||
if ((mRedirectRegistrarId > 0) && NS_FAILED(aResult))
|
||||
LOG(("RecvRedirect2Verify[%p]: Redirect failed", this));
|
||||
if (mSentRedirect1Begin && NS_SUCCEEDED(result))
|
||||
if ((mRedirectRegistrarId > 0) && NS_SUCCEEDED(aResult))
|
||||
LOG(("RecvRedirect2Verify[%p]: Redirect succeeded", this));
|
||||
if (!mRedirectChannel)
|
||||
LOG(("RecvRedirect2Verify[%p]: Missing redirect channel", this));
|
||||
|
@ -849,20 +1080,19 @@ HttpChannelParent::RecvRedirect2Verify(const nsresult& result,
|
|||
mReceivedRedirect2Verify = true;
|
||||
|
||||
if (mRedirectCallback) {
|
||||
LOG(("HttpChannelParent::RecvRedirect2Verify call OnRedirectVerifyCallback"
|
||||
LOG(("HttpChannelParent::ContinueRedirect2Verify call OnRedirectVerifyCallback"
|
||||
" [this=%p result=%" PRIx32 ", mRedirectCallback=%p]\n",
|
||||
this, static_cast<uint32_t>(result), mRedirectCallback.get()));
|
||||
mRedirectCallback->OnRedirectVerifyCallback(result);
|
||||
this, static_cast<uint32_t>(aResult), mRedirectCallback.get()));
|
||||
mRedirectCallback->OnRedirectVerifyCallback(aResult);
|
||||
mRedirectCallback = nullptr;
|
||||
}
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
HttpChannelParent::RecvDocumentChannelCleanup()
|
||||
{
|
||||
// From now on only using mAssociatedContentSecurity. Free everything else.
|
||||
CleanupBackgroundChannel(); // Background channel can be closed.
|
||||
mChannel = nullptr; // Reclaim some memory sooner.
|
||||
mCacheEntry = nullptr; // Else we'll block other channels reading same URI
|
||||
return IPC_OK();
|
||||
|
@ -1297,6 +1527,7 @@ HttpChannelParent::OnStopRequest(nsIRequest *aRequest,
|
|||
|
||||
if (mIPCClosed || !SendOnStopRequest(aStatusCode, timing))
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1513,7 +1744,9 @@ HttpChannelParent::StartRedirect(uint32_t registrarId,
|
|||
}
|
||||
|
||||
// Bug 621446 investigation
|
||||
mSentRedirect1Begin = true;
|
||||
// Store registrar Id of the new channel to find the redirect
|
||||
// HttpChannelParent later in verification phase.
|
||||
mRedirectRegistrarId = registrarId;
|
||||
|
||||
// Result is handled in RecvRedirect2Verify above
|
||||
|
||||
|
@ -1815,12 +2048,16 @@ HttpChannelParent::NotifyDiversionFailed(nsresult aErrorCode,
|
|||
if (!isPending) {
|
||||
mParentListener->OnStopRequest(mChannel, nullptr, aErrorCode);
|
||||
}
|
||||
mParentListener = nullptr;
|
||||
mChannel = nullptr;
|
||||
|
||||
if (!mIPCClosed) {
|
||||
Unused << DoSendDeleteSelf();
|
||||
}
|
||||
|
||||
// DoSendDeleteSelf will need channel Id to remove the strong reference in
|
||||
// BackgroundChannelRegistrar if channel pairing is aborted.
|
||||
// Thus we need to keep mChannel until DoSendDeleteSelf is done.
|
||||
mParentListener = nullptr;
|
||||
mChannel = nullptr;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -1863,6 +2100,9 @@ HttpChannelParent::DoSendDeleteSelf()
|
|||
{
|
||||
bool rv = SendDeleteSelf();
|
||||
mIPCClosed = true;
|
||||
|
||||
CleanupBackgroundChannel();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -1913,6 +2153,22 @@ HttpChannelParent::IssueWarning(uint32_t aWarning, bool aAsError)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsIAsyncVerifyRedirectReadyCallback
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
HttpChannelParent::ReadyToVerify(nsresult aResult)
|
||||
{
|
||||
LOG(("HttpChannelParent::RecvRedirect2Verify [this=%p result=%" PRIx32 "]\n",
|
||||
this, static_cast<uint32_t>(aResult)));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
ContinueRedirect2Verify(aResult);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
HttpChannelParent::DoSendSetPriority(int16_t aValue)
|
||||
{
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "mozilla/net/PHttpChannelParent.h"
|
||||
#include "mozilla/net/NeckoCommon.h"
|
||||
#include "mozilla/net/NeckoParent.h"
|
||||
#include "mozilla/MozPromise.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIParentRedirectingChannel.h"
|
||||
#include "nsIProgressEventSink.h"
|
||||
|
@ -37,6 +38,7 @@ class PBrowserOrId;
|
|||
|
||||
namespace net {
|
||||
|
||||
class HttpBackgroundChannelParent;
|
||||
class HttpChannelParentListener;
|
||||
class ChannelEventQueue;
|
||||
|
||||
|
@ -52,6 +54,7 @@ class HttpChannelParent final : public nsIInterfaceRequestor
|
|||
, public nsIAuthPromptProvider
|
||||
, public nsIDeprecationWarner
|
||||
, public HttpChannelSecurityWarningReporter
|
||||
, public nsIAsyncVerifyRedirectReadyCallback
|
||||
{
|
||||
virtual ~HttpChannelParent();
|
||||
|
||||
|
@ -65,6 +68,7 @@ public:
|
|||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
NS_DECL_NSIAUTHPROMPTPROVIDER
|
||||
NS_DECL_NSIDEPRECATIONWARNER
|
||||
NS_DECL_NSIASYNCVERIFYREDIRECTREADYCALLBACK
|
||||
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(HTTP_CHANNEL_PARENT_IID)
|
||||
|
||||
|
@ -99,10 +103,22 @@ public:
|
|||
MOZ_MUST_USE nsresult OpenAlternativeOutputStream(const nsACString & type,
|
||||
nsIOutputStream * *_retval);
|
||||
|
||||
// Callbacks for each asynchronous tasks required in AsyncOpen
|
||||
// procedure, will call InvokeAsyncOpen when all the expected
|
||||
// tasks is finished successfully or when any failure happened.
|
||||
// @see mAsyncOpenBarrier.
|
||||
void TryInvokeAsyncOpen(nsresult aRv);
|
||||
|
||||
void InvokeAsyncOpen(nsresult rv);
|
||||
|
||||
// Calls SendSetPriority if mIPCClosed is false.
|
||||
void DoSendSetPriority(int16_t aValue);
|
||||
|
||||
// Callback while background channel is ready.
|
||||
void OnBackgroundParentReady(HttpBackgroundChannelParent* aBgParent);
|
||||
// Callback while background channel is destroyed.
|
||||
void OnBackgroundParentDestroyed();
|
||||
|
||||
protected:
|
||||
// used to connect redirected-to channel in parent with just created
|
||||
// ChildChannel. Used during redirects.
|
||||
|
@ -217,8 +233,26 @@ private:
|
|||
void MaybeFlushPendingDiversion();
|
||||
void ResponseSynthesized();
|
||||
|
||||
// final step for Redirect2Verify procedure, will be invoked while both
|
||||
// redirecting and redirected channel are ready or any error happened.
|
||||
// OnRedirectVerifyCallback will be invoked for finishing the async
|
||||
// redirect verification procedure.
|
||||
void ContinueRedirect2Verify(const nsresult& aResult);
|
||||
|
||||
void AsyncOpenFailed(nsresult aRv);
|
||||
|
||||
// Request to pair with a HttpBackgroundChannelParent with the same channel
|
||||
// id, a promise will be returned so the caller can append callbacks on it.
|
||||
// If called multiple times before mBgParent is available, the same promise
|
||||
// will be returned and the callbacks will be invoked in order.
|
||||
already_AddRefed<GenericPromise> WaitForBgParent();
|
||||
|
||||
// Remove the association with background channel after main-thread IPC
|
||||
// is about to be destroyed or no further event is going to be sent, i.e.,
|
||||
// DocumentChannelCleanup.
|
||||
void CleanupBackgroundChannel();
|
||||
|
||||
friend class HttpBackgroundChannelParent;
|
||||
friend class DivertDataAvailableEvent;
|
||||
friend class DivertStopRequestEvent;
|
||||
friend class DivertCompleteEvent;
|
||||
|
@ -238,7 +272,6 @@ private:
|
|||
// since the information can be recontructed from ODA.
|
||||
bool mIgnoreProgress : 1;
|
||||
|
||||
bool mSentRedirect1Begin : 1;
|
||||
bool mSentRedirect1BeginFailed : 1;
|
||||
bool mReceivedRedirect2Verify : 1;
|
||||
|
||||
|
@ -274,6 +307,20 @@ private:
|
|||
dom::TabId mNestedFrameId;
|
||||
|
||||
RefPtr<ChannelEventQueue> mEventQ;
|
||||
|
||||
RefPtr<HttpBackgroundChannelParent> mBgParent;
|
||||
|
||||
// Number of events to wait before actually invoking AsyncOpen on the main
|
||||
// channel. For each asynchronous step required before InvokeAsyncOpen, should
|
||||
// increase 1 to mAsyncOpenBarrier and invoke TryInvokeAsyncOpen after
|
||||
// finished. This attribute is main thread only.
|
||||
uint8_t mAsyncOpenBarrier = 0;
|
||||
|
||||
// Corresponding redirect channel registrar Id. 0 means redirection is not started.
|
||||
uint32_t mRedirectRegistrarId = 0;
|
||||
|
||||
MozPromiseHolder<GenericPromise> mPromise;
|
||||
MozPromiseRequestHolder<GenericPromise> mRequest;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(HttpChannelParent,
|
||||
|
|
|
@ -8,6 +8,7 @@ with Files('**'):
|
|||
BUG_COMPONENT = ('Core', 'Networking: HTTP')
|
||||
|
||||
XPIDL_SOURCES += [
|
||||
'nsIBackgroundChannelRegistrar.idl',
|
||||
'nsIHstsPrimingCallback.idl',
|
||||
'nsIHttpActivityObserver.idl',
|
||||
'nsIHttpAuthenticableChannel.idl',
|
||||
|
@ -60,6 +61,7 @@ UNIFIED_SOURCES += [
|
|||
'AltDataOutputStreamParent.cpp',
|
||||
'AlternateServices.cpp',
|
||||
'ASpdySession.cpp',
|
||||
'BackgroundChannelRegistrar.cpp',
|
||||
'CacheControlParser.cpp',
|
||||
'ConnectionDiagnostics.cpp',
|
||||
'HSTSPrimerListener.cpp',
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 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 "nsISupports.idl"
|
||||
|
||||
%{ C++
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
class HttpBackgroundChannelParent;
|
||||
class HttpChannelParent;
|
||||
}
|
||||
}
|
||||
%}
|
||||
|
||||
[ptr] native HttpChannelParent(mozilla::net::HttpChannelParent);
|
||||
[ptr] native HttpBackgroundChannelParent(mozilla::net::HttpBackgroundChannelParent);
|
||||
|
||||
/*
|
||||
* Registrar for pairing HttpChannelParent and HttpBackgroundChannelParent via
|
||||
* channel Id. HttpChannelParent::OnBackgroundParentReady and
|
||||
* HttpBackgroundChannelParent::LinkToChannel will be invoked to notify the
|
||||
* existence of associated channel object.
|
||||
*/
|
||||
[builtinclass, uuid(8acaa9b1-f0c4-4ade-baeb-39b0d4b96e5b)]
|
||||
interface nsIBackgroundChannelRegistrar : nsISupports
|
||||
{
|
||||
/*
|
||||
* Link the provided channel parent actor with the given channel Id.
|
||||
* callbacks will be invoked immediately when the HttpBackgroundChannelParent
|
||||
* associated with the same channel Id is found. Store the HttpChannelParent
|
||||
* until a matched linkBackgroundChannel is invoked.
|
||||
*
|
||||
* @param aKey the channel Id
|
||||
* @param aChannel the channel parent actor to be paired
|
||||
*/
|
||||
[noscript,notxpcom,nostdcall] void linkHttpChannel(in uint64_t aKey,
|
||||
in HttpChannelParent aChannel);
|
||||
|
||||
/*
|
||||
* Link the provided background channel with the given channel Id.
|
||||
* callbacks will be invoked immediately when the HttpChannelParent associated
|
||||
* with the same channel Id is found. Store the HttpBackgroundChannelParent
|
||||
* until a matched linkHttpChannel is invoked.
|
||||
*
|
||||
* @param aKey the channel Id
|
||||
* @param aBgChannel the background channel to be paired
|
||||
*/
|
||||
[noscript,notxpcom,nostdcall] void linkBackgroundChannel(in uint64_t aKey,
|
||||
in HttpBackgroundChannelParent aBgChannel);
|
||||
|
||||
/*
|
||||
* Delete previous stored HttpChannelParent or HttpBackgroundChannelParent
|
||||
* if no need to wait for the paired channel object, e.g. background channel
|
||||
* is destroyed before pairing is completed.
|
||||
*
|
||||
* @param aKey the channel Id
|
||||
*/
|
||||
[noscript,notxpcom,nostdcall] void deleteChannel(in uint64_t aKey);
|
||||
|
||||
};
|
Загрузка…
Ссылка в новой задаче