/* -*- 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 "necko-config.h" #include "nsHttp.h" #include "mozilla/BasePrincipal.h" #include "mozilla/ContentPrincipal.h" #include "mozilla/ipc/IPCStreamUtils.h" #include "mozilla/net/ExtensionProtocolHandler.h" #include "mozilla/net/NeckoParent.h" #include "mozilla/net/HttpChannelParent.h" #include "mozilla/net/CookieServiceParent.h" #include "mozilla/net/WyciwygChannelParent.h" #include "mozilla/net/FTPChannelParent.h" #include "mozilla/net/WebSocketChannelParent.h" #include "mozilla/net/WebSocketEventListenerParent.h" #include "mozilla/net/DataChannelParent.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/ChannelDiverterParent.h" #include "mozilla/net/IPCTransportProvider.h" #include "mozilla/net/TrackingDummyChannelParent.h" #ifdef MOZ_WEBRTC #include "mozilla/net/StunAddrsRequestParent.h" #endif #include "mozilla/dom/ChromeUtils.h" #include "mozilla/dom/ContentParent.h" #include "mozilla/dom/TabContext.h" #include "mozilla/dom/TabParent.h" #include "mozilla/dom/network/TCPSocketParent.h" #include "mozilla/dom/network/TCPServerSocketParent.h" #include "mozilla/dom/network/UDPSocketParent.h" #include "mozilla/dom/ServiceWorkerManager.h" #include "mozilla/LoadContext.h" #include "mozilla/MozPromise.h" #include "nsPrintfCString.h" #include "nsHTMLDNSPrefetch.h" #include "nsEscape.h" #include "SerializedLoadContext.h" #include "nsAuthInformationHolder.h" #include "nsIAuthPromptCallback.h" #include "nsINetworkPredictor.h" #include "nsINetworkPredictorVerifier.h" #include "nsISpeculativeConnect.h" #include "nsNetUtil.h" using mozilla::OriginAttributes; using mozilla::dom::ChromeUtils; using mozilla::dom::ContentParent; using mozilla::dom::ServiceWorkerManager; using mozilla::dom::TabContext; using mozilla::dom::TabParent; using mozilla::net::PTCPSocketParent; using mozilla::dom::TCPSocketParent; using mozilla::net::PTCPServerSocketParent; using mozilla::dom::TCPServerSocketParent; using mozilla::net::PUDPSocketParent; using mozilla::dom::UDPSocketParent; using mozilla::ipc::OptionalPrincipalInfo; using mozilla::ipc::PrincipalInfo; using mozilla::ipc::LoadInfoArgsToLoadInfo; using IPC::SerializedLoadContext; namespace mozilla { namespace net { // C++ file contents NeckoParent::NeckoParent() { // 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 proto = do_GetService("@mozilla.org/network/protocol;1?name=http"); // only register once--we will have multiple NeckoParents if there are // multiple child processes. static bool registeredBool = false; if (!registeredBool) { Preferences::AddBoolVarCache(&NeckoCommonInternal::gSecurityDisabled, "network.disable.ipc.security"); registeredBool = true; } } 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 GetRequestingPrincipal(const OptionalLoadInfoArgs& aOptionalLoadInfoArgs) { if (aOptionalLoadInfoArgs.type() != OptionalLoadInfoArgs::TLoadInfoArgs) { return nullptr; } const LoadInfoArgs& loadInfoArgs = aOptionalLoadInfoArgs.get_LoadInfoArgs(); const OptionalPrincipalInfo& optionalPrincipalInfo = loadInfoArgs.requestingPrincipalInfo(); if (optionalPrincipalInfo.type() != OptionalPrincipalInfo::TPrincipalInfo) { return nullptr; } const PrincipalInfo& principalInfo = optionalPrincipalInfo.get_PrincipalInfo(); return PrincipalInfoToPrincipal(principalInfo); } static already_AddRefed GetRequestingPrincipal(const HttpChannelCreationArgs& aArgs) { if (aArgs.type() != HttpChannelCreationArgs::THttpChannelOpenArgs) { return nullptr; } const HttpChannelOpenArgs& args = aArgs.get_HttpChannelOpenArgs(); return GetRequestingPrincipal(args.loadInfo()); } static already_AddRefed GetRequestingPrincipal(const FTPChannelCreationArgs& aArgs) { if (aArgs.type() != FTPChannelCreationArgs::TFTPChannelOpenArgs) { return nullptr; } const FTPChannelOpenArgs& args = aArgs.get_FTPChannelOpenArgs(); return GetRequestingPrincipal(args.loadInfo()); } // Bug 1289001 - If GetValidatedOriginAttributes returns an error string, that // usually leads to a content crash with very little info about the cause. // We prefer to crash on the parent, so we get the reason in the crash report. static MOZ_COLD void CrashWithReason(const char * reason) { #ifndef RELEASE_OR_BETA MOZ_CRASH_UNSAFE_OOL(reason); #endif } const char* NeckoParent::GetValidatedOriginAttributes(const SerializedLoadContext& aSerialized, PContentParent* aContent, nsIPrincipal* aRequestingPrincipal, OriginAttributes& aAttrs) { if (!UsingNeckoIPCSecurity()) { if (!aSerialized.IsNotNull()) { // If serialized is null, we cannot validate anything. We have to assume // that this requests comes from a SystemPrincipal. aAttrs = OriginAttributes(NECKO_NO_APP_ID, false); } else { aAttrs = aSerialized.mOriginAttributes; } return nullptr; } if (!aSerialized.IsNotNull()) { CrashWithReason("GetValidatedOriginAttributes | SerializedLoadContext from child is null"); return "SerializedLoadContext from child is null"; } nsTArray contextArray = static_cast(aContent)->GetManagedTabContext(); nsAutoCString serializedSuffix; aSerialized.mOriginAttributes.CreateAnonymizedSuffix(serializedSuffix); nsAutoCString debugString; for (uint32_t i = 0; i < contextArray.Length(); i++) { const TabContext& tabContext = contextArray[i]; if (!ChromeUtils::IsOriginAttributesEqual(aSerialized.mOriginAttributes, tabContext.OriginAttributesRef())) { debugString.AppendLiteral("("); debugString.Append(serializedSuffix); debugString.AppendLiteral(","); nsAutoCString tabSuffix; tabContext.OriginAttributesRef().CreateAnonymizedSuffix(tabSuffix); debugString.Append(tabSuffix); debugString.AppendLiteral(")"); continue; } aAttrs = aSerialized.mOriginAttributes; return nullptr; } // This may be a ServiceWorker: when a push notification is received, FF wakes // up the corrisponding service worker so that it can manage the PushEvent. At // that time we probably don't have any valid tabcontext, but still, we want // to support http channel requests coming from that ServiceWorker. if (aRequestingPrincipal) { RefPtr swm = ServiceWorkerManager::GetInstance(); if (swm && swm->MayHaveActiveServiceWorkerInstance(static_cast(aContent), aRequestingPrincipal)) { aAttrs = aSerialized.mOriginAttributes; return nullptr; } } nsAutoCString errorString; errorString.AppendLiteral("GetValidatedOriginAttributes | App does not have permission -"); errorString.Append(debugString); // Leak the buffer on the heap to make sure that it lives long enough, as // MOZ_CRASH_ANNOTATE expects the pointer passed to it to live to the end of // the program. char * error = strdup(errorString.BeginReading()); CrashWithReason(error); return "App does not have permission"; } const char * NeckoParent::CreateChannelLoadContext(const PBrowserOrId& aBrowser, PContentParent* aContent, const SerializedLoadContext& aSerialized, nsIPrincipal* aRequestingPrincipal, nsCOMPtr &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); switch (aBrowser.type()) { case PBrowserOrId::TPBrowserParent: { RefPtr tabParent = TabParent::GetFrom(aBrowser.get_PBrowserParent()); dom::Element* topFrameElement = nullptr; if (tabParent) { topFrameElement = tabParent->GetOwnerElement(); } aResult = new LoadContext(aSerialized, topFrameElement, attrs); break; } case PBrowserOrId::TTabId: { aResult = new LoadContext(aSerialized, aBrowser.get_TabId(), attrs); break; } default: MOZ_CRASH(); } } return nullptr; } void NeckoParent::ActorDestroy(ActorDestroyReason aWhy) { // Nothing needed here. Called right before destructor since this is a // non-refcounted class. } PHttpChannelParent* NeckoParent::AllocPHttpChannelParent(const PBrowserOrId& aBrowser, const SerializedLoadContext& aSerialized, const HttpChannelCreationArgs& aOpenArgs) { nsCOMPtr requestingPrincipal = GetRequestingPrincipal(aOpenArgs); nsCOMPtr 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); HttpChannelParent *p = new HttpChannelParent(aBrowser, loadContext, overrideStatus); p->AddRef(); return p; } bool NeckoParent::DeallocPHttpChannelParent(PHttpChannelParent* channel) { HttpChannelParent *p = static_cast(channel); p->Release(); return true; } mozilla::ipc::IPCResult NeckoParent::RecvPHttpChannelConstructor( PHttpChannelParent* aActor, const PBrowserOrId& aBrowser, const SerializedLoadContext& aSerialized, const HttpChannelCreationArgs& aOpenArgs) { HttpChannelParent* p = static_cast(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(aActor); p->Release(); #endif return true; } PAltDataOutputStreamParent* NeckoParent::AllocPAltDataOutputStreamParent( const nsCString& type, const int64_t& predictedSize, PHttpChannelParent* channel) { HttpChannelParent* chan = static_cast(channel); nsCOMPtr 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(aActor); parent->Release(); return true; } PFTPChannelParent* NeckoParent::AllocPFTPChannelParent(const PBrowserOrId& aBrowser, const SerializedLoadContext& aSerialized, const FTPChannelCreationArgs& aOpenArgs) { nsCOMPtr requestingPrincipal = GetRequestingPrincipal(aOpenArgs); nsCOMPtr loadContext; const char *error = CreateChannelLoadContext(aBrowser, Manager(), aSerialized, requestingPrincipal, loadContext); if (error) { printf_stderr("NeckoParent::AllocPFTPChannelParent: " "FATAL error: %s: KILLING CHILD PROCESS\n", error); return nullptr; } PBOverrideStatus overrideStatus = PBOverrideStatusFromLoadContext(aSerialized); FTPChannelParent *p = new FTPChannelParent(aBrowser, loadContext, overrideStatus); p->AddRef(); return p; } bool NeckoParent::DeallocPFTPChannelParent(PFTPChannelParent* channel) { FTPChannelParent *p = static_cast(channel); p->Release(); return true; } mozilla::ipc::IPCResult NeckoParent::RecvPFTPChannelConstructor( PFTPChannelParent* aActor, const PBrowserOrId& aBrowser, const SerializedLoadContext& aSerialized, const FTPChannelCreationArgs& aOpenArgs) { FTPChannelParent* p = static_cast(aActor); if (!p->Init(aOpenArgs)) { return IPC_FAIL_NO_REASON(this); } return IPC_OK(); } PCookieServiceParent* NeckoParent::AllocPCookieServiceParent() { return new CookieServiceParent(); } bool NeckoParent::DeallocPCookieServiceParent(PCookieServiceParent* cs) { delete cs; return true; } PWyciwygChannelParent* NeckoParent::AllocPWyciwygChannelParent() { WyciwygChannelParent *p = new WyciwygChannelParent(); p->AddRef(); return p; } bool NeckoParent::DeallocPWyciwygChannelParent(PWyciwygChannelParent* channel) { WyciwygChannelParent *p = static_cast(channel); p->Release(); return true; } PWebSocketParent* NeckoParent::AllocPWebSocketParent(const PBrowserOrId& browser, const SerializedLoadContext& serialized, const uint32_t& aSerial) { nsCOMPtr 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 tabParent = TabParent::GetFrom(browser.get_PBrowserParent()); PBOverrideStatus overrideStatus = PBOverrideStatusFromLoadContext(serialized); WebSocketChannelParent* p = new WebSocketChannelParent(tabParent, loadContext, overrideStatus, aSerial); p->AddRef(); return p; } bool NeckoParent::DeallocPWebSocketParent(PWebSocketParent* actor) { WebSocketChannelParent* p = static_cast(actor); p->Release(); return true; } PWebSocketEventListenerParent* NeckoParent::AllocPWebSocketEventListenerParent(const uint64_t& aInnerWindowID) { RefPtr c = new WebSocketEventListenerParent(aInnerWindowID); return c.forget().take(); } bool NeckoParent::DeallocPWebSocketEventListenerParent(PWebSocketEventListenerParent* aActor) { RefPtr c = dont_AddRef(static_cast(aActor)); MOZ_ASSERT(c); return true; } PDataChannelParent* NeckoParent::AllocPDataChannelParent(const uint32_t &channelId) { RefPtr p = new DataChannelParent(); return p.forget().take(); } bool NeckoParent::DeallocPDataChannelParent(PDataChannelParent* actor) { RefPtr p = dont_AddRef(static_cast(actor)); return true; } mozilla::ipc::IPCResult NeckoParent::RecvPDataChannelConstructor(PDataChannelParent* actor, const uint32_t& channelId) { DataChannelParent* p = static_cast(actor); DebugOnly rv = p->Init(channelId); MOZ_ASSERT(rv); return IPC_OK(); } PSimpleChannelParent* NeckoParent::AllocPSimpleChannelParent(const uint32_t &channelId) { RefPtr p = new SimpleChannelParent(); return p.forget().take(); } bool NeckoParent::DeallocPSimpleChannelParent(PSimpleChannelParent* actor) { RefPtr p = dont_AddRef(actor).downcast(); return true; } mozilla::ipc::IPCResult NeckoParent::RecvPSimpleChannelConstructor(PSimpleChannelParent* actor, const uint32_t& channelId) { SimpleChannelParent* p = static_cast(actor); MOZ_ALWAYS_TRUE(p->Init(channelId)); return IPC_OK(); } PFileChannelParent* NeckoParent::AllocPFileChannelParent(const uint32_t &channelId) { RefPtr p = new FileChannelParent(); return p.forget().take(); } bool NeckoParent::DeallocPFileChannelParent(PFileChannelParent* actor) { RefPtr p = dont_AddRef(static_cast(actor)); return true; } mozilla::ipc::IPCResult NeckoParent::RecvPFileChannelConstructor(PFileChannelParent* actor, const uint32_t& channelId) { FileChannelParent* p = static_cast(actor); DebugOnly rv = p->Init(channelId); MOZ_ASSERT(rv); return IPC_OK(); } PTCPSocketParent* NeckoParent::AllocPTCPSocketParent(const nsString& /* 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(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(aActor)->Init(); return IPC_OK(); } bool NeckoParent::DeallocPTCPServerSocketParent(PTCPServerSocketParent* actor) { TCPServerSocketParent* p = static_cast(actor); p->ReleaseIPDLReference(); return true; } PUDPSocketParent* NeckoParent::AllocPUDPSocketParent(const Principal& /* unused */, const nsCString& /* unused */) { RefPtr p = new UDPSocketParent(this); return p.forget().take(); } mozilla::ipc::IPCResult NeckoParent::RecvPUDPSocketConstructor(PUDPSocketParent* aActor, const Principal& aPrincipal, const nsCString& aFilter) { if (!static_cast(aActor)->Init(aPrincipal, aFilter)) { return IPC_FAIL_NO_REASON(this); } return IPC_OK(); } bool NeckoParent::DeallocPUDPSocketParent(PUDPSocketParent* actor) { UDPSocketParent* p = static_cast(actor); p->Release(); return true; } PDNSRequestParent* NeckoParent::AllocPDNSRequestParent(const nsCString& aHost, const OriginAttributes& aOriginAttributes, const uint32_t& aFlags) { DNSRequestParent *p = new DNSRequestParent(); p->AddRef(); return p; } mozilla::ipc::IPCResult NeckoParent::RecvPDNSRequestConstructor(PDNSRequestParent* aActor, const nsCString& aHost, const OriginAttributes& aOriginAttributes, const uint32_t& aFlags) { static_cast(aActor)->DoAsyncResolve(aHost, aOriginAttributes, aFlags); return IPC_OK(); } bool NeckoParent::DeallocPDNSRequestParent(PDNSRequestParent* aParent) { DNSRequestParent *p = static_cast(aParent); p->Release(); return true; } mozilla::ipc::IPCResult NeckoParent::RecvSpeculativeConnect(const URIParams& aURI, const Principal& aPrincipal, const bool& aAnonymous) { nsCOMPtr speculator(gIOService); nsCOMPtr uri = DeserializeURI(aURI); nsCOMPtr principal(aPrincipal); if (uri && speculator) { if (aAnonymous) { speculator->SpeculativeAnonymousConnect2(uri, principal, nullptr); } else { speculator->SpeculativeConnect2(uri, principal, nullptr); } } return IPC_OK(); } mozilla::ipc::IPCResult NeckoParent::RecvHTMLDNSPrefetch(const nsString& hostname, const bool& isHttps, const OriginAttributes& aOriginAttributes, const uint16_t& flags) { nsHTMLDNSPrefetch::Prefetch(hostname, isHttps, aOriginAttributes, flags); return IPC_OK(); } mozilla::ipc::IPCResult NeckoParent::RecvCancelHTMLDNSPrefetch(const nsString& hostname, const bool& isHttps, const OriginAttributes& aOriginAttributes, const uint16_t& flags, const nsresult& reason) { nsHTMLDNSPrefetch::CancelPrefetch(hostname, isHttps, aOriginAttributes, flags, reason); return IPC_OK(); } PChannelDiverterParent* NeckoParent::AllocPChannelDiverterParent(const ChannelDiverterArgs& channel) { return new ChannelDiverterParent(); } mozilla::ipc::IPCResult NeckoParent::RecvPChannelDiverterConstructor(PChannelDiverterParent* actor, const ChannelDiverterArgs& channel) { auto parent = static_cast(actor); parent->Init(channel); return IPC_OK(); } bool NeckoParent::DeallocPChannelDiverterParent(PChannelDiverterParent* parent) { delete static_cast(parent); return true; } PTransportProviderParent* NeckoParent::AllocPTransportProviderParent() { RefPtr res = new TransportProviderParent(); return res.forget().take(); } bool NeckoParent::DeallocPTransportProviderParent(PTransportProviderParent* aActor) { RefPtr provider = dont_AddRef(static_cast(aActor)); return true; } namespace { std::map >& CallbackMap() { MOZ_ASSERT(NS_IsMainThread()); static std::map > sCallbackMap; return sCallbackMap; } } // namespace NS_IMPL_ISUPPORTS(NeckoParent::NestedFrameAuthPrompt, nsIAuthPrompt2) NeckoParent::NestedFrameAuthPrompt::NestedFrameAuthPrompt(PNeckoParent* aParent, TabId aNestedFrameId) : mNeckoParent(aParent) , mNestedFrameId(aNestedFrameId) {} NS_IMETHODIMP NeckoParent::NestedFrameAuthPrompt::AsyncPromptAuth( nsIChannel* aChannel, nsIAuthPromptCallback* callback, nsISupports*, uint32_t, nsIAuthInformation* aInfo, nsICancelable**) { static uint64_t callbackId = 0; MOZ_ASSERT(XRE_IsParentProcess()); nsCOMPtr uri; nsresult rv = aChannel->GetURI(getter_AddRefs(uri)); NS_ENSURE_SUCCESS(rv, rv); nsAutoCString spec; if (uri) { rv = uri->GetSpec(spec); NS_ENSURE_SUCCESS(rv, rv); } nsString realm; rv = aInfo->GetRealm(realm); NS_ENSURE_SUCCESS(rv, rv); callbackId++; if (mNeckoParent->SendAsyncAuthPromptForNestedFrame(mNestedFrameId, spec, realm, callbackId)) { CallbackMap()[callbackId] = callback; return NS_OK; } return NS_ERROR_FAILURE; } mozilla::ipc::IPCResult NeckoParent::RecvOnAuthAvailable(const uint64_t& aCallbackId, const nsString& aUser, const nsString& aPassword, const nsString& aDomain) { nsCOMPtr callback = CallbackMap()[aCallbackId]; if (!callback) { return IPC_OK(); } CallbackMap().erase(aCallbackId); RefPtr holder = new nsAuthInformationHolder(0, EmptyString(), EmptyCString()); holder->SetUsername(aUser); holder->SetPassword(aPassword); holder->SetDomain(aDomain); callback->OnAuthAvailable(nullptr, holder); return IPC_OK(); } mozilla::ipc::IPCResult NeckoParent::RecvOnAuthCancelled(const uint64_t& aCallbackId, const bool& aUserCancel) { nsCOMPtr callback = CallbackMap()[aCallbackId]; if (!callback) { return IPC_OK(); } CallbackMap().erase(aCallbackId); callback->OnAuthCancelled(nullptr, aUserCancel); return IPC_OK(); } /* Predictor Messages */ mozilla::ipc::IPCResult NeckoParent::RecvPredPredict(const ipc::OptionalURIParams& aTargetURI, const ipc::OptionalURIParams& aSourceURI, const uint32_t& aReason, const OriginAttributes& aOriginAttributes, const bool& hasVerifier) { nsCOMPtr targetURI = DeserializeURI(aTargetURI); nsCOMPtr sourceURI = DeserializeURI(aSourceURI); // Get the current predictor nsresult rv = NS_OK; nsCOMPtr predictor = do_GetService("@mozilla.org/network/predictor;1", &rv); NS_ENSURE_SUCCESS(rv, IPC_FAIL_NO_REASON(this)); nsCOMPtr verifier; if (hasVerifier) { verifier = do_QueryInterface(predictor); } predictor->PredictNative(targetURI, sourceURI, aReason, aOriginAttributes, verifier); return IPC_OK(); } mozilla::ipc::IPCResult NeckoParent::RecvPredLearn(const ipc::URIParams& aTargetURI, const ipc::OptionalURIParams& aSourceURI, const uint32_t& aReason, const OriginAttributes& aOriginAttributes) { nsCOMPtr targetURI = DeserializeURI(aTargetURI); nsCOMPtr sourceURI = DeserializeURI(aSourceURI); // Get the current predictor nsresult rv = NS_OK; nsCOMPtr predictor = do_GetService("@mozilla.org/network/predictor;1", &rv); NS_ENSURE_SUCCESS(rv, IPC_FAIL_NO_REASON(this)); predictor->LearnNative(targetURI, sourceURI, aReason, aOriginAttributes); return IPC_OK(); } mozilla::ipc::IPCResult NeckoParent::RecvPredReset() { // Get the current predictor nsresult rv = NS_OK; nsCOMPtr predictor = do_GetService("@mozilla.org/network/predictor;1", &rv); NS_ENSURE_SUCCESS(rv, IPC_FAIL_NO_REASON(this)); predictor->Reset(); return IPC_OK(); } mozilla::ipc::IPCResult NeckoParent::RecvRequestContextLoadBegin(const uint64_t& rcid) { nsCOMPtr rcsvc = do_GetService("@mozilla.org/network/request-context-service;1"); if (!rcsvc) { return IPC_OK(); } nsCOMPtr rc; rcsvc->GetRequestContext(rcid, getter_AddRefs(rc)); if (rc) { rc->BeginLoad(); } return IPC_OK(); } mozilla::ipc::IPCResult NeckoParent::RecvRequestContextAfterDOMContentLoaded(const uint64_t& rcid) { nsCOMPtr rcsvc = do_GetService("@mozilla.org/network/request-context-service;1"); if (!rcsvc) { return IPC_OK(); } nsCOMPtr rc; rcsvc->GetRequestContext(rcid, getter_AddRefs(rc)); if (rc) { rc->DOMContentLoaded(); } return IPC_OK(); } mozilla::ipc::IPCResult NeckoParent::RecvRemoveRequestContext(const uint64_t& rcid) { nsCOMPtr rcsvc = do_GetService("@mozilla.org/network/request-context-service;1"); if (!rcsvc) { return IPC_OK(); } rcsvc->RemoveRequestContext(rcid); return IPC_OK(); } mozilla::ipc::IPCResult NeckoParent::RecvGetExtensionStream(const URIParams& aURI, GetExtensionStreamResolver&& aResolve) { nsCOMPtr deserializedURI = DeserializeURI(aURI); if (!deserializedURI) { return IPC_FAIL_NO_REASON(this); } RefPtr 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 inputStream; bool terminateSender = true; auto inputStreamOrReason = ph->NewStream(deserializedURI, &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(const URIParams& aURI, GetExtensionFDResolver&& aResolve) { nsCOMPtr deserializedURI = DeserializeURI(aURI); if (!deserializedURI) { return IPC_FAIL_NO_REASON(this); } RefPtr 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(deserializedURI, &terminateSender, aResolve); if (result.isErr() && terminateSender) { return IPC_FAIL_NO_REASON(this); } if (result.isErr()) { FileDescriptor invalidFD; aResolve(invalidFD); } return IPC_OK(); } PTrackingDummyChannelParent* NeckoParent::AllocPTrackingDummyChannelParent(nsIURI* aURI, const OptionalLoadInfoArgs& aLoadInfo) { RefPtr c = new TrackingDummyChannelParent(); return c.forget().take(); } mozilla::ipc::IPCResult NeckoParent::RecvPTrackingDummyChannelConstructor(PTrackingDummyChannelParent* aActor, nsIURI* aURI, const OptionalLoadInfoArgs& aLoadInfo) { TrackingDummyChannelParent* p = static_cast(aActor); if (NS_WARN_IF(!aURI)) { return IPC_FAIL_NO_REASON(this); } nsCOMPtr loadInfo; nsresult rv = LoadInfoArgsToLoadInfo(aLoadInfo, getter_AddRefs(loadInfo)); if (NS_WARN_IF(NS_FAILED(rv)) || !loadInfo) { return IPC_FAIL_NO_REASON(this); } p->Init(aURI, loadInfo); return IPC_OK(); } bool NeckoParent::DeallocPTrackingDummyChannelParent(PTrackingDummyChannelParent* aActor) { RefPtr c = dont_AddRef(static_cast(aActor)); MOZ_ASSERT(c); return true; } } // namespace net } // namespace mozilla