зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1623380 - Send ODA directly to content process r=dragana
Differential Revision: https://phabricator.services.mozilla.com/D67609
This commit is contained in:
Родитель
92d967bf64
Коммит
467f6725fc
|
@ -8,6 +8,8 @@ include GMPTypes;
|
|||
|
||||
using cdm::HdcpVersion from "content_decryption_module.h";
|
||||
|
||||
include "GMPMessageUtils.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
#include "mozilla/ipc/PParentToChildStreamParent.h"
|
||||
#include "mozilla/layout/VsyncParent.h"
|
||||
#include "mozilla/net/HttpBackgroundChannelParent.h"
|
||||
#include "mozilla/net/BackgroundDataBridgeParent.h"
|
||||
#include "mozilla/dom/network/UDPSocketParent.h"
|
||||
#include "mozilla/dom/WebAuthnTransactionParent.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
|
@ -136,6 +137,17 @@ void BackgroundParentImpl::ActorDestroy(ActorDestroyReason aWhy) {
|
|||
AssertIsOnBackgroundThread();
|
||||
}
|
||||
|
||||
already_AddRefed<net::PBackgroundDataBridgeParent>
|
||||
BackgroundParentImpl::AllocPBackgroundDataBridgeParent(
|
||||
const uint64_t& aChannelID) {
|
||||
MOZ_ASSERT(XRE_IsSocketProcess(), "Should be in socket process");
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
RefPtr<net::BackgroundDataBridgeParent> actor =
|
||||
new net::BackgroundDataBridgeParent(aChannelID);
|
||||
return actor.forget();
|
||||
}
|
||||
|
||||
BackgroundParentImpl::PBackgroundTestParent*
|
||||
BackgroundParentImpl::AllocPBackgroundTestParent(const nsCString& aTestArg) {
|
||||
AssertIsInMainOrSocketProcess();
|
||||
|
|
|
@ -47,6 +47,9 @@ class BackgroundParentImpl : public PBackgroundParent,
|
|||
virtual already_AddRefed<PBackgroundIDBFactoryParent>
|
||||
AllocPBackgroundIDBFactoryParent(const LoggingInfo& aLoggingInfo) override;
|
||||
|
||||
virtual already_AddRefed<net::PBackgroundDataBridgeParent>
|
||||
AllocPBackgroundDataBridgeParent(const uint64_t& aChannelID) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvPBackgroundIDBFactoryConstructor(
|
||||
PBackgroundIDBFactoryParent* aActor,
|
||||
const LoggingInfo& aLoggingInfo) override;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* 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 protocol PBackgroundDataBridge;
|
||||
include protocol PBackgroundIDBFactory;
|
||||
include protocol PBackgroundIndexedDBUtils;
|
||||
include protocol PBackgroundSDBConnection;
|
||||
|
@ -72,6 +73,7 @@ namespace ipc {
|
|||
|
||||
sync protocol PBackground
|
||||
{
|
||||
manages PBackgroundDataBridge;
|
||||
manages PBackgroundIDBFactory;
|
||||
manages PBackgroundIndexedDBUtils;
|
||||
manages PBackgroundSDBConnection;
|
||||
|
@ -122,6 +124,8 @@ parent:
|
|||
// Only called at startup during mochitests to check the basic infrastructure.
|
||||
async PBackgroundTest(nsCString testArg);
|
||||
|
||||
async PBackgroundDataBridge(uint64_t channelID);
|
||||
|
||||
async PBackgroundIDBFactory(LoggingInfo loggingInfo);
|
||||
|
||||
async PBackgroundIndexedDBUtils();
|
||||
|
|
|
@ -7688,6 +7688,12 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
# Whether we can send OnDataAvailable to content process directly.
|
||||
- name: network.send_ODA_to_content_directly
|
||||
type: RelaxedAtomicBool
|
||||
value: true
|
||||
mirror: always
|
||||
|
||||
# Telemetry of traffic categories. Whether or not to enable HttpTrafficAnalyzer.
|
||||
- name: network.traffic_analyzer.enabled
|
||||
type: RelaxedAtomicBool
|
||||
|
|
|
@ -222,6 +222,7 @@ static const char* gCallbackPrefsForSocketProcess[] = {
|
|||
WEBRTC_PREF_PREFIX,
|
||||
NETWORK_DNS_PREF,
|
||||
"network.ssl_tokens_cache_enabled",
|
||||
"network.send_ODA_to_content_directly",
|
||||
nullptr,
|
||||
};
|
||||
|
||||
|
|
|
@ -14,10 +14,12 @@
|
|||
#include "mozilla/dom/MemoryReportRequest.h"
|
||||
#include "mozilla/ipc/CrashReporterClient.h"
|
||||
#include "mozilla/ipc/BackgroundChild.h"
|
||||
#include "mozilla/ipc/BackgroundParent.h"
|
||||
#include "mozilla/ipc/FileDescriptorSetChild.h"
|
||||
#include "mozilla/ipc/IPCStreamAlloc.h"
|
||||
#include "mozilla/ipc/ProcessChild.h"
|
||||
#include "mozilla/net/AltSvcTransactionChild.h"
|
||||
#include "mozilla/net/BackgroundDataBridgeParent.h"
|
||||
#include "mozilla/net/DNSRequestChild.h"
|
||||
#include "mozilla/net/DNSRequestParent.h"
|
||||
#include "mozilla/ipc/PChildToParentStreamChild.h"
|
||||
|
@ -58,7 +60,8 @@ using namespace ipc;
|
|||
|
||||
SocketProcessChild* sSocketProcessChild;
|
||||
|
||||
SocketProcessChild::SocketProcessChild() : mShuttingDown(false) {
|
||||
SocketProcessChild::SocketProcessChild()
|
||||
: mShuttingDown(false), mMutex("SocketProcessChild::mMutex") {
|
||||
LOG(("CONSTRUCT SocketProcessChild::SocketProcessChild\n"));
|
||||
nsDebugImpl::SetMultiprocessMode("Socket");
|
||||
|
||||
|
@ -381,5 +384,24 @@ mozilla::ipc::IPCResult SocketProcessChild::RecvPDNSRequestConstructor(
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
void SocketProcessChild::AddDataBridgeToMap(
|
||||
uint64_t aChannelId, BackgroundDataBridgeParent* aActor) {
|
||||
ipc::AssertIsOnBackgroundThread();
|
||||
MutexAutoLock lock(mMutex);
|
||||
mBackgroundDataBridgeMap.Put(aChannelId, aActor);
|
||||
}
|
||||
|
||||
void SocketProcessChild::RemoveDataBridgeFromMap(uint64_t aChannelId) {
|
||||
ipc::AssertIsOnBackgroundThread();
|
||||
MutexAutoLock lock(mMutex);
|
||||
mBackgroundDataBridgeMap.Remove(aChannelId);
|
||||
}
|
||||
|
||||
Maybe<RefPtr<BackgroundDataBridgeParent>>
|
||||
SocketProcessChild::GetAndRemoveDataBridge(uint64_t aChannelId) {
|
||||
MutexAutoLock lock(mMutex);
|
||||
return mBackgroundDataBridgeMap.GetAndRemove(aChannelId);
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "mozilla/net/PSocketProcessChild.h"
|
||||
#include "mozilla/ipc/InputStreamUtils.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -18,6 +19,7 @@ namespace mozilla {
|
|||
namespace net {
|
||||
|
||||
class SocketProcessBridgeParent;
|
||||
class BackgroundDataBridgeParent;
|
||||
|
||||
// The IPC actor implements PSocketProcessChild in child process.
|
||||
// This is allocated and kept alive by SocketProcessImpl.
|
||||
|
@ -96,6 +98,12 @@ class SocketProcessChild final
|
|||
const OriginAttributes& aOriginAttributes,
|
||||
const uint32_t& aFlags) override;
|
||||
|
||||
void AddDataBridgeToMap(uint64_t aChannelId,
|
||||
BackgroundDataBridgeParent* aActor);
|
||||
void RemoveDataBridgeFromMap(uint64_t aChannelId);
|
||||
Maybe<RefPtr<BackgroundDataBridgeParent>> GetAndRemoveDataBridge(
|
||||
uint64_t aChannelId);
|
||||
|
||||
protected:
|
||||
friend class SocketProcessImpl;
|
||||
~SocketProcessChild();
|
||||
|
@ -111,6 +119,10 @@ class SocketProcessChild final
|
|||
#endif
|
||||
|
||||
bool mShuttingDown;
|
||||
// Protect the table below.
|
||||
Mutex mMutex;
|
||||
nsDataHashtable<nsUint64HashKey, RefPtr<BackgroundDataBridgeParent>>
|
||||
mBackgroundDataBridgeMap;
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
/* 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 "mozilla/net/BackgroundDataBridgeChild.h"
|
||||
#include "mozilla/net/HttpBackgroundChannelChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
BackgroundDataBridgeChild::BackgroundDataBridgeChild(
|
||||
HttpBackgroundChannelChild* aBgChild)
|
||||
: mBgChild(aBgChild), mBackgroundThread(NS_GetCurrentThread()) {
|
||||
MOZ_ASSERT(aBgChild);
|
||||
}
|
||||
|
||||
BackgroundDataBridgeChild::~BackgroundDataBridgeChild() = default;
|
||||
|
||||
void BackgroundDataBridgeChild::Destroy() {
|
||||
RefPtr<BackgroundDataBridgeChild> self = this;
|
||||
MOZ_ALWAYS_SUCCEEDS(mBackgroundThread->Dispatch(
|
||||
NS_NewRunnableFunction("BackgroundDataBridgeParent::Destroy",
|
||||
[self]() {
|
||||
if (self->CanSend()) {
|
||||
Unused << self->Send__delete__(self);
|
||||
}
|
||||
}),
|
||||
NS_DISPATCH_NORMAL));
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult BackgroundDataBridgeChild::RecvOnTransportAndData(
|
||||
const uint64_t& offset, const uint32_t& count, const nsCString& data) {
|
||||
MOZ_ASSERT(mBgChild);
|
||||
return mBgChild->RecvOnTransportAndData(NS_OK, NS_NET_STATUS_RECEIVING_FROM,
|
||||
offset, count, data, true);
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,37 @@
|
|||
/* 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_BackgroundDataBridgeChild_h
|
||||
#define mozilla_net_BackgroundDataBridgeChild_h
|
||||
|
||||
#include "mozilla/net/PBackgroundDataBridgeChild.h"
|
||||
#include "mozilla/ipc/BackgroundChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
class HttpBackgroundChannelChild;
|
||||
|
||||
class BackgroundDataBridgeChild final : public PBackgroundDataBridgeChild {
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(BackgroundDataBridgeChild, override)
|
||||
|
||||
explicit BackgroundDataBridgeChild(HttpBackgroundChannelChild* aBgChild);
|
||||
void Destroy();
|
||||
|
||||
protected:
|
||||
virtual ~BackgroundDataBridgeChild();
|
||||
|
||||
RefPtr<HttpBackgroundChannelChild> mBgChild;
|
||||
nsCOMPtr<nsIThread> mBackgroundThread;
|
||||
|
||||
public:
|
||||
mozilla::ipc::IPCResult RecvOnTransportAndData(const uint64_t& offset,
|
||||
const uint32_t& count,
|
||||
const nsCString& data);
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_net_BackgroundDataBridgeChild_h
|
|
@ -0,0 +1,39 @@
|
|||
/* 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 "mozilla/net/BackgroundDataBridgeParent.h"
|
||||
#include "mozilla/net/SocketProcessChild.h"
|
||||
#include "mozilla/Unused.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
BackgroundDataBridgeParent::BackgroundDataBridgeParent(uint64_t aChannelID)
|
||||
: mChannelID(aChannelID), mBackgroundThread(NS_GetCurrentThread()) {
|
||||
SocketProcessChild::GetSingleton()->AddDataBridgeToMap(aChannelID, this);
|
||||
}
|
||||
|
||||
void BackgroundDataBridgeParent::ActorDestroy(ActorDestroyReason aWhy) {
|
||||
SocketProcessChild::GetSingleton()->RemoveDataBridgeFromMap(mChannelID);
|
||||
}
|
||||
|
||||
already_AddRefed<nsIThread> BackgroundDataBridgeParent::GetBackgroundThread() {
|
||||
nsCOMPtr<nsIThread> thread = mBackgroundThread;
|
||||
return thread.forget();
|
||||
}
|
||||
|
||||
void BackgroundDataBridgeParent::Destroy() {
|
||||
RefPtr<BackgroundDataBridgeParent> self = this;
|
||||
MOZ_ALWAYS_SUCCEEDS(mBackgroundThread->Dispatch(
|
||||
NS_NewRunnableFunction("BackgroundDataBridgeParent::Destroy",
|
||||
[self]() {
|
||||
if (self->CanSend()) {
|
||||
Unused << self->Send__delete__(self);
|
||||
}
|
||||
}),
|
||||
NS_DISPATCH_NORMAL));
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,32 @@
|
|||
/* 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_BackgroundDataBridgeParent_h
|
||||
#define mozilla_net_BackgroundDataBridgeParent_h
|
||||
|
||||
#include "mozilla/net/PBackgroundDataBridgeParent.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
class BackgroundDataBridgeParent final : public PBackgroundDataBridgeParent {
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(BackgroundDataBridgeParent, override)
|
||||
|
||||
explicit BackgroundDataBridgeParent(uint64_t aChannelID);
|
||||
void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
already_AddRefed<nsIThread> GetBackgroundThread();
|
||||
void Destroy();
|
||||
|
||||
private:
|
||||
virtual ~BackgroundDataBridgeParent() = default;
|
||||
|
||||
uint64_t mChannelID;
|
||||
nsCOMPtr<nsIThread> mBackgroundThread;
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_net_BackgroundDataBridgeParent_h
|
|
@ -7,6 +7,10 @@
|
|||
#include "DelayHttpChannelQueue.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsHttpChannel.h"
|
||||
#include "nsThreadManager.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::net;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "Http2HuffmanOutgoing.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "nsCharSeparatedTokenizer.h"
|
||||
#include "nsIMemoryReporter.h"
|
||||
#include "nsHttpHandler.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "mozilla/ipc/BackgroundChild.h"
|
||||
#include "mozilla/ipc/PBackgroundChild.h"
|
||||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
#include "mozilla/net/BackgroundDataBridgeChild.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "nsSocketTransportService2.h"
|
||||
|
||||
|
@ -46,6 +47,21 @@ nsresult HttpBackgroundChannelChild::Init(HttpChannelChild* aChannelChild) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void HttpBackgroundChannelChild::CreateDataBridge() {
|
||||
MOZ_ASSERT(OnSocketThread());
|
||||
PBackgroundChild* actorChild =
|
||||
BackgroundChild::GetOrCreateSocketActorForCurrentThread();
|
||||
if (NS_WARN_IF(!actorChild)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mDataBridgeChild = new BackgroundDataBridgeChild(this);
|
||||
if (!actorChild->SendPBackgroundDataBridgeConstructor(
|
||||
mDataBridgeChild, mChannelChild->ChannelId())) {
|
||||
mDataBridgeChild = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void HttpBackgroundChannelChild::OnChannelClosed() {
|
||||
LOG(("HttpBackgroundChannelChild::OnChannelClosed [this=%p]\n", this));
|
||||
MOZ_ASSERT(OnSocketThread());
|
||||
|
@ -55,6 +71,11 @@ void HttpBackgroundChannelChild::OnChannelClosed() {
|
|||
|
||||
// Remove pending IPC messages as well.
|
||||
mQueuedRunnables.Clear();
|
||||
|
||||
if (mDataBridgeChild) {
|
||||
mDataBridgeChild->Destroy();
|
||||
mDataBridgeChild = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void HttpBackgroundChannelChild::OnStartRequestReceived() {
|
||||
|
@ -98,8 +119,18 @@ bool HttpBackgroundChannelChild::CreateBackgroundChannel() {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool HttpBackgroundChannelChild::IsWaitingOnStartRequest() {
|
||||
bool HttpBackgroundChannelChild::IsWaitingOnStartRequest(
|
||||
bool aDataFromSocketProcess) {
|
||||
MOZ_ASSERT(OnSocketThread());
|
||||
|
||||
// When data is from socket process, it is possible that both mStartSent and
|
||||
// mStartReceived are false here. We need to wait until OnStartRequest sent
|
||||
// from parent process.
|
||||
// TODO: We can remove this code when diversion is removed in bug 1604448.
|
||||
if (aDataFromSocketProcess) {
|
||||
return !mStartReceived;
|
||||
}
|
||||
|
||||
// Need to wait for OnStartRequest if it is sent by
|
||||
// parent process but not received by content process.
|
||||
return (mStartSent && !mStartReceived);
|
||||
|
@ -117,25 +148,29 @@ IPCResult HttpBackgroundChannelChild::RecvOnStartRequestSent() {
|
|||
|
||||
IPCResult HttpBackgroundChannelChild::RecvOnTransportAndData(
|
||||
const nsresult& aChannelStatus, const nsresult& aTransportStatus,
|
||||
const uint64_t& aOffset, const uint32_t& aCount, const nsCString& aData) {
|
||||
LOG(("HttpBackgroundChannelChild::RecvOnTransportAndData [this=%p]\n", this));
|
||||
const uint64_t& aOffset, const uint32_t& aCount, const nsCString& aData,
|
||||
const bool& aDataFromSocketProcess) {
|
||||
LOG(
|
||||
("HttpBackgroundChannelChild::RecvOnTransportAndData [this=%p, "
|
||||
"aDataFromSocketProcess=%d]\n",
|
||||
this, aDataFromSocketProcess));
|
||||
MOZ_ASSERT(OnSocketThread());
|
||||
|
||||
if (NS_WARN_IF(!mChannelChild)) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
if (IsWaitingOnStartRequest()) {
|
||||
if (IsWaitingOnStartRequest(aDataFromSocketProcess)) {
|
||||
LOG((" > pending until OnStartRequest [offset=%" PRIu64 " count=%" PRIu32
|
||||
"]\n",
|
||||
aOffset, aCount));
|
||||
|
||||
mQueuedRunnables.AppendElement(
|
||||
NewRunnableMethod<const nsresult, const nsresult, const uint64_t,
|
||||
const uint32_t, const nsCString>(
|
||||
const uint32_t, const nsCString, bool>(
|
||||
"HttpBackgroundChannelChild::RecvOnTransportAndData", this,
|
||||
&HttpBackgroundChannelChild::RecvOnTransportAndData, aChannelStatus,
|
||||
aTransportStatus, aOffset, aCount, aData));
|
||||
aTransportStatus, aOffset, aCount, aData, aDataFromSocketProcess));
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
|
|
@ -17,11 +17,14 @@ using mozilla::ipc::IPCResult;
|
|||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
class BackgroundDataBridgeChild;
|
||||
class HttpChannelChild;
|
||||
|
||||
class HttpBackgroundChannelChild final : public PHttpBackgroundChannelChild {
|
||||
friend class BackgroundChannelCreateCallback;
|
||||
friend class PHttpBackgroundChannelChild;
|
||||
friend class HttpChannelChild;
|
||||
friend class BackgroundDataBridgeChild;
|
||||
|
||||
public:
|
||||
explicit HttpBackgroundChannelChild();
|
||||
|
@ -45,7 +48,8 @@ class HttpBackgroundChannelChild final : public PHttpBackgroundChannelChild {
|
|||
const nsresult& aTransportStatus,
|
||||
const uint64_t& aOffset,
|
||||
const uint32_t& aCount,
|
||||
const nsCString& aData);
|
||||
const nsCString& aData,
|
||||
const bool& aDataFromSocketProcess);
|
||||
|
||||
IPCResult RecvOnStopRequest(
|
||||
const nsresult& aChannelStatus, const ResourceTimingStructArgs& aTiming,
|
||||
|
@ -61,6 +65,8 @@ class HttpBackgroundChannelChild final : public PHttpBackgroundChannelChild {
|
|||
|
||||
void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
void CreateDataBridge();
|
||||
|
||||
private:
|
||||
virtual ~HttpBackgroundChannelChild();
|
||||
|
||||
|
@ -75,7 +81,12 @@ class HttpBackgroundChannelChild final : public PHttpBackgroundChannelChild {
|
|||
// OnStartRequestReceived.
|
||||
// return true after both RecvOnStartRequestSend and OnStartRequestReceived
|
||||
// are invoked.
|
||||
bool IsWaitingOnStartRequest();
|
||||
// When ODA message is from socket process, it is possible that both
|
||||
// RecvOnStartRequestSent and OnStartRequestReceived are not invoked, but
|
||||
// RecvOnTransportAndData is already invoked. In this case, we only need to
|
||||
// check if OnStartRequestReceived is invoked to make sure ODA doesn't happen
|
||||
// before OnStartRequest.
|
||||
bool IsWaitingOnStartRequest(bool aDataFromSocketProcess = false);
|
||||
|
||||
// Associated HttpChannelChild for handling the channel events.
|
||||
// Will be removed while failed to create background channel,
|
||||
|
@ -95,6 +106,8 @@ class HttpBackgroundChannelChild final : public PHttpBackgroundChannelChild {
|
|||
// Should be flushed after OnStartRequest is received and handled.
|
||||
// Should only access on STS thread.
|
||||
nsTArray<nsCOMPtr<nsIRunnable>> mQueuedRunnables;
|
||||
|
||||
RefPtr<BackgroundDataBridgeChild> mDataBridgeChild;
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
|
|
|
@ -192,7 +192,7 @@ bool HttpBackgroundChannelParent::OnTransportAndData(
|
|||
}
|
||||
|
||||
return SendOnTransportAndData(aChannelStatus, aTransportStatus, aOffset,
|
||||
aCount, aData);
|
||||
aCount, aData, false);
|
||||
}
|
||||
|
||||
bool HttpBackgroundChannelParent::OnStopRequest(
|
||||
|
|
|
@ -43,6 +43,8 @@
|
|||
#include "mozilla/ipc/BackgroundUtils.h"
|
||||
#include "mozilla/net/ChannelDiverterChild.h"
|
||||
#include "mozilla/net/DNS.h"
|
||||
#include "mozilla/net/SocketProcessBridgeChild.h"
|
||||
#include "mozilla/StaticPrefs_network.h"
|
||||
#include "mozilla/StoragePrincipalHelper.h"
|
||||
#include "SerializedLoadContext.h"
|
||||
#include "nsInputStreamPump.h"
|
||||
|
@ -60,6 +62,7 @@
|
|||
#include "nsCORSListenerProxy.h"
|
||||
#include "nsApplicationCache.h"
|
||||
#include "ClassifierDummyChannel.h"
|
||||
#include "nsIOService.h"
|
||||
|
||||
#ifdef MOZ_TASK_TRACER
|
||||
# include "GeckoTaskTracer.h"
|
||||
|
@ -878,6 +881,8 @@ void HttpChannelChild::OnTransportAndData(const nsresult& aChannelStatus,
|
|||
DoOnDataAvailable(this, nullptr, stringStream, aOffset, aCount);
|
||||
stringStream->Close();
|
||||
|
||||
// TODO: Bug 1523916 backpressure needs to take into account if the data is
|
||||
// coming from the main process or from the socket process via PBackground.
|
||||
if (NeedToReportBytesRead()) {
|
||||
mUnreportBytesRead += aCount;
|
||||
if (mUnreportBytesRead >= gHttpHandler->SendWindowSize() >> 2) {
|
||||
|
@ -2090,6 +2095,8 @@ HttpChannelChild::ConnectParent(uint32_t registrarId) {
|
|||
mBgChild = std::move(bgChild);
|
||||
}
|
||||
|
||||
MaybeConnectToSocketProcess();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -2845,6 +2852,8 @@ nsresult HttpChannelChild::ContinueAsyncOpen() {
|
|||
mBgChild = std::move(bgChild);
|
||||
}
|
||||
|
||||
MaybeConnectToSocketProcess();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -4021,5 +4030,27 @@ void HttpChannelChild::DoDiagnosticAssertWhenOnStopNotCalledOnDestroy() {
|
|||
#endif
|
||||
}
|
||||
|
||||
void HttpChannelChild::MaybeConnectToSocketProcess() {
|
||||
if (!nsIOService::UseSocketProcess()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!StaticPrefs::network_send_ODA_to_content_directly()) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<HttpBackgroundChannelChild> bgChild = mBgChild;
|
||||
SocketProcessBridgeChild::GetSocketProcessBridge()->Then(
|
||||
GetCurrentThreadSerialEventTarget(), __func__,
|
||||
[bgChild]() {
|
||||
gSocketTransportService->Dispatch(
|
||||
NewRunnableMethod("HttpBackgroundChannelChild::CreateDataBridge",
|
||||
bgChild,
|
||||
&HttpBackgroundChannelChild::CreateDataBridge),
|
||||
NS_DISPATCH_NORMAL);
|
||||
},
|
||||
[]() { NS_WARNING("Failed to create SocketProcessBridgeChild"); });
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -539,6 +539,7 @@ class HttpChannelChild final : public PHttpChannelChild,
|
|||
void DoNotifyListener();
|
||||
void ContinueDoNotifyListener();
|
||||
void OnAfterLastPart(const nsresult& aStatus);
|
||||
void MaybeConnectToSocketProcess();
|
||||
|
||||
// Create a a new channel to be used in a redirection, based on the provided
|
||||
// response headers.
|
||||
|
|
|
@ -1695,6 +1695,12 @@ HttpChannelParent::OnDataAvailable(nsIRequest* aRequest,
|
|||
transportStatus = NS_NET_STATUS_READING;
|
||||
}
|
||||
|
||||
if (httpChannelImpl->OnDataAlreadySent()) {
|
||||
LOG((" OnDataAvailable already sent to the child.\n"));
|
||||
uint32_t n;
|
||||
return aInputStream->ReadSegments(NS_DiscardSegment, nullptr, aCount, &n);
|
||||
}
|
||||
|
||||
static uint32_t const kCopyChunkSize = 128 * 1024;
|
||||
uint32_t toRead = std::min<uint32_t>(aCount, kCopyChunkSize);
|
||||
|
||||
|
|
|
@ -10,8 +10,11 @@
|
|||
#include "HttpTransactionChild.h"
|
||||
|
||||
#include "mozilla/ipc/IPCStreamUtils.h"
|
||||
#include "mozilla/ipc/BackgroundParent.h"
|
||||
#include "mozilla/net/BackgroundDataBridgeParent.h"
|
||||
#include "mozilla/net/InputChannelThrottleQueueChild.h"
|
||||
#include "mozilla/net/SocketProcessChild.h"
|
||||
#include "mozilla/StaticPrefs_network.h"
|
||||
#include "nsInputStreamPump.h"
|
||||
#include "nsHttpHandler.h"
|
||||
#include "nsProxyInfo.h"
|
||||
|
@ -19,18 +22,21 @@
|
|||
#include "nsQueryObject.h"
|
||||
#include "nsSerializationHelper.h"
|
||||
|
||||
using mozilla::ipc::BackgroundParent;
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
NS_IMPL_ISUPPORTS(HttpTransactionChild, nsIRequestObserver, nsIStreamListener,
|
||||
nsITransportEventSink, nsIThrottledInputChannel);
|
||||
nsITransportEventSink, nsIThrottledInputChannel,
|
||||
nsIThreadRetargetableStreamListener);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// HttpTransactionChild <public>
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
HttpTransactionChild::HttpTransactionChild()
|
||||
: mCanceled(false), mStatus(NS_OK), mChannelId(0) {
|
||||
: mCanceled(false), mStatus(NS_OK), mChannelId(0), mIsDocumentLoad(false) {
|
||||
LOG(("Creating HttpTransactionChild @%p\n", this));
|
||||
}
|
||||
|
||||
|
@ -125,6 +131,11 @@ nsresult HttpTransactionChild::InitInternal(
|
|||
mozilla::ipc::IPCResult HttpTransactionChild::RecvCancelPump(
|
||||
const nsresult& aStatus) {
|
||||
LOG(("HttpTransactionChild::RecvCancelPump start [this=%p]\n", this));
|
||||
CancelInternal(aStatus);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
void HttpTransactionChild::CancelInternal(nsresult aStatus) {
|
||||
MOZ_ASSERT(NS_FAILED(aStatus));
|
||||
|
||||
mCanceled = true;
|
||||
|
@ -132,8 +143,6 @@ mozilla::ipc::IPCResult HttpTransactionChild::RecvCancelPump(
|
|||
if (mTransactionPump) {
|
||||
mTransactionPump->Cancel(mStatus);
|
||||
}
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult HttpTransactionChild::RecvSuspendPump() {
|
||||
|
@ -164,7 +173,8 @@ mozilla::ipc::IPCResult HttpTransactionChild::RecvInit(
|
|||
const bool& aResponseTimeoutEnabled, const uint64_t& aChannelId,
|
||||
const bool& aHasTransactionObserver,
|
||||
const Maybe<H2PushedStreamArg>& aPushedStreamArg,
|
||||
const mozilla::Maybe<PInputChannelThrottleQueueChild*>& aThrottleQueue) {
|
||||
const mozilla::Maybe<PInputChannelThrottleQueueChild*>& aThrottleQueue,
|
||||
const bool& aIsDocumentLoad) {
|
||||
mRequestHead = aReqHeaders;
|
||||
if (aRequestBody) {
|
||||
mUploadStream = mozilla::ipc::DeserializeIPCStream(aRequestBody);
|
||||
|
@ -172,6 +182,7 @@ mozilla::ipc::IPCResult HttpTransactionChild::RecvInit(
|
|||
|
||||
mTransaction = new nsHttpTransaction();
|
||||
mChannelId = aChannelId;
|
||||
mIsDocumentLoad = aIsDocumentLoad;
|
||||
|
||||
if (aThrottleQueue.isSome()) {
|
||||
mThrottleQueue =
|
||||
|
@ -254,10 +265,6 @@ HttpTransactionChild::OnDataAvailable(nsIRequest* aRequest,
|
|||
return mStatus;
|
||||
}
|
||||
|
||||
if (!CanSend()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// TODO: send string data in chunks and handle errors. Bug 1600129.
|
||||
nsCString data;
|
||||
nsresult rv = NS_ReadInputStreamToString(aInputStream, data, aCount);
|
||||
|
@ -265,7 +272,47 @@ HttpTransactionChild::OnDataAvailable(nsIRequest* aRequest,
|
|||
return rv;
|
||||
}
|
||||
|
||||
Unused << SendOnDataAvailable(data, aOffset, aCount);
|
||||
if (NS_IsMainThread()) {
|
||||
if (!CanSend()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
LOG((" ODA to parent process"));
|
||||
Unused << SendOnDataAvailable(data, aOffset, aCount, false);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
ipc::AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(mDataBridgeParent);
|
||||
|
||||
if (!mDataBridgeParent->CanSend()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
bool dataSentToContentProcess =
|
||||
mDataBridgeParent->SendOnTransportAndData(aOffset, aCount, data);
|
||||
LOG((" ODA to content process, dataSentToContentProcess=%d",
|
||||
dataSentToContentProcess));
|
||||
if (!dataSentToContentProcess) {
|
||||
MOZ_ASSERT(false, "Send ODA to content process failed");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// We still need to send ODA to parent process, because the data needs to be
|
||||
// saved in cache. Note that we set dataSentToChildProcess to true, to this
|
||||
// ODA will not be sent to child process.
|
||||
RefPtr<HttpTransactionChild> self = this;
|
||||
rv = NS_DispatchToMainThread(
|
||||
NS_NewRunnableFunction(
|
||||
"HttpTransactionChild::OnDataAvailable",
|
||||
[self, offset(aOffset), count(aCount), data(data)]() {
|
||||
if (!self->SendOnDataAvailable(data, offset, count, true)) {
|
||||
self->CancelInternal(NS_ERROR_FAILURE);
|
||||
}
|
||||
}),
|
||||
NS_DISPATCH_NORMAL);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -293,6 +340,36 @@ static void GetDataForSniffer(void* aClosure, const uint8_t* aData,
|
|||
outData->AppendElements(aData, std::min(aCount, MAX_BYTES_SNIFFED));
|
||||
}
|
||||
|
||||
bool HttpTransactionChild::CanSendODAToContentProcessDirectly(
|
||||
const Maybe<nsHttpResponseHead>& aHead) {
|
||||
if (!StaticPrefs::network_send_ODA_to_content_directly()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If this is a document load, the content process that receives ODA is not
|
||||
// decided yet, so don't bother to do the rest check.
|
||||
if (mIsDocumentLoad) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!aHead) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We only need to deliver ODA when the response is succeed.
|
||||
if (aHead->Status() != 200) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// UnknownDecoder could be used in parent process, so we can't send ODA to
|
||||
// content process.
|
||||
if (!aHead->HasContentType()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HttpTransactionChild::OnStartRequest(nsIRequest* aRequest) {
|
||||
LOG(("HttpTransactionChild::OnStartRequest start [this=%p] mTransaction=%p\n",
|
||||
|
@ -336,6 +413,31 @@ HttpTransactionChild::OnStartRequest(nsIRequest* aRequest) {
|
|||
}
|
||||
}
|
||||
|
||||
if (CanSendODAToContentProcessDirectly(optionalHead)) {
|
||||
Maybe<RefPtr<BackgroundDataBridgeParent>> dataBridgeParent =
|
||||
SocketProcessChild::GetSingleton()->GetAndRemoveDataBridge(mChannelId);
|
||||
// Check if there is a registered BackgroundDataBridgeParent.
|
||||
if (dataBridgeParent) {
|
||||
mDataBridgeParent = std::move(dataBridgeParent.ref());
|
||||
|
||||
nsCOMPtr<nsIThread> backgroundThread =
|
||||
mDataBridgeParent->GetBackgroundThread();
|
||||
nsCOMPtr<nsIThreadRetargetableRequest> retargetableTransactionPump;
|
||||
retargetableTransactionPump = do_QueryObject(mTransactionPump);
|
||||
// nsInputStreamPump should implement this interface.
|
||||
MOZ_ASSERT(retargetableTransactionPump);
|
||||
|
||||
nsresult rv =
|
||||
retargetableTransactionPump->RetargetDeliveryTo(backgroundThread);
|
||||
LOG((" Retarget to background thread [this=%p rv=%08x]\n", this,
|
||||
static_cast<uint32_t>(rv)));
|
||||
if (NS_FAILED(rv)) {
|
||||
mDataBridgeParent->Destroy();
|
||||
mDataBridgeParent = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32_t proxyConnectResponseCode =
|
||||
mTransaction->GetProxyConnectResponseCode();
|
||||
|
||||
|
@ -343,7 +445,6 @@ HttpTransactionChild::OnStartRequest(nsIRequest* aRequest) {
|
|||
mTransaction->ProxyConnectFailed(),
|
||||
ToTimingStructArgs(mTransaction->Timings()),
|
||||
proxyConnectResponseCode, dataForSniffer);
|
||||
LOG(("HttpTransactionChild::OnStartRequest end [this=%p]\n", this));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -351,6 +452,11 @@ NS_IMETHODIMP
|
|||
HttpTransactionChild::OnStopRequest(nsIRequest* aRequest, nsresult aStatus) {
|
||||
LOG(("HttpTransactionChild::OnStopRequest [this=%p]\n", this));
|
||||
|
||||
if (mDataBridgeParent) {
|
||||
mDataBridgeParent->Destroy();
|
||||
mDataBridgeParent = nullptr;
|
||||
}
|
||||
|
||||
// Don't bother sending IPC to parent process if already canceled.
|
||||
if (mCanceled) {
|
||||
return mStatus;
|
||||
|
@ -434,5 +540,14 @@ HttpTransactionChild::GetThrottleQueue(nsIInputChannelThrottleQueue** aQueue) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// EventSourceImpl::nsIThreadRetargetableStreamListener
|
||||
//-----------------------------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
HttpTransactionChild::CheckListenerChain() {
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Should be on the main thread!");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -6,11 +6,13 @@
|
|||
#ifndef HttpTransactionChild_h__
|
||||
#define HttpTransactionChild_h__
|
||||
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "mozilla/net/NeckoChannelParams.h"
|
||||
#include "mozilla/net/PHttpTransactionChild.h"
|
||||
#include "nsHttpRequestHead.h"
|
||||
#include "nsIRequest.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIThreadRetargetableStreamListener.h"
|
||||
#include "nsIThrottledInputChannel.h"
|
||||
#include "nsITransport.h"
|
||||
|
||||
|
@ -19,6 +21,7 @@ class nsInputStreamPump;
|
|||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
class BackgroundDataBridgeParent;
|
||||
class InputChannelThrottleQueueChild;
|
||||
class nsHttpConnectionInfo;
|
||||
class nsHttpTransaction;
|
||||
|
@ -31,13 +34,15 @@ class nsProxyInfo;
|
|||
class HttpTransactionChild final : public PHttpTransactionChild,
|
||||
public nsIStreamListener,
|
||||
public nsITransportEventSink,
|
||||
public nsIThrottledInputChannel {
|
||||
public nsIThrottledInputChannel,
|
||||
public nsIThreadRetargetableStreamListener {
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
NS_DECL_NSITRANSPORTEVENTSINK
|
||||
NS_DECL_NSITHROTTLEDINPUTCHANNEL
|
||||
NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
|
||||
|
||||
explicit HttpTransactionChild();
|
||||
|
||||
|
@ -52,7 +57,8 @@ class HttpTransactionChild final : public PHttpTransactionChild,
|
|||
const bool& aResponseTimeoutEnabled, const uint64_t& aChannelId,
|
||||
const bool& aHasTransactionObserver,
|
||||
const Maybe<H2PushedStreamArg>& aPushedStreamArg,
|
||||
const mozilla::Maybe<PInputChannelThrottleQueueChild*>& aThrottleQueue);
|
||||
const mozilla::Maybe<PInputChannelThrottleQueueChild*>& aThrottleQueue,
|
||||
const bool& aIsDocumentLoad);
|
||||
mozilla::ipc::IPCResult RecvUpdateClassOfService(
|
||||
const uint32_t& classOfService);
|
||||
mozilla::ipc::IPCResult RecvCancelPump(const nsresult& aStatus);
|
||||
|
@ -85,16 +91,25 @@ class HttpTransactionChild final : public PHttpTransactionChild,
|
|||
bool aHasTransactionObserver,
|
||||
const Maybe<H2PushedStreamArg>& aPushedStreamArg);
|
||||
|
||||
bool mCanceled;
|
||||
void CancelInternal(nsresult aStatus);
|
||||
|
||||
bool CanSendODAToContentProcessDirectly(
|
||||
const Maybe<nsHttpResponseHead>& aHead);
|
||||
|
||||
// Use Release-Acquire ordering to ensure the OMT ODA is ignored while
|
||||
// transaction is canceled on main thread.
|
||||
Atomic<bool, ReleaseAcquire> mCanceled;
|
||||
nsresult mStatus;
|
||||
uint64_t mChannelId;
|
||||
nsHttpRequestHead mRequestHead;
|
||||
bool mIsDocumentLoad;
|
||||
|
||||
nsCOMPtr<nsIInputStream> mUploadStream;
|
||||
RefPtr<nsHttpTransaction> mTransaction;
|
||||
nsCOMPtr<nsIRequest> mTransactionPump;
|
||||
Maybe<TransactionObserverResult> mTransactionObserverResult;
|
||||
RefPtr<InputChannelThrottleQueueChild> mThrottleQueue;
|
||||
RefPtr<BackgroundDataBridgeParent> mDataBridgeParent;
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
|
|
|
@ -64,7 +64,7 @@ NS_IMETHODIMP_(MozExternalRefCountType) HttpTransactionParent::Release(void) {
|
|||
// HttpTransactionParent <public>
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
HttpTransactionParent::HttpTransactionParent()
|
||||
HttpTransactionParent::HttpTransactionParent(bool aIsDocumentLoad)
|
||||
: mResponseIsComplete(false),
|
||||
mTransferSize(0),
|
||||
mRequestSize(0),
|
||||
|
@ -79,7 +79,9 @@ HttpTransactionParent::HttpTransactionParent()
|
|||
mOnStopRequestCalled(false),
|
||||
mResolvedByTRR(false),
|
||||
mProxyConnectResponseCode(0),
|
||||
mChannelId(0) {
|
||||
mChannelId(0),
|
||||
mDataAlreadySent(false),
|
||||
mIsDocumentLoad(aIsDocumentLoad) {
|
||||
LOG(("Creating HttpTransactionParent @%p\n", this));
|
||||
|
||||
this->mSelfAddr.inet = {};
|
||||
|
@ -170,7 +172,8 @@ nsresult HttpTransactionParent::Init(
|
|||
topLevelOuterContentWindowId,
|
||||
static_cast<uint8_t>(trafficCategory), requestContextID,
|
||||
classOfService, initialRwin, responseTimeoutEnabled, mChannelId,
|
||||
!!mTransactionObserver, pushedStreamArg, throttleQueue)) {
|
||||
!!mTransactionObserver, pushedStreamArg, throttleQueue,
|
||||
mIsDocumentLoad)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -288,6 +291,8 @@ int64_t HttpTransactionParent::GetTransferSize() { return mTransferSize; }
|
|||
|
||||
int64_t HttpTransactionParent::GetRequestSize() { return mRequestSize; }
|
||||
|
||||
bool HttpTransactionParent::DataAlreadySent() { return mDataAlreadySent; }
|
||||
|
||||
nsISupports* HttpTransactionParent::SecurityInfo() { return mSecurityInfo; }
|
||||
|
||||
bool HttpTransactionParent::ProxyConnectFailed() { return mProxyConnectFailed; }
|
||||
|
@ -434,7 +439,8 @@ void HttpTransactionParent::DoOnTransportStatus(const nsresult& aStatus,
|
|||
}
|
||||
|
||||
mozilla::ipc::IPCResult HttpTransactionParent::RecvOnDataAvailable(
|
||||
const nsCString& aData, const uint64_t& aOffset, const uint32_t& aCount) {
|
||||
const nsCString& aData, const uint64_t& aOffset, const uint32_t& aCount,
|
||||
const bool& aDataSentToChildProcess) {
|
||||
LOG(("HttpTransactionParent::RecvOnDataAvailable [this=%p, aOffset= %" PRIu64
|
||||
" aCount=%" PRIu32,
|
||||
this, aOffset, aCount));
|
||||
|
@ -445,18 +451,22 @@ mozilla::ipc::IPCResult HttpTransactionParent::RecvOnDataAvailable(
|
|||
|
||||
mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
|
||||
this, [self = UnsafePtr<HttpTransactionParent>(this), aData, aOffset,
|
||||
aCount]() { self->DoOnDataAvailable(aData, aOffset, aCount); }));
|
||||
aCount, aDataSentToChildProcess]() {
|
||||
self->DoOnDataAvailable(aData, aOffset, aCount,
|
||||
aDataSentToChildProcess);
|
||||
}));
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
void HttpTransactionParent::DoOnDataAvailable(const nsCString& aData,
|
||||
const uint64_t& aOffset,
|
||||
const uint32_t& aCount) {
|
||||
void HttpTransactionParent::DoOnDataAvailable(
|
||||
const nsCString& aData, const uint64_t& aOffset, const uint32_t& aCount,
|
||||
const bool& aDataSentToChildProcess) {
|
||||
LOG(("HttpTransactionParent::DoOnDataAvailable [this=%p]\n", this));
|
||||
if (mCanceled) {
|
||||
return;
|
||||
}
|
||||
|
||||
mDataAlreadySent = aDataSentToChildProcess;
|
||||
nsCOMPtr<nsIInputStream> stringStream;
|
||||
nsresult rv = NS_NewByteInputStream(getter_AddRefs(stringStream),
|
||||
MakeSpan(aData.get(), aCount),
|
||||
|
|
|
@ -41,7 +41,7 @@ class HttpTransactionParent final : public PHttpTransactionParent,
|
|||
NS_DECL_NSITHREADRETARGETABLEREQUEST
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(HTTP_TRANSACTION_PARENT_IID)
|
||||
|
||||
explicit HttpTransactionParent();
|
||||
explicit HttpTransactionParent(bool aIsDocumentLoad);
|
||||
|
||||
void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
|
@ -54,9 +54,9 @@ class HttpTransactionParent final : public PHttpTransactionParent,
|
|||
mozilla::ipc::IPCResult RecvOnTransportStatus(const nsresult& aStatus,
|
||||
const int64_t& aProgress,
|
||||
const int64_t& aProgressMax);
|
||||
mozilla::ipc::IPCResult RecvOnDataAvailable(const nsCString& aData,
|
||||
const uint64_t& aOffset,
|
||||
const uint32_t& aCount);
|
||||
mozilla::ipc::IPCResult RecvOnDataAvailable(
|
||||
const nsCString& aData, const uint64_t& aOffset, const uint32_t& aCount,
|
||||
const bool& aDataSentToChildProcess);
|
||||
mozilla::ipc::IPCResult RecvOnStopRequest(
|
||||
const nsresult& aStatus, const bool& aResponseIsComplete,
|
||||
const int64_t& aTransferSize, const TimingStructArgs& aTimings,
|
||||
|
@ -93,7 +93,8 @@ class HttpTransactionParent final : public PHttpTransactionParent,
|
|||
void DoOnTransportStatus(const nsresult& aStatus, const int64_t& aProgress,
|
||||
const int64_t& aProgressMax);
|
||||
void DoOnDataAvailable(const nsCString& aData, const uint64_t& aOffset,
|
||||
const uint32_t& aCount);
|
||||
const uint32_t& aCount,
|
||||
const bool& aDataSentToChildProcess);
|
||||
void DoOnStopRequest(
|
||||
const nsresult& aStatus, const bool& aResponseIsComplete,
|
||||
const int64_t& aTransferSize, const TimingStructArgs& aTimings,
|
||||
|
@ -125,6 +126,8 @@ class HttpTransactionParent final : public PHttpTransactionParent,
|
|||
bool mResolvedByTRR;
|
||||
int32_t mProxyConnectResponseCode;
|
||||
uint64_t mChannelId;
|
||||
bool mDataAlreadySent;
|
||||
bool mIsDocumentLoad;
|
||||
|
||||
NetAddr mSelfAddr;
|
||||
NetAddr mPeerAddr;
|
||||
|
|
|
@ -147,6 +147,8 @@ class HttpTransactionShell : public nsISupports {
|
|||
virtual bool ProxyConnectFailed() = 0;
|
||||
virtual int32_t GetProxyConnectResponseCode() = 0;
|
||||
|
||||
virtual bool DataAlreadySent() = 0;
|
||||
|
||||
virtual nsHttpTransaction* AsHttpTransaction() = 0;
|
||||
virtual HttpTransactionParent* AsHttpTransactionParent() = 0;
|
||||
};
|
||||
|
@ -200,6 +202,7 @@ NS_DEFINE_STATIC_IID_ACCESSOR(HttpTransactionShell, HTTPTRANSACTIONSHELL_IID)
|
|||
virtual void SetH2WSConnRefTaken() override; \
|
||||
virtual bool ProxyConnectFailed() override; \
|
||||
virtual int32_t GetProxyConnectResponseCode() override; \
|
||||
virtual bool DataAlreadySent() override; \
|
||||
virtual nsHttpTransaction* AsHttpTransaction() override; \
|
||||
virtual HttpTransactionParent* AsHttpTransactionParent() override;
|
||||
} // namespace net
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
/* 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 protocol PBackground;
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
async refcounted protocol PBackgroundDataBridge
|
||||
{
|
||||
manager PBackground;
|
||||
|
||||
child:
|
||||
async OnTransportAndData(uint64_t offset,
|
||||
uint32_t count,
|
||||
nsCString data);
|
||||
|
||||
both:
|
||||
async __delete__();
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
|
@ -36,7 +36,8 @@ child:
|
|||
nsresult transportStatus,
|
||||
uint64_t offset,
|
||||
uint32_t count,
|
||||
nsCString data);
|
||||
nsCString data,
|
||||
bool dataFromSocketProcess);
|
||||
|
||||
// This is duplicated on PHttpChannel, which gets used for multi-part
|
||||
// streams to make synchronization when we get OnStartRequest multiple
|
||||
|
|
|
@ -43,7 +43,8 @@ parent:
|
|||
int64_t progressMax);
|
||||
async OnDataAvailable(nsCString data,
|
||||
uint64_t offset,
|
||||
uint32_t count);
|
||||
uint32_t count,
|
||||
bool dataSentToChildProcess);
|
||||
async OnStopRequest(nsresult status,
|
||||
bool responseIsComplete,
|
||||
int64_t transferSize,
|
||||
|
@ -74,7 +75,8 @@ child:
|
|||
uint64_t channelId,
|
||||
bool hasTransactionObserver,
|
||||
H2PushedStreamArg? pushedStreamArg,
|
||||
PInputChannelThrottleQueue? throttleQueue);
|
||||
PInputChannelThrottleQueue? throttleQueue,
|
||||
bool aIsDocumentLoad);
|
||||
|
||||
async UpdateClassOfService(uint32_t classOfService);
|
||||
async CancelPump(nsresult status);
|
||||
|
|
|
@ -42,6 +42,8 @@ EXPORTS.mozilla.net += [
|
|||
'AltSvcTransactionChild.h',
|
||||
'AltSvcTransactionParent.h',
|
||||
'BackgroundChannelRegistrar.h',
|
||||
'BackgroundDataBridgeChild.h',
|
||||
'BackgroundDataBridgeParent.h',
|
||||
'ClassifierDummyChannel.h',
|
||||
'ClassifierDummyChannelChild.h',
|
||||
'ClassifierDummyChannelParent.h',
|
||||
|
@ -82,6 +84,8 @@ UNIFIED_SOURCES += [
|
|||
'AltSvcTransactionParent.cpp',
|
||||
'ASpdySession.cpp',
|
||||
'BackgroundChannelRegistrar.cpp',
|
||||
'BackgroundDataBridgeChild.cpp',
|
||||
'BackgroundDataBridgeParent.cpp',
|
||||
'CacheControlParser.cpp',
|
||||
'ClassifierDummyChannel.cpp',
|
||||
'ClassifierDummyChannelChild.cpp',
|
||||
|
@ -145,6 +149,7 @@ IPDL_SOURCES += [
|
|||
'PAltDataOutputStream.ipdl',
|
||||
'PAltService.ipdl',
|
||||
'PAltSvcTransaction.ipdl',
|
||||
'PBackgroundDataBridge.ipdl',
|
||||
'PClassifierDummyChannel.ipdl',
|
||||
'PHttpBackgroundChannel.ipdl',
|
||||
'PHttpChannel.ipdl',
|
||||
|
|
|
@ -396,6 +396,7 @@ nsHttpChannel::nsHttpChannel()
|
|||
mIsIsolated(0),
|
||||
mTopWindowOriginComputed(0),
|
||||
mHasCrossOriginOpenerPolicyMismatch(0),
|
||||
mDataAlreadySent(0),
|
||||
mPushedStreamId(0),
|
||||
mLocalBlocklist(false),
|
||||
mOnTailUnblock(nullptr),
|
||||
|
@ -1349,7 +1350,16 @@ nsresult nsHttpChannel::SetupTransaction() {
|
|||
MOZ_ASSERT(gIOService->SocketProcessReady(),
|
||||
"Socket process should be ready.");
|
||||
|
||||
RefPtr<HttpTransactionParent> transParent = new HttpTransactionParent();
|
||||
nsCOMPtr<nsIParentChannel> parentChannel;
|
||||
NS_QueryNotificationCallbacks(this, parentChannel);
|
||||
RefPtr<DocumentLoadListener> documentChannelParent =
|
||||
do_QueryObject(parentChannel);
|
||||
// See HttpTransactionChild::CanSendODAToContentProcessDirectly() and
|
||||
// nsHttpChannel::CallOnStartRequest() for the reason why we need to know if
|
||||
// this is a document load. We only send ODA directly to child process for
|
||||
// non document loads.
|
||||
RefPtr<HttpTransactionParent> transParent =
|
||||
new HttpTransactionParent(!!documentChannelParent);
|
||||
LOG1(("nsHttpChannel %p created HttpTransactionParent %p\n", this,
|
||||
transParent.get()));
|
||||
|
||||
|
@ -1923,6 +1933,10 @@ nsresult nsHttpChannel::CallOnStartRequest() {
|
|||
}
|
||||
}
|
||||
|
||||
// Note that the code below should be synced with the code in
|
||||
// HttpTransactionChild::CanSendODAToContentProcessDirectly(). We MUST make
|
||||
// sure HttpTransactionChild::CanSendODAToContentProcessDirectly() returns
|
||||
// false when a stream converter is applied.
|
||||
bool unknownDecoderStarted = false;
|
||||
if (mResponseHead && !mResponseHead->HasContentType()) {
|
||||
MOZ_ASSERT(mConnectionInfo, "Should have connection info here");
|
||||
|
@ -8466,6 +8480,10 @@ nsHttpChannel::OnDataAvailable(nsIRequest* request, nsIInputStream* input,
|
|||
seekable = nullptr;
|
||||
}
|
||||
|
||||
mDataAlreadySent = false;
|
||||
if (mTransaction) {
|
||||
mDataAlreadySent = mTransaction->DataAlreadySent();
|
||||
}
|
||||
nsresult rv =
|
||||
mListener->OnDataAvailable(this, input, mLogicalOffset, count);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
|
|
|
@ -198,6 +198,8 @@ class nsHttpChannel final : public HttpBaseChannel,
|
|||
void SetWarningReporter(HttpChannelSecurityWarningReporter* aReporter);
|
||||
HttpChannelSecurityWarningReporter* GetWarningReporter();
|
||||
|
||||
bool OnDataAlreadySent() { return mDataAlreadySent; }
|
||||
|
||||
public: /* internal necko use only */
|
||||
uint32_t GetRequestTime() const { return mRequestTime; }
|
||||
|
||||
|
@ -735,6 +737,10 @@ class nsHttpChannel final : public HttpBaseChannel,
|
|||
// opener policy ( see ComputeCrossOriginOpenerPolicyMismatch )
|
||||
uint32_t mHasCrossOriginOpenerPolicyMismatch : 1;
|
||||
|
||||
// True if the data has already been sent from the socket process to the
|
||||
// content process.
|
||||
uint32_t mDataAlreadySent : 1;
|
||||
|
||||
// The origin of the top window, only valid when mTopWindowOriginComputed is
|
||||
// true.
|
||||
nsCString mTopWindowOrigin;
|
||||
|
|
|
@ -1175,7 +1175,7 @@ nsresult nsHttpResponseHead::GetOriginalHeader(nsHttpAtom aHeader,
|
|||
return rv;
|
||||
}
|
||||
|
||||
bool nsHttpResponseHead::HasContentType() {
|
||||
bool nsHttpResponseHead::HasContentType() const {
|
||||
RecursiveMutexAutoLock monitor(mRecursiveMutex);
|
||||
return !mContentType.IsEmpty();
|
||||
}
|
||||
|
|
|
@ -157,7 +157,7 @@ class nsHttpResponseHead {
|
|||
[[nodiscard]] nsresult GetOriginalHeader(nsHttpAtom aHeader,
|
||||
nsIHttpHeaderVisitor* aVisitor);
|
||||
|
||||
bool HasContentType();
|
||||
bool HasContentType() const;
|
||||
bool HasContentCharset();
|
||||
bool GetContentTypeOptionsHeader(nsACString& aOutput);
|
||||
|
||||
|
|
|
@ -1003,6 +1003,8 @@ nsresult nsHttpTransaction::WriteSegments(nsAHttpSegmentWriter* writer,
|
|||
|
||||
bool nsHttpTransaction::ProxyConnectFailed() { return mProxyConnectFailed; }
|
||||
|
||||
bool nsHttpTransaction::DataAlreadySent() { return false; }
|
||||
|
||||
nsISupports* nsHttpTransaction::SecurityInfo() { return mSecurityInfo; }
|
||||
|
||||
bool nsHttpTransaction::HasStickyConnection() const {
|
||||
|
|
Загрузка…
Ссылка в новой задаче