forked from mirrors/gecko-dev
Backed out changeset 61af32f40777 (bug 1770944) Backed out changeset 4ff0c45db93b (bug 1770944) Backed out changeset 8a217eff7bcd (bug 1770944) Backed out changeset 6435f48c96bf (bug 1770944) Backed out changeset 0d2432765ca0 (bug 1770944) Backed out changeset 58e02566db85 (bug 1770944) Backed out changeset 0a8c4c2460ee (bug 1770944) Backed out changeset 9416bafd9982 (bug 1770944) Backed out changeset 79de4f83fe2e (bug 1770944) Backed out changeset 63ac518aceb0 (bug 1770944) Backed out changeset 14952f872b77 (bug 1770944) Backed out changeset f65e0967ad75 (bug 1770944) Backed out changeset bd53c42038f7 (bug 1770944) Backed out changeset 36c378ba8212 (bug 1770944) Backed out changeset 9ba54ab06348 (bug 1770944) Backed out changeset fb5a54b3cbe9 (bug 1770944)
889 lines
30 KiB
C++
889 lines
30 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set sw=2 ts=8 et tw=80 : */
|
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "nsHttp.h"
|
|
#include "mozilla/BasePrincipal.h"
|
|
#include "mozilla/ContentPrincipal.h"
|
|
#include "mozilla/ipc/IPCStreamUtils.h"
|
|
#include "mozilla/net/ExtensionProtocolHandler.h"
|
|
#include "mozilla/net/PageThumbProtocolHandler.h"
|
|
#include "mozilla/net/NeckoParent.h"
|
|
#include "mozilla/net/HttpChannelParent.h"
|
|
#include "mozilla/net/CookieServiceParent.h"
|
|
#include "mozilla/net/WebSocketChannelParent.h"
|
|
#include "mozilla/net/WebSocketEventListenerParent.h"
|
|
#include "mozilla/net/DataChannelParent.h"
|
|
#ifdef MOZ_WIDGET_GTK
|
|
# include "mozilla/net/GIOChannelParent.h"
|
|
#endif
|
|
#include "mozilla/net/DocumentChannelParent.h"
|
|
#include "mozilla/net/SimpleChannelParent.h"
|
|
#include "mozilla/net/AltDataOutputStreamParent.h"
|
|
#include "mozilla/Unused.h"
|
|
#include "mozilla/net/FileChannelParent.h"
|
|
#include "mozilla/net/DNSRequestParent.h"
|
|
#include "mozilla/net/IPCTransportProvider.h"
|
|
#include "mozilla/net/RemoteStreamGetter.h"
|
|
#include "mozilla/net/RequestContextService.h"
|
|
#include "mozilla/net/SocketProcessParent.h"
|
|
#include "mozilla/net/PSocketProcessBridgeParent.h"
|
|
#ifdef MOZ_WEBRTC
|
|
# include "mozilla/net/StunAddrsRequestParent.h"
|
|
# include "mozilla/net/WebrtcTCPSocketParent.h"
|
|
#endif
|
|
#include "mozilla/dom/ContentParent.h"
|
|
#include "mozilla/dom/BrowserParent.h"
|
|
#include "mozilla/dom/MaybeDiscarded.h"
|
|
#include "mozilla/dom/network/TCPSocketParent.h"
|
|
#include "mozilla/dom/network/TCPServerSocketParent.h"
|
|
#include "mozilla/dom/network/UDPSocketParent.h"
|
|
#ifdef MOZ_PLACES
|
|
# include "mozilla/places/PageIconProtocolHandler.h"
|
|
#endif
|
|
#include "mozilla/LoadContext.h"
|
|
#include "mozilla/MozPromise.h"
|
|
#include "nsPrintfCString.h"
|
|
#include "mozilla/dom/HTMLDNSPrefetch.h"
|
|
#include "nsEscape.h"
|
|
#include "SerializedLoadContext.h"
|
|
#include "nsAuthInformationHolder.h"
|
|
#include "nsINetworkPredictor.h"
|
|
#include "nsINetworkPredictorVerifier.h"
|
|
#include "nsISpeculativeConnect.h"
|
|
#include "nsHttpHandler.h"
|
|
#include "nsNetUtil.h"
|
|
#include "nsIOService.h"
|
|
|
|
using IPC::SerializedLoadContext;
|
|
using mozilla::dom::BrowserParent;
|
|
using mozilla::dom::ContentParent;
|
|
using mozilla::dom::TCPServerSocketParent;
|
|
using mozilla::dom::TCPSocketParent;
|
|
using mozilla::dom::UDPSocketParent;
|
|
using mozilla::ipc::LoadInfoArgsToLoadInfo;
|
|
using mozilla::ipc::PrincipalInfo;
|
|
#ifdef MOZ_PLACES
|
|
using mozilla::places::PageIconProtocolHandler;
|
|
#endif
|
|
|
|
namespace mozilla {
|
|
namespace net {
|
|
|
|
// C++ file contents
|
|
NeckoParent::NeckoParent() : mSocketProcessBridgeInited(false) {
|
|
// Init HTTP protocol handler now since we need atomTable up and running very
|
|
// early (IPDL argument handling for PHttpChannel constructor needs it) so
|
|
// normal init (during 1st Http channel request) isn't early enough.
|
|
nsCOMPtr<nsIProtocolHandler> proto =
|
|
do_GetService("@mozilla.org/network/protocol;1?name=http");
|
|
}
|
|
|
|
static PBOverrideStatus PBOverrideStatusFromLoadContext(
|
|
const SerializedLoadContext& aSerialized) {
|
|
if (!aSerialized.IsNotNull() && aSerialized.IsPrivateBitValid()) {
|
|
return (aSerialized.mOriginAttributes.mPrivateBrowsingId > 0)
|
|
? kPBOverride_Private
|
|
: kPBOverride_NotPrivate;
|
|
}
|
|
return kPBOverride_Unset;
|
|
}
|
|
|
|
static already_AddRefed<nsIPrincipal> GetRequestingPrincipal(
|
|
const LoadInfoArgs& aLoadInfoArgs) {
|
|
const Maybe<PrincipalInfo>& optionalPrincipalInfo =
|
|
aLoadInfoArgs.requestingPrincipalInfo();
|
|
|
|
if (optionalPrincipalInfo.isNothing()) {
|
|
return nullptr;
|
|
}
|
|
|
|
const PrincipalInfo& principalInfo = optionalPrincipalInfo.ref();
|
|
|
|
auto principalOrErr = PrincipalInfoToPrincipal(principalInfo);
|
|
return principalOrErr.isOk() ? principalOrErr.unwrap().forget() : nullptr;
|
|
}
|
|
|
|
static already_AddRefed<nsIPrincipal> GetRequestingPrincipal(
|
|
const HttpChannelCreationArgs& aArgs) {
|
|
if (aArgs.type() != HttpChannelCreationArgs::THttpChannelOpenArgs) {
|
|
return nullptr;
|
|
}
|
|
|
|
const HttpChannelOpenArgs& args = aArgs.get_HttpChannelOpenArgs();
|
|
return GetRequestingPrincipal(args.loadInfo());
|
|
}
|
|
|
|
const char* NeckoParent::GetValidatedOriginAttributes(
|
|
const SerializedLoadContext& aSerialized, PContentParent* aContent,
|
|
nsIPrincipal* aRequestingPrincipal, OriginAttributes& aAttrs) {
|
|
if (!aSerialized.IsNotNull()) {
|
|
// If serialized is null, we cannot validate anything. We have to assume
|
|
// that this requests comes from a SystemPrincipal.
|
|
aAttrs = OriginAttributes(false);
|
|
} else {
|
|
aAttrs = aSerialized.mOriginAttributes;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
const char* NeckoParent::CreateChannelLoadContext(
|
|
PBrowserParent* aBrowser, PContentParent* aContent,
|
|
const SerializedLoadContext& aSerialized,
|
|
nsIPrincipal* aRequestingPrincipal, nsCOMPtr<nsILoadContext>& aResult) {
|
|
OriginAttributes attrs;
|
|
const char* error = GetValidatedOriginAttributes(aSerialized, aContent,
|
|
aRequestingPrincipal, attrs);
|
|
if (error) {
|
|
return error;
|
|
}
|
|
|
|
// if !UsingNeckoIPCSecurity(), we may not have a LoadContext to set. This is
|
|
// the common case for most xpcshell tests.
|
|
if (aSerialized.IsNotNull()) {
|
|
attrs.SyncAttributesWithPrivateBrowsing(
|
|
aSerialized.mOriginAttributes.mPrivateBrowsingId > 0);
|
|
|
|
RefPtr<BrowserParent> browserParent = BrowserParent::GetFrom(aBrowser);
|
|
dom::Element* topFrameElement = nullptr;
|
|
if (browserParent) {
|
|
topFrameElement = browserParent->GetOwnerElement();
|
|
}
|
|
aResult = new LoadContext(aSerialized, topFrameElement, attrs);
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
void NeckoParent::ActorDestroy(ActorDestroyReason aWhy) {
|
|
// Nothing needed here. Called right before destructor since this is a
|
|
// non-refcounted class.
|
|
}
|
|
|
|
already_AddRefed<PHttpChannelParent> NeckoParent::AllocPHttpChannelParent(
|
|
PBrowserParent* aBrowser, const SerializedLoadContext& aSerialized,
|
|
const HttpChannelCreationArgs& aOpenArgs) {
|
|
nsCOMPtr<nsIPrincipal> requestingPrincipal =
|
|
GetRequestingPrincipal(aOpenArgs);
|
|
|
|
nsCOMPtr<nsILoadContext> loadContext;
|
|
const char* error = CreateChannelLoadContext(
|
|
aBrowser, Manager(), aSerialized, requestingPrincipal, loadContext);
|
|
if (error) {
|
|
printf_stderr(
|
|
"NeckoParent::AllocPHttpChannelParent: "
|
|
"FATAL error: %s: KILLING CHILD PROCESS\n",
|
|
error);
|
|
return nullptr;
|
|
}
|
|
PBOverrideStatus overrideStatus =
|
|
PBOverrideStatusFromLoadContext(aSerialized);
|
|
RefPtr<HttpChannelParent> p = new HttpChannelParent(
|
|
BrowserParent::GetFrom(aBrowser), loadContext, overrideStatus);
|
|
return p.forget();
|
|
}
|
|
|
|
mozilla::ipc::IPCResult NeckoParent::RecvPHttpChannelConstructor(
|
|
PHttpChannelParent* aActor, PBrowserParent* aBrowser,
|
|
const SerializedLoadContext& aSerialized,
|
|
const HttpChannelCreationArgs& aOpenArgs) {
|
|
HttpChannelParent* p = static_cast<HttpChannelParent*>(aActor);
|
|
if (!p->Init(aOpenArgs)) {
|
|
return IPC_FAIL_NO_REASON(this);
|
|
}
|
|
return IPC_OK();
|
|
}
|
|
|
|
PStunAddrsRequestParent* NeckoParent::AllocPStunAddrsRequestParent() {
|
|
#ifdef MOZ_WEBRTC
|
|
StunAddrsRequestParent* p = new StunAddrsRequestParent();
|
|
p->AddRef();
|
|
return p;
|
|
#else
|
|
return nullptr;
|
|
#endif
|
|
}
|
|
|
|
bool NeckoParent::DeallocPStunAddrsRequestParent(
|
|
PStunAddrsRequestParent* aActor) {
|
|
#ifdef MOZ_WEBRTC
|
|
StunAddrsRequestParent* p = static_cast<StunAddrsRequestParent*>(aActor);
|
|
p->Release();
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
PWebrtcTCPSocketParent* NeckoParent::AllocPWebrtcTCPSocketParent(
|
|
const Maybe<TabId>& aTabId) {
|
|
#ifdef MOZ_WEBRTC
|
|
WebrtcTCPSocketParent* parent = new WebrtcTCPSocketParent(aTabId);
|
|
parent->AddRef();
|
|
return parent;
|
|
#else
|
|
return nullptr;
|
|
#endif
|
|
}
|
|
|
|
bool NeckoParent::DeallocPWebrtcTCPSocketParent(
|
|
PWebrtcTCPSocketParent* aActor) {
|
|
#ifdef MOZ_WEBRTC
|
|
WebrtcTCPSocketParent* parent = static_cast<WebrtcTCPSocketParent*>(aActor);
|
|
parent->Release();
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
PAltDataOutputStreamParent* NeckoParent::AllocPAltDataOutputStreamParent(
|
|
const nsACString& type, const int64_t& predictedSize,
|
|
PHttpChannelParent* channel) {
|
|
HttpChannelParent* chan = static_cast<HttpChannelParent*>(channel);
|
|
nsCOMPtr<nsIAsyncOutputStream> stream;
|
|
nsresult rv = chan->OpenAlternativeOutputStream(type, predictedSize,
|
|
getter_AddRefs(stream));
|
|
AltDataOutputStreamParent* parent = new AltDataOutputStreamParent(stream);
|
|
parent->AddRef();
|
|
// If the return value was not NS_OK, the error code will be sent
|
|
// asynchronously to the child, after receiving the first message.
|
|
parent->SetError(rv);
|
|
return parent;
|
|
}
|
|
|
|
bool NeckoParent::DeallocPAltDataOutputStreamParent(
|
|
PAltDataOutputStreamParent* aActor) {
|
|
AltDataOutputStreamParent* parent =
|
|
static_cast<AltDataOutputStreamParent*>(aActor);
|
|
parent->Release();
|
|
return true;
|
|
}
|
|
|
|
already_AddRefed<PDocumentChannelParent>
|
|
NeckoParent::AllocPDocumentChannelParent(
|
|
const dom::MaybeDiscarded<dom::BrowsingContext>& aContext,
|
|
const DocumentChannelCreationArgs& args) {
|
|
RefPtr<DocumentChannelParent> p = new DocumentChannelParent();
|
|
return p.forget();
|
|
}
|
|
|
|
mozilla::ipc::IPCResult NeckoParent::RecvPDocumentChannelConstructor(
|
|
PDocumentChannelParent* aActor,
|
|
const dom::MaybeDiscarded<dom::BrowsingContext>& aContext,
|
|
const DocumentChannelCreationArgs& aArgs) {
|
|
DocumentChannelParent* p = static_cast<DocumentChannelParent*>(aActor);
|
|
|
|
if (aContext.IsNullOrDiscarded()) {
|
|
Unused << p->SendFailedAsyncOpen(NS_ERROR_FAILURE);
|
|
return IPC_OK();
|
|
}
|
|
|
|
if (!p->Init(aContext.get_canonical(), aArgs)) {
|
|
return IPC_FAIL(this, "Couldn't initialize DocumentChannel");
|
|
}
|
|
|
|
return IPC_OK();
|
|
}
|
|
|
|
PCookieServiceParent* NeckoParent::AllocPCookieServiceParent() {
|
|
return new CookieServiceParent();
|
|
}
|
|
|
|
bool NeckoParent::DeallocPCookieServiceParent(PCookieServiceParent* cs) {
|
|
delete cs;
|
|
return true;
|
|
}
|
|
|
|
PWebSocketParent* NeckoParent::AllocPWebSocketParent(
|
|
PBrowserParent* browser, const SerializedLoadContext& serialized,
|
|
const uint32_t& aSerial) {
|
|
nsCOMPtr<nsILoadContext> loadContext;
|
|
const char* error = CreateChannelLoadContext(browser, Manager(), serialized,
|
|
nullptr, loadContext);
|
|
if (error) {
|
|
printf_stderr(
|
|
"NeckoParent::AllocPWebSocketParent: "
|
|
"FATAL error: %s: KILLING CHILD PROCESS\n",
|
|
error);
|
|
return nullptr;
|
|
}
|
|
|
|
RefPtr<BrowserParent> browserParent = BrowserParent::GetFrom(browser);
|
|
PBOverrideStatus overrideStatus = PBOverrideStatusFromLoadContext(serialized);
|
|
WebSocketChannelParent* p = new WebSocketChannelParent(
|
|
browserParent, loadContext, overrideStatus, aSerial);
|
|
p->AddRef();
|
|
return p;
|
|
}
|
|
|
|
bool NeckoParent::DeallocPWebSocketParent(PWebSocketParent* actor) {
|
|
WebSocketChannelParent* p = static_cast<WebSocketChannelParent*>(actor);
|
|
p->Release();
|
|
return true;
|
|
}
|
|
|
|
PWebSocketEventListenerParent* NeckoParent::AllocPWebSocketEventListenerParent(
|
|
const uint64_t& aInnerWindowID) {
|
|
RefPtr<WebSocketEventListenerParent> c =
|
|
new WebSocketEventListenerParent(aInnerWindowID);
|
|
return c.forget().take();
|
|
}
|
|
|
|
bool NeckoParent::DeallocPWebSocketEventListenerParent(
|
|
PWebSocketEventListenerParent* aActor) {
|
|
RefPtr<WebSocketEventListenerParent> c =
|
|
dont_AddRef(static_cast<WebSocketEventListenerParent*>(aActor));
|
|
MOZ_ASSERT(c);
|
|
return true;
|
|
}
|
|
|
|
already_AddRefed<PDataChannelParent> NeckoParent::AllocPDataChannelParent(
|
|
const uint32_t& channelId) {
|
|
RefPtr<DataChannelParent> p = new DataChannelParent();
|
|
return p.forget();
|
|
}
|
|
|
|
mozilla::ipc::IPCResult NeckoParent::RecvPDataChannelConstructor(
|
|
PDataChannelParent* actor, const uint32_t& channelId) {
|
|
DataChannelParent* p = static_cast<DataChannelParent*>(actor);
|
|
DebugOnly<bool> rv = p->Init(channelId);
|
|
MOZ_ASSERT(rv);
|
|
return IPC_OK();
|
|
}
|
|
|
|
#ifdef MOZ_WIDGET_GTK
|
|
static already_AddRefed<nsIPrincipal> GetRequestingPrincipal(
|
|
const GIOChannelCreationArgs& aArgs) {
|
|
if (aArgs.type() != GIOChannelCreationArgs::TGIOChannelOpenArgs) {
|
|
return nullptr;
|
|
}
|
|
|
|
const GIOChannelOpenArgs& args = aArgs.get_GIOChannelOpenArgs();
|
|
return GetRequestingPrincipal(args.loadInfo());
|
|
}
|
|
|
|
PGIOChannelParent* NeckoParent::AllocPGIOChannelParent(
|
|
PBrowserParent* aBrowser, const SerializedLoadContext& aSerialized,
|
|
const GIOChannelCreationArgs& aOpenArgs) {
|
|
nsCOMPtr<nsIPrincipal> requestingPrincipal =
|
|
GetRequestingPrincipal(aOpenArgs);
|
|
|
|
nsCOMPtr<nsILoadContext> loadContext;
|
|
const char* error = CreateChannelLoadContext(
|
|
aBrowser, Manager(), aSerialized, requestingPrincipal, loadContext);
|
|
if (error) {
|
|
printf_stderr(
|
|
"NeckoParent::AllocPGIOChannelParent: "
|
|
"FATAL error: %s: KILLING CHILD PROCESS\n",
|
|
error);
|
|
return nullptr;
|
|
}
|
|
PBOverrideStatus overrideStatus =
|
|
PBOverrideStatusFromLoadContext(aSerialized);
|
|
GIOChannelParent* p = new GIOChannelParent(BrowserParent::GetFrom(aBrowser),
|
|
loadContext, overrideStatus);
|
|
p->AddRef();
|
|
return p;
|
|
}
|
|
|
|
bool NeckoParent::DeallocPGIOChannelParent(PGIOChannelParent* channel) {
|
|
GIOChannelParent* p = static_cast<GIOChannelParent*>(channel);
|
|
p->Release();
|
|
return true;
|
|
}
|
|
|
|
mozilla::ipc::IPCResult NeckoParent::RecvPGIOChannelConstructor(
|
|
PGIOChannelParent* actor, PBrowserParent* aBrowser,
|
|
const SerializedLoadContext& aSerialized,
|
|
const GIOChannelCreationArgs& aOpenArgs) {
|
|
GIOChannelParent* p = static_cast<GIOChannelParent*>(actor);
|
|
DebugOnly<bool> rv = p->Init(aOpenArgs);
|
|
MOZ_ASSERT(rv);
|
|
return IPC_OK();
|
|
}
|
|
#endif
|
|
|
|
PSimpleChannelParent* NeckoParent::AllocPSimpleChannelParent(
|
|
const uint32_t& channelId) {
|
|
RefPtr<SimpleChannelParent> p = new SimpleChannelParent();
|
|
return p.forget().take();
|
|
}
|
|
|
|
bool NeckoParent::DeallocPSimpleChannelParent(PSimpleChannelParent* actor) {
|
|
RefPtr<SimpleChannelParent> p =
|
|
dont_AddRef(actor).downcast<SimpleChannelParent>();
|
|
return true;
|
|
}
|
|
|
|
mozilla::ipc::IPCResult NeckoParent::RecvPSimpleChannelConstructor(
|
|
PSimpleChannelParent* actor, const uint32_t& channelId) {
|
|
SimpleChannelParent* p = static_cast<SimpleChannelParent*>(actor);
|
|
MOZ_ALWAYS_TRUE(p->Init(channelId));
|
|
return IPC_OK();
|
|
}
|
|
|
|
already_AddRefed<PFileChannelParent> NeckoParent::AllocPFileChannelParent(
|
|
const uint32_t& channelId) {
|
|
RefPtr<FileChannelParent> p = new FileChannelParent();
|
|
return p.forget();
|
|
}
|
|
|
|
mozilla::ipc::IPCResult NeckoParent::RecvPFileChannelConstructor(
|
|
PFileChannelParent* actor, const uint32_t& channelId) {
|
|
FileChannelParent* p = static_cast<FileChannelParent*>(actor);
|
|
DebugOnly<bool> rv = p->Init(channelId);
|
|
MOZ_ASSERT(rv);
|
|
return IPC_OK();
|
|
}
|
|
|
|
PTCPSocketParent* NeckoParent::AllocPTCPSocketParent(
|
|
const nsAString& /* host */, const uint16_t& /* port */) {
|
|
// We actually don't need host/port to construct a TCPSocketParent since
|
|
// TCPSocketParent will maintain an internal nsIDOMTCPSocket instance which
|
|
// can be delegated to get the host/port.
|
|
TCPSocketParent* p = new TCPSocketParent();
|
|
p->AddIPDLReference();
|
|
return p;
|
|
}
|
|
|
|
bool NeckoParent::DeallocPTCPSocketParent(PTCPSocketParent* actor) {
|
|
TCPSocketParent* p = static_cast<TCPSocketParent*>(actor);
|
|
p->ReleaseIPDLReference();
|
|
return true;
|
|
}
|
|
|
|
PTCPServerSocketParent* NeckoParent::AllocPTCPServerSocketParent(
|
|
const uint16_t& aLocalPort, const uint16_t& aBacklog,
|
|
const bool& aUseArrayBuffers) {
|
|
TCPServerSocketParent* p =
|
|
new TCPServerSocketParent(this, aLocalPort, aBacklog, aUseArrayBuffers);
|
|
p->AddIPDLReference();
|
|
return p;
|
|
}
|
|
|
|
mozilla::ipc::IPCResult NeckoParent::RecvPTCPServerSocketConstructor(
|
|
PTCPServerSocketParent* aActor, const uint16_t& aLocalPort,
|
|
const uint16_t& aBacklog, const bool& aUseArrayBuffers) {
|
|
static_cast<TCPServerSocketParent*>(aActor)->Init();
|
|
return IPC_OK();
|
|
}
|
|
|
|
bool NeckoParent::DeallocPTCPServerSocketParent(PTCPServerSocketParent* actor) {
|
|
TCPServerSocketParent* p = static_cast<TCPServerSocketParent*>(actor);
|
|
p->ReleaseIPDLReference();
|
|
return true;
|
|
}
|
|
|
|
PUDPSocketParent* NeckoParent::AllocPUDPSocketParent(
|
|
nsIPrincipal* /* unused */, const nsACString& /* unused */) {
|
|
RefPtr<UDPSocketParent> p = new UDPSocketParent(this);
|
|
|
|
return p.forget().take();
|
|
}
|
|
|
|
mozilla::ipc::IPCResult NeckoParent::RecvPUDPSocketConstructor(
|
|
PUDPSocketParent* aActor, nsIPrincipal* aPrincipal,
|
|
const nsACString& aFilter) {
|
|
if (!static_cast<UDPSocketParent*>(aActor)->Init(aPrincipal, aFilter)) {
|
|
return IPC_FAIL_NO_REASON(this);
|
|
}
|
|
return IPC_OK();
|
|
}
|
|
|
|
bool NeckoParent::DeallocPUDPSocketParent(PUDPSocketParent* actor) {
|
|
UDPSocketParent* p = static_cast<UDPSocketParent*>(actor);
|
|
p->Release();
|
|
return true;
|
|
}
|
|
|
|
already_AddRefed<PDNSRequestParent> NeckoParent::AllocPDNSRequestParent(
|
|
const nsACString& aHost, const nsACString& aTrrServer, const int32_t& aPort,
|
|
const uint16_t& aType, const OriginAttributes& aOriginAttributes,
|
|
const nsIDNSService::DNSFlags& aFlags) {
|
|
RefPtr<DNSRequestHandler> handler = new DNSRequestHandler();
|
|
RefPtr<DNSRequestParent> actor = new DNSRequestParent(handler);
|
|
return actor.forget();
|
|
}
|
|
|
|
mozilla::ipc::IPCResult NeckoParent::RecvPDNSRequestConstructor(
|
|
PDNSRequestParent* aActor, const nsACString& aHost,
|
|
const nsACString& aTrrServer, const int32_t& aPort, const uint16_t& aType,
|
|
const OriginAttributes& aOriginAttributes,
|
|
const nsIDNSService::DNSFlags& aFlags) {
|
|
RefPtr<DNSRequestParent> actor = static_cast<DNSRequestParent*>(aActor);
|
|
RefPtr<DNSRequestHandler> handler =
|
|
actor->GetDNSRequest()->AsDNSRequestHandler();
|
|
handler->DoAsyncResolve(aHost, aTrrServer, aPort, aType, aOriginAttributes,
|
|
aFlags);
|
|
return IPC_OK();
|
|
}
|
|
|
|
mozilla::ipc::IPCResult NeckoParent::RecvSpeculativeConnect(
|
|
nsIURI* aURI, nsIPrincipal* aPrincipal,
|
|
Maybe<OriginAttributes>&& aOriginAttributes, const bool& aAnonymous) {
|
|
nsCOMPtr<nsISpeculativeConnect> speculator(gIOService);
|
|
nsCOMPtr<nsIPrincipal> principal(aPrincipal);
|
|
if (!aURI) {
|
|
return IPC_FAIL(this, "aURI must not be null");
|
|
}
|
|
if (aURI && speculator) {
|
|
if (aOriginAttributes) {
|
|
speculator->SpeculativeConnectWithOriginAttributesNative(
|
|
aURI, std::move(aOriginAttributes.ref()), nullptr, aAnonymous);
|
|
} else {
|
|
speculator->SpeculativeConnect(aURI, principal, nullptr, aAnonymous);
|
|
}
|
|
}
|
|
return IPC_OK();
|
|
}
|
|
|
|
mozilla::ipc::IPCResult NeckoParent::RecvHTMLDNSPrefetch(
|
|
const nsAString& hostname, const bool& isHttps,
|
|
const OriginAttributes& aOriginAttributes,
|
|
const nsIDNSService::DNSFlags& flags) {
|
|
dom::HTMLDNSPrefetch::Prefetch(hostname, isHttps, aOriginAttributes, flags);
|
|
return IPC_OK();
|
|
}
|
|
|
|
mozilla::ipc::IPCResult NeckoParent::RecvCancelHTMLDNSPrefetch(
|
|
const nsAString& hostname, const bool& isHttps,
|
|
const OriginAttributes& aOriginAttributes,
|
|
const nsIDNSService::DNSFlags& flags, const nsresult& reason) {
|
|
dom::HTMLDNSPrefetch::CancelPrefetch(hostname, isHttps, aOriginAttributes,
|
|
flags, reason);
|
|
return IPC_OK();
|
|
}
|
|
|
|
PTransportProviderParent* NeckoParent::AllocPTransportProviderParent() {
|
|
RefPtr<TransportProviderParent> res = new TransportProviderParent();
|
|
return res.forget().take();
|
|
}
|
|
|
|
bool NeckoParent::DeallocPTransportProviderParent(
|
|
PTransportProviderParent* aActor) {
|
|
RefPtr<TransportProviderParent> provider =
|
|
dont_AddRef(static_cast<TransportProviderParent*>(aActor));
|
|
return true;
|
|
}
|
|
|
|
/* Predictor Messages */
|
|
mozilla::ipc::IPCResult NeckoParent::RecvPredPredict(
|
|
nsIURI* aTargetURI, nsIURI* aSourceURI, const uint32_t& aReason,
|
|
const OriginAttributes& aOriginAttributes, const bool& hasVerifier) {
|
|
// Get the current predictor
|
|
nsresult rv = NS_OK;
|
|
nsCOMPtr<nsINetworkPredictor> predictor =
|
|
do_GetService("@mozilla.org/network/predictor;1", &rv);
|
|
NS_ENSURE_SUCCESS(rv, IPC_OK());
|
|
|
|
nsCOMPtr<nsINetworkPredictorVerifier> verifier;
|
|
if (hasVerifier) {
|
|
verifier = do_QueryInterface(predictor);
|
|
}
|
|
predictor->PredictNative(aTargetURI, aSourceURI, aReason, aOriginAttributes,
|
|
verifier);
|
|
return IPC_OK();
|
|
}
|
|
|
|
mozilla::ipc::IPCResult NeckoParent::RecvPredLearn(
|
|
nsIURI* aTargetURI, nsIURI* aSourceURI, const uint32_t& aReason,
|
|
const OriginAttributes& aOriginAttributes) {
|
|
// Get the current predictor
|
|
nsresult rv = NS_OK;
|
|
nsCOMPtr<nsINetworkPredictor> predictor =
|
|
do_GetService("@mozilla.org/network/predictor;1", &rv);
|
|
NS_ENSURE_SUCCESS(rv, IPC_OK());
|
|
|
|
predictor->LearnNative(aTargetURI, aSourceURI, aReason, aOriginAttributes);
|
|
return IPC_OK();
|
|
}
|
|
|
|
mozilla::ipc::IPCResult NeckoParent::RecvPredReset() {
|
|
// Get the current predictor
|
|
nsresult rv = NS_OK;
|
|
nsCOMPtr<nsINetworkPredictor> predictor =
|
|
do_GetService("@mozilla.org/network/predictor;1", &rv);
|
|
NS_ENSURE_SUCCESS(rv, IPC_OK());
|
|
|
|
predictor->Reset();
|
|
return IPC_OK();
|
|
}
|
|
|
|
mozilla::ipc::IPCResult NeckoParent::RecvRequestContextLoadBegin(
|
|
const uint64_t& rcid) {
|
|
nsCOMPtr<nsIRequestContextService> rcsvc =
|
|
RequestContextService::GetOrCreate();
|
|
if (!rcsvc) {
|
|
return IPC_OK();
|
|
}
|
|
nsCOMPtr<nsIRequestContext> rc;
|
|
rcsvc->GetRequestContext(rcid, getter_AddRefs(rc));
|
|
if (rc) {
|
|
rc->BeginLoad();
|
|
}
|
|
|
|
return IPC_OK();
|
|
}
|
|
|
|
mozilla::ipc::IPCResult NeckoParent::RecvRequestContextAfterDOMContentLoaded(
|
|
const uint64_t& rcid) {
|
|
nsCOMPtr<nsIRequestContextService> rcsvc =
|
|
RequestContextService::GetOrCreate();
|
|
if (!rcsvc) {
|
|
return IPC_OK();
|
|
}
|
|
nsCOMPtr<nsIRequestContext> rc;
|
|
rcsvc->GetRequestContext(rcid, getter_AddRefs(rc));
|
|
if (rc) {
|
|
rc->DOMContentLoaded();
|
|
}
|
|
|
|
return IPC_OK();
|
|
}
|
|
|
|
mozilla::ipc::IPCResult NeckoParent::RecvRemoveRequestContext(
|
|
const uint64_t& rcid) {
|
|
nsCOMPtr<nsIRequestContextService> rcsvc =
|
|
RequestContextService::GetOrCreate();
|
|
if (!rcsvc) {
|
|
return IPC_OK();
|
|
}
|
|
|
|
rcsvc->RemoveRequestContext(rcid);
|
|
|
|
return IPC_OK();
|
|
}
|
|
|
|
mozilla::ipc::IPCResult NeckoParent::RecvGetExtensionStream(
|
|
nsIURI* aURI, GetExtensionStreamResolver&& aResolve) {
|
|
if (!aURI) {
|
|
return IPC_FAIL(this, "aURI must not be null");
|
|
}
|
|
|
|
RefPtr<ExtensionProtocolHandler> ph(ExtensionProtocolHandler::GetSingleton());
|
|
MOZ_ASSERT(ph);
|
|
|
|
// Ask the ExtensionProtocolHandler to give us a new input stream for
|
|
// this URI. The request comes from an ExtensionProtocolHandler in the
|
|
// child process, but is not guaranteed to be a valid moz-extension URI,
|
|
// and not guaranteed to represent a resource that the child should be
|
|
// allowed to access. The ExtensionProtocolHandler is responsible for
|
|
// validating the request. Specifically, only URI's for local files that
|
|
// an extension is allowed to access via moz-extension URI's should be
|
|
// accepted.
|
|
nsCOMPtr<nsIInputStream> inputStream;
|
|
bool terminateSender = true;
|
|
auto inputStreamOrReason = ph->NewStream(aURI, &terminateSender);
|
|
if (inputStreamOrReason.isOk()) {
|
|
inputStream = inputStreamOrReason.unwrap();
|
|
}
|
|
|
|
// If NewStream failed, we send back an invalid stream to the child so
|
|
// it can handle the error. MozPromise rejection is reserved for channel
|
|
// errors/disconnects.
|
|
aResolve(inputStream);
|
|
|
|
if (terminateSender) {
|
|
return IPC_FAIL_NO_REASON(this);
|
|
}
|
|
return IPC_OK();
|
|
}
|
|
|
|
mozilla::ipc::IPCResult NeckoParent::RecvGetExtensionFD(
|
|
nsIURI* aURI, GetExtensionFDResolver&& aResolve) {
|
|
if (!aURI) {
|
|
return IPC_FAIL(this, "aURI must not be null");
|
|
}
|
|
|
|
RefPtr<ExtensionProtocolHandler> ph(ExtensionProtocolHandler::GetSingleton());
|
|
MOZ_ASSERT(ph);
|
|
|
|
// Ask the ExtensionProtocolHandler to give us a new input stream for
|
|
// this URI. The request comes from an ExtensionProtocolHandler in the
|
|
// child process, but is not guaranteed to be a valid moz-extension URI,
|
|
// and not guaranteed to represent a resource that the child should be
|
|
// allowed to access. The ExtensionProtocolHandler is responsible for
|
|
// validating the request. Specifically, only URI's for local files that
|
|
// an extension is allowed to access via moz-extension URI's should be
|
|
// accepted.
|
|
bool terminateSender = true;
|
|
auto result = ph->NewFD(aURI, &terminateSender, aResolve);
|
|
|
|
if (result.isErr() && terminateSender) {
|
|
return IPC_FAIL_NO_REASON(this);
|
|
}
|
|
|
|
if (result.isErr()) {
|
|
FileDescriptor invalidFD;
|
|
aResolve(invalidFD);
|
|
}
|
|
|
|
return IPC_OK();
|
|
}
|
|
|
|
mozilla::ipc::IPCResult NeckoParent::RecvInitSocketProcessBridge(
|
|
InitSocketProcessBridgeResolver&& aResolver) {
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
// Initing the socket process bridge must be async here in order to
|
|
// wait for the socket process launch before executing.
|
|
auto task = [self = RefPtr{this}, resolver = std::move(aResolver)]() {
|
|
// The content process might be already destroyed.
|
|
if (!self->CanSend()) {
|
|
return;
|
|
}
|
|
|
|
Endpoint<PSocketProcessBridgeChild> invalidEndpoint;
|
|
if (NS_WARN_IF(self->mSocketProcessBridgeInited)) {
|
|
resolver(std::move(invalidEndpoint));
|
|
return;
|
|
}
|
|
|
|
SocketProcessParent* parent = SocketProcessParent::GetSingleton();
|
|
if (NS_WARN_IF(!parent)) {
|
|
resolver(std::move(invalidEndpoint));
|
|
return;
|
|
}
|
|
|
|
Endpoint<PSocketProcessBridgeParent> parentEndpoint;
|
|
Endpoint<PSocketProcessBridgeChild> childEndpoint;
|
|
if (NS_WARN_IF(NS_FAILED(PSocketProcessBridge::CreateEndpoints(
|
|
parent->OtherPid(), self->Manager()->OtherPid(), &parentEndpoint,
|
|
&childEndpoint)))) {
|
|
resolver(std::move(invalidEndpoint));
|
|
return;
|
|
}
|
|
|
|
if (NS_WARN_IF(!parent->SendInitSocketProcessBridgeParent(
|
|
self->Manager()->OtherPid(), std::move(parentEndpoint)))) {
|
|
resolver(std::move(invalidEndpoint));
|
|
return;
|
|
}
|
|
|
|
resolver(std::move(childEndpoint));
|
|
self->mSocketProcessBridgeInited = true;
|
|
};
|
|
gIOService->CallOrWaitForSocketProcess(std::move(task));
|
|
|
|
return IPC_OK();
|
|
}
|
|
|
|
mozilla::ipc::IPCResult NeckoParent::RecvResetSocketProcessBridge() {
|
|
// SendResetSocketProcessBridge is called from
|
|
// SocketProcessBridgeChild::ActorDestroy if the socket process
|
|
// crashes. This is necessary in order to properly initialize the
|
|
// restarted socket process.
|
|
mSocketProcessBridgeInited = false;
|
|
return IPC_OK();
|
|
}
|
|
|
|
mozilla::ipc::IPCResult NeckoParent::RecvEnsureHSTSData(
|
|
EnsureHSTSDataResolver&& aResolver) {
|
|
auto callback = [aResolver{std::move(aResolver)}](bool aResult) {
|
|
aResolver(aResult);
|
|
};
|
|
RefPtr<HSTSDataCallbackWrapper> wrapper =
|
|
new HSTSDataCallbackWrapper(std::move(callback));
|
|
gHttpHandler->EnsureHSTSDataReadyNative(wrapper);
|
|
return IPC_OK();
|
|
}
|
|
|
|
mozilla::ipc::IPCResult NeckoParent::RecvGetPageThumbStream(
|
|
nsIURI* aURI, const LoadInfoArgs& aLoadInfoArgs,
|
|
GetPageThumbStreamResolver&& aResolver) {
|
|
// Only the privileged about content process is allowed to access
|
|
// things over the moz-page-thumb protocol. Any other content process
|
|
// that tries to send this should have been blocked via the
|
|
// ScriptSecurityManager, but if somehow the process has been tricked into
|
|
// sending this message, we send IPC_FAIL in order to crash that
|
|
// likely-compromised content process.
|
|
if (static_cast<ContentParent*>(Manager())->GetRemoteType() !=
|
|
PRIVILEGEDABOUT_REMOTE_TYPE) {
|
|
return IPC_FAIL(this, "Wrong process type");
|
|
}
|
|
|
|
RefPtr<PageThumbProtocolHandler> ph(PageThumbProtocolHandler::GetSingleton());
|
|
MOZ_ASSERT(ph);
|
|
|
|
// Ask the PageThumbProtocolHandler to give us a new input stream for
|
|
// this URI. The request comes from a PageThumbProtocolHandler in the
|
|
// child process, but is not guaranteed to be a valid moz-page-thumb URI,
|
|
// and not guaranteed to represent a resource that the child should be
|
|
// allowed to access. The PageThumbProtocolHandler is responsible for
|
|
// validating the request.
|
|
nsCOMPtr<nsIInputStream> inputStream;
|
|
bool terminateSender = true;
|
|
auto inputStreamPromise = ph->NewStream(aURI, &terminateSender);
|
|
|
|
if (terminateSender) {
|
|
return IPC_FAIL(this, "Malformed moz-page-thumb request");
|
|
}
|
|
|
|
inputStreamPromise->Then(
|
|
GetMainThreadSerialEventTarget(), __func__,
|
|
[aResolver](const RemoteStreamInfo& aInfo) { aResolver(Some(aInfo)); },
|
|
[aResolver](nsresult aRv) {
|
|
// If NewStream failed, we send back an invalid stream to the child so
|
|
// it can handle the error. MozPromise rejection is reserved for channel
|
|
// errors/disconnects.
|
|
Unused << NS_WARN_IF(NS_FAILED(aRv));
|
|
aResolver(Nothing());
|
|
});
|
|
|
|
return IPC_OK();
|
|
}
|
|
|
|
mozilla::ipc::IPCResult NeckoParent::RecvGetPageIconStream(
|
|
nsIURI* aURI, const LoadInfoArgs& aLoadInfoArgs,
|
|
GetPageIconStreamResolver&& aResolver) {
|
|
#ifdef MOZ_PLACES
|
|
const nsACString& remoteType =
|
|
ContentParent::Cast(Manager())->GetRemoteType();
|
|
|
|
// Only the privileged about content process is allowed to access
|
|
// things over the page-icon protocol. Any other content process
|
|
// that tries to send this should have been blocked via the
|
|
// ScriptSecurityManager, but if somehow the process has been tricked into
|
|
// sending this message, we send IPC_FAIL in order to crash that
|
|
// likely-compromised content process.
|
|
if (remoteType != PRIVILEGEDABOUT_REMOTE_TYPE) {
|
|
return IPC_FAIL(this, "Wrong process type");
|
|
}
|
|
|
|
nsCOMPtr<nsILoadInfo> loadInfo;
|
|
nsresult rv = mozilla::ipc::LoadInfoArgsToLoadInfo(aLoadInfoArgs, remoteType,
|
|
getter_AddRefs(loadInfo));
|
|
if (NS_FAILED(rv)) {
|
|
return IPC_FAIL(this, "Page-icon request must include loadInfo");
|
|
}
|
|
|
|
RefPtr<PageIconProtocolHandler> ph(PageIconProtocolHandler::GetSingleton());
|
|
MOZ_ASSERT(ph);
|
|
|
|
nsCOMPtr<nsIInputStream> inputStream;
|
|
bool terminateSender = true;
|
|
auto inputStreamPromise = ph->NewStream(aURI, loadInfo, &terminateSender);
|
|
|
|
if (terminateSender) {
|
|
return IPC_FAIL(this, "Malformed page-icon request");
|
|
}
|
|
|
|
inputStreamPromise->Then(
|
|
GetMainThreadSerialEventTarget(), __func__,
|
|
[aResolver](const RemoteStreamInfo& aInfo) { aResolver(Some(aInfo)); },
|
|
[aResolver](nsresult aRv) {
|
|
// If NewStream failed, we send back an invalid stream to the child so
|
|
// it can handle the error. MozPromise rejection is reserved for channel
|
|
// errors/disconnects.
|
|
Unused << NS_WARN_IF(NS_FAILED(aRv));
|
|
aResolver(Nothing());
|
|
});
|
|
|
|
return IPC_OK();
|
|
#else
|
|
return IPC_FAIL(this, "page-icon: protocol unavailable");
|
|
#endif
|
|
}
|
|
|
|
} // namespace net
|
|
} // namespace mozilla
|