Backed out changeset 8c746156d7c5 (bug 1908317) as requested by developer CLOSED...
[gecko.git] / netwerk / ipc / NeckoParent.cpp
blob509698c89989ee6cf3854297cf567306b55be80c
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set sw=2 ts=8 et tw=80 : */
4 /* This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 #include "nsHttp.h"
9 #include "mozilla/BasePrincipal.h"
10 #include "mozilla/Components.h"
11 #include "mozilla/ContentPrincipal.h"
12 #include "mozilla/ipc/IPCStreamUtils.h"
13 #include "mozilla/net/ExtensionProtocolHandler.h"
14 #include "mozilla/net/PageThumbProtocolHandler.h"
15 #include "mozilla/net/NeckoParent.h"
16 #include "mozilla/net/HttpChannelParent.h"
17 #include "mozilla/net/CookieServiceParent.h"
18 #include "mozilla/net/WebSocketChannelParent.h"
19 #include "mozilla/net/WebSocketEventListenerParent.h"
20 #include "mozilla/net/DataChannelParent.h"
21 #ifdef MOZ_WIDGET_GTK
22 # include "mozilla/net/GIOChannelParent.h"
23 #endif
24 #include "mozilla/net/DocumentChannelParent.h"
25 #include "mozilla/net/SimpleChannelParent.h"
26 #include "mozilla/net/AltDataOutputStreamParent.h"
27 #include "mozilla/Unused.h"
28 #include "mozilla/net/FileChannelParent.h"
29 #include "mozilla/net/DNSRequestParent.h"
30 #include "mozilla/net/IPCTransportProvider.h"
31 #include "mozilla/net/RemoteStreamGetter.h"
32 #include "mozilla/net/RequestContextService.h"
33 #include "mozilla/net/SocketProcessParent.h"
34 #include "mozilla/net/PSocketProcessBridgeParent.h"
35 #ifdef MOZ_WEBRTC
36 # include "mozilla/net/StunAddrsRequestParent.h"
37 # include "mozilla/net/WebrtcTCPSocketParent.h"
38 #endif
39 #include "mozilla/dom/ContentParent.h"
40 #include "mozilla/dom/BrowserParent.h"
41 #include "mozilla/dom/MaybeDiscarded.h"
42 #include "mozilla/dom/network/TCPSocketParent.h"
43 #include "mozilla/dom/network/TCPServerSocketParent.h"
44 #include "mozilla/dom/network/UDPSocketParent.h"
45 #ifdef MOZ_PLACES
46 # include "mozilla/places/PageIconProtocolHandler.h"
47 #endif
48 #include "mozilla/LoadContext.h"
49 #include "mozilla/MozPromise.h"
50 #include "nsPrintfCString.h"
51 #include "mozilla/dom/HTMLDNSPrefetch.h"
52 #include "nsEscape.h"
53 #include "SerializedLoadContext.h"
54 #include "nsAuthInformationHolder.h"
55 #include "nsINetworkPredictor.h"
56 #include "nsINetworkPredictorVerifier.h"
57 #include "nsISpeculativeConnect.h"
58 #include "nsHttpHandler.h"
59 #include "nsNetUtil.h"
60 #include "nsIOService.h"
62 using IPC::SerializedLoadContext;
63 using mozilla::dom::BrowserParent;
64 using mozilla::dom::ContentParent;
65 using mozilla::dom::TCPServerSocketParent;
66 using mozilla::dom::TCPSocketParent;
67 using mozilla::dom::UDPSocketParent;
68 using mozilla::ipc::LoadInfoArgsToLoadInfo;
69 using mozilla::ipc::PrincipalInfo;
70 #ifdef MOZ_PLACES
71 using mozilla::places::PageIconProtocolHandler;
72 #endif
74 namespace mozilla {
75 namespace net {
77 // C++ file contents
78 NeckoParent::NeckoParent() : mSocketProcessBridgeInited(false) {
79 // Init HTTP protocol handler now since we need atomTable up and running very
80 // early (IPDL argument handling for PHttpChannel constructor needs it) so
81 // normal init (during 1st Http channel request) isn't early enough.
82 nsCOMPtr<nsIProtocolHandler> proto =
83 do_GetService("@mozilla.org/network/protocol;1?name=http");
86 static PBOverrideStatus PBOverrideStatusFromLoadContext(
87 const SerializedLoadContext& aSerialized) {
88 if (!aSerialized.IsNotNull() && aSerialized.IsPrivateBitValid()) {
89 return aSerialized.mOriginAttributes.IsPrivateBrowsing()
90 ? kPBOverride_Private
91 : kPBOverride_NotPrivate;
93 return kPBOverride_Unset;
96 static already_AddRefed<nsIPrincipal> GetRequestingPrincipal(
97 const LoadInfoArgs& aLoadInfoArgs) {
98 const Maybe<PrincipalInfo>& optionalPrincipalInfo =
99 aLoadInfoArgs.requestingPrincipalInfo();
101 if (optionalPrincipalInfo.isNothing()) {
102 return nullptr;
105 const PrincipalInfo& principalInfo = optionalPrincipalInfo.ref();
107 auto principalOrErr = PrincipalInfoToPrincipal(principalInfo);
108 return principalOrErr.isOk() ? principalOrErr.unwrap().forget() : nullptr;
111 static already_AddRefed<nsIPrincipal> GetRequestingPrincipal(
112 const HttpChannelCreationArgs& aArgs) {
113 if (aArgs.type() != HttpChannelCreationArgs::THttpChannelOpenArgs) {
114 return nullptr;
117 const HttpChannelOpenArgs& args = aArgs.get_HttpChannelOpenArgs();
118 return GetRequestingPrincipal(args.loadInfo());
121 const char* NeckoParent::GetValidatedOriginAttributes(
122 const SerializedLoadContext& aSerialized, PContentParent* aContent,
123 nsIPrincipal* aRequestingPrincipal, OriginAttributes& aAttrs) {
124 if (!aSerialized.IsNotNull()) {
125 // If serialized is null, we cannot validate anything. We have to assume
126 // that this requests comes from a SystemPrincipal.
127 aAttrs = OriginAttributes();
128 } else {
129 aAttrs = aSerialized.mOriginAttributes;
131 return nullptr;
134 const char* NeckoParent::CreateChannelLoadContext(
135 PBrowserParent* aBrowser, PContentParent* aContent,
136 const SerializedLoadContext& aSerialized,
137 nsIPrincipal* aRequestingPrincipal, nsCOMPtr<nsILoadContext>& aResult) {
138 OriginAttributes attrs;
139 const char* error = GetValidatedOriginAttributes(aSerialized, aContent,
140 aRequestingPrincipal, attrs);
141 if (error) {
142 return error;
145 // if !UsingNeckoIPCSecurity(), we may not have a LoadContext to set. This is
146 // the common case for most xpcshell tests.
147 if (aSerialized.IsNotNull()) {
148 attrs.SyncAttributesWithPrivateBrowsing(
149 aSerialized.mOriginAttributes.IsPrivateBrowsing());
151 RefPtr<BrowserParent> browserParent = BrowserParent::GetFrom(aBrowser);
152 dom::Element* topFrameElement = nullptr;
153 if (browserParent) {
154 topFrameElement = browserParent->GetOwnerElement();
156 aResult = new LoadContext(aSerialized, topFrameElement, attrs);
159 return nullptr;
162 void NeckoParent::ActorDestroy(ActorDestroyReason aWhy) {
163 // Nothing needed here. Called right before destructor since this is a
164 // non-refcounted class.
167 already_AddRefed<PHttpChannelParent> NeckoParent::AllocPHttpChannelParent(
168 PBrowserParent* aBrowser, const SerializedLoadContext& aSerialized,
169 const HttpChannelCreationArgs& aOpenArgs) {
170 nsCOMPtr<nsIPrincipal> requestingPrincipal =
171 GetRequestingPrincipal(aOpenArgs);
173 nsCOMPtr<nsILoadContext> loadContext;
174 const char* error = CreateChannelLoadContext(
175 aBrowser, Manager(), aSerialized, requestingPrincipal, loadContext);
176 if (error) {
177 printf_stderr(
178 "NeckoParent::AllocPHttpChannelParent: "
179 "FATAL error: %s: KILLING CHILD PROCESS\n",
180 error);
181 return nullptr;
183 PBOverrideStatus overrideStatus =
184 PBOverrideStatusFromLoadContext(aSerialized);
185 RefPtr<HttpChannelParent> p = new HttpChannelParent(
186 BrowserParent::GetFrom(aBrowser), loadContext, overrideStatus);
187 return p.forget();
190 mozilla::ipc::IPCResult NeckoParent::RecvPHttpChannelConstructor(
191 PHttpChannelParent* aActor, PBrowserParent* aBrowser,
192 const SerializedLoadContext& aSerialized,
193 const HttpChannelCreationArgs& aOpenArgs) {
194 HttpChannelParent* p = static_cast<HttpChannelParent*>(aActor);
195 if (!p->Init(aOpenArgs)) {
196 return IPC_FAIL_NO_REASON(this);
198 return IPC_OK();
201 PStunAddrsRequestParent* NeckoParent::AllocPStunAddrsRequestParent() {
202 #ifdef MOZ_WEBRTC
203 StunAddrsRequestParent* p = new StunAddrsRequestParent();
204 p->AddRef();
205 return p;
206 #else
207 return nullptr;
208 #endif
211 bool NeckoParent::DeallocPStunAddrsRequestParent(
212 PStunAddrsRequestParent* aActor) {
213 #ifdef MOZ_WEBRTC
214 StunAddrsRequestParent* p = static_cast<StunAddrsRequestParent*>(aActor);
215 p->Release();
216 #endif
217 return true;
220 PWebrtcTCPSocketParent* NeckoParent::AllocPWebrtcTCPSocketParent(
221 const Maybe<TabId>& aTabId) {
222 #ifdef MOZ_WEBRTC
223 WebrtcTCPSocketParent* parent = new WebrtcTCPSocketParent(aTabId);
224 parent->AddRef();
225 return parent;
226 #else
227 return nullptr;
228 #endif
231 bool NeckoParent::DeallocPWebrtcTCPSocketParent(
232 PWebrtcTCPSocketParent* aActor) {
233 #ifdef MOZ_WEBRTC
234 WebrtcTCPSocketParent* parent = static_cast<WebrtcTCPSocketParent*>(aActor);
235 parent->Release();
236 #endif
237 return true;
240 PAltDataOutputStreamParent* NeckoParent::AllocPAltDataOutputStreamParent(
241 const nsACString& type, const int64_t& predictedSize,
242 PHttpChannelParent* channel) {
243 HttpChannelParent* chan = static_cast<HttpChannelParent*>(channel);
244 nsCOMPtr<nsIAsyncOutputStream> stream;
245 nsresult rv = chan->OpenAlternativeOutputStream(type, predictedSize,
246 getter_AddRefs(stream));
247 AltDataOutputStreamParent* parent = new AltDataOutputStreamParent(stream);
248 parent->AddRef();
249 // If the return value was not NS_OK, the error code will be sent
250 // asynchronously to the child, after receiving the first message.
251 parent->SetError(rv);
252 return parent;
255 bool NeckoParent::DeallocPAltDataOutputStreamParent(
256 PAltDataOutputStreamParent* aActor) {
257 AltDataOutputStreamParent* parent =
258 static_cast<AltDataOutputStreamParent*>(aActor);
259 parent->Release();
260 return true;
263 already_AddRefed<PDocumentChannelParent>
264 NeckoParent::AllocPDocumentChannelParent(
265 const dom::MaybeDiscarded<dom::BrowsingContext>& aContext,
266 const DocumentChannelCreationArgs& args) {
267 RefPtr<DocumentChannelParent> p = new DocumentChannelParent();
268 return p.forget();
271 mozilla::ipc::IPCResult NeckoParent::RecvPDocumentChannelConstructor(
272 PDocumentChannelParent* aActor,
273 const dom::MaybeDiscarded<dom::BrowsingContext>& aContext,
274 const DocumentChannelCreationArgs& aArgs) {
275 DocumentChannelParent* p = static_cast<DocumentChannelParent*>(aActor);
277 if (aContext.IsNullOrDiscarded()) {
278 Unused << p->SendFailedAsyncOpen(NS_ERROR_FAILURE);
279 return IPC_OK();
282 if (!p->Init(aContext.get_canonical(), aArgs)) {
283 return IPC_FAIL(this, "Couldn't initialize DocumentChannel");
286 return IPC_OK();
289 PCookieServiceParent* NeckoParent::AllocPCookieServiceParent() {
290 return new CookieServiceParent();
293 bool NeckoParent::DeallocPCookieServiceParent(PCookieServiceParent* cs) {
294 delete cs;
295 return true;
298 PWebSocketParent* NeckoParent::AllocPWebSocketParent(
299 PBrowserParent* browser, const SerializedLoadContext& serialized,
300 const uint32_t& aSerial) {
301 nsCOMPtr<nsILoadContext> loadContext;
302 const char* error = CreateChannelLoadContext(browser, Manager(), serialized,
303 nullptr, loadContext);
304 if (error) {
305 printf_stderr(
306 "NeckoParent::AllocPWebSocketParent: "
307 "FATAL error: %s: KILLING CHILD PROCESS\n",
308 error);
309 return nullptr;
312 RefPtr<BrowserParent> browserParent = BrowserParent::GetFrom(browser);
313 PBOverrideStatus overrideStatus = PBOverrideStatusFromLoadContext(serialized);
314 WebSocketChannelParent* p = new WebSocketChannelParent(
315 browserParent, loadContext, overrideStatus, aSerial);
316 p->AddRef();
317 return p;
320 bool NeckoParent::DeallocPWebSocketParent(PWebSocketParent* actor) {
321 WebSocketChannelParent* p = static_cast<WebSocketChannelParent*>(actor);
322 p->Release();
323 return true;
326 PWebSocketEventListenerParent* NeckoParent::AllocPWebSocketEventListenerParent(
327 const uint64_t& aInnerWindowID) {
328 RefPtr<WebSocketEventListenerParent> c =
329 new WebSocketEventListenerParent(aInnerWindowID);
330 return c.forget().take();
333 bool NeckoParent::DeallocPWebSocketEventListenerParent(
334 PWebSocketEventListenerParent* aActor) {
335 RefPtr<WebSocketEventListenerParent> c =
336 dont_AddRef(static_cast<WebSocketEventListenerParent*>(aActor));
337 MOZ_ASSERT(c);
338 return true;
341 already_AddRefed<PDataChannelParent> NeckoParent::AllocPDataChannelParent(
342 const uint32_t& channelId) {
343 RefPtr<DataChannelParent> p = new DataChannelParent();
344 return p.forget();
347 mozilla::ipc::IPCResult NeckoParent::RecvPDataChannelConstructor(
348 PDataChannelParent* actor, const uint32_t& channelId) {
349 DataChannelParent* p = static_cast<DataChannelParent*>(actor);
350 DebugOnly<bool> rv = p->Init(channelId);
351 MOZ_ASSERT(rv);
352 return IPC_OK();
355 #ifdef MOZ_WIDGET_GTK
356 static already_AddRefed<nsIPrincipal> GetRequestingPrincipal(
357 const GIOChannelCreationArgs& aArgs) {
358 if (aArgs.type() != GIOChannelCreationArgs::TGIOChannelOpenArgs) {
359 return nullptr;
362 const GIOChannelOpenArgs& args = aArgs.get_GIOChannelOpenArgs();
363 return GetRequestingPrincipal(args.loadInfo());
366 PGIOChannelParent* NeckoParent::AllocPGIOChannelParent(
367 PBrowserParent* aBrowser, const SerializedLoadContext& aSerialized,
368 const GIOChannelCreationArgs& aOpenArgs) {
369 nsCOMPtr<nsIPrincipal> requestingPrincipal =
370 GetRequestingPrincipal(aOpenArgs);
372 nsCOMPtr<nsILoadContext> loadContext;
373 const char* error = CreateChannelLoadContext(
374 aBrowser, Manager(), aSerialized, requestingPrincipal, loadContext);
375 if (error) {
376 printf_stderr(
377 "NeckoParent::AllocPGIOChannelParent: "
378 "FATAL error: %s: KILLING CHILD PROCESS\n",
379 error);
380 return nullptr;
382 PBOverrideStatus overrideStatus =
383 PBOverrideStatusFromLoadContext(aSerialized);
384 GIOChannelParent* p = new GIOChannelParent(BrowserParent::GetFrom(aBrowser),
385 loadContext, overrideStatus);
386 p->AddRef();
387 return p;
390 bool NeckoParent::DeallocPGIOChannelParent(PGIOChannelParent* channel) {
391 GIOChannelParent* p = static_cast<GIOChannelParent*>(channel);
392 p->Release();
393 return true;
396 mozilla::ipc::IPCResult NeckoParent::RecvPGIOChannelConstructor(
397 PGIOChannelParent* actor, PBrowserParent* aBrowser,
398 const SerializedLoadContext& aSerialized,
399 const GIOChannelCreationArgs& aOpenArgs) {
400 GIOChannelParent* p = static_cast<GIOChannelParent*>(actor);
401 DebugOnly<bool> rv = p->Init(aOpenArgs);
402 MOZ_ASSERT(rv);
403 return IPC_OK();
405 #endif
407 PSimpleChannelParent* NeckoParent::AllocPSimpleChannelParent(
408 const uint32_t& channelId) {
409 RefPtr<SimpleChannelParent> p = new SimpleChannelParent();
410 return p.forget().take();
413 bool NeckoParent::DeallocPSimpleChannelParent(PSimpleChannelParent* actor) {
414 RefPtr<SimpleChannelParent> p =
415 dont_AddRef(actor).downcast<SimpleChannelParent>();
416 return true;
419 mozilla::ipc::IPCResult NeckoParent::RecvPSimpleChannelConstructor(
420 PSimpleChannelParent* actor, const uint32_t& channelId) {
421 SimpleChannelParent* p = static_cast<SimpleChannelParent*>(actor);
422 MOZ_ALWAYS_TRUE(p->Init(channelId));
423 return IPC_OK();
426 already_AddRefed<PFileChannelParent> NeckoParent::AllocPFileChannelParent(
427 const uint32_t& channelId) {
428 RefPtr<FileChannelParent> p = new FileChannelParent();
429 return p.forget();
432 mozilla::ipc::IPCResult NeckoParent::RecvPFileChannelConstructor(
433 PFileChannelParent* actor, const uint32_t& channelId) {
434 FileChannelParent* p = static_cast<FileChannelParent*>(actor);
435 DebugOnly<bool> rv = p->Init(channelId);
436 MOZ_ASSERT(rv);
437 return IPC_OK();
440 PTCPSocketParent* NeckoParent::AllocPTCPSocketParent(
441 const nsAString& /* host */, const uint16_t& /* port */) {
442 // We actually don't need host/port to construct a TCPSocketParent since
443 // TCPSocketParent will maintain an internal nsIDOMTCPSocket instance which
444 // can be delegated to get the host/port.
445 TCPSocketParent* p = new TCPSocketParent();
446 p->AddIPDLReference();
447 return p;
450 bool NeckoParent::DeallocPTCPSocketParent(PTCPSocketParent* actor) {
451 TCPSocketParent* p = static_cast<TCPSocketParent*>(actor);
452 p->ReleaseIPDLReference();
453 return true;
456 PTCPServerSocketParent* NeckoParent::AllocPTCPServerSocketParent(
457 const uint16_t& aLocalPort, const uint16_t& aBacklog,
458 const bool& aUseArrayBuffers) {
459 TCPServerSocketParent* p =
460 new TCPServerSocketParent(this, aLocalPort, aBacklog, aUseArrayBuffers);
461 p->AddIPDLReference();
462 return p;
465 mozilla::ipc::IPCResult NeckoParent::RecvPTCPServerSocketConstructor(
466 PTCPServerSocketParent* aActor, const uint16_t& aLocalPort,
467 const uint16_t& aBacklog, const bool& aUseArrayBuffers) {
468 static_cast<TCPServerSocketParent*>(aActor)->Init();
469 return IPC_OK();
472 bool NeckoParent::DeallocPTCPServerSocketParent(PTCPServerSocketParent* actor) {
473 TCPServerSocketParent* p = static_cast<TCPServerSocketParent*>(actor);
474 p->ReleaseIPDLReference();
475 return true;
478 PUDPSocketParent* NeckoParent::AllocPUDPSocketParent(
479 nsIPrincipal* /* unused */, const nsACString& /* unused */) {
480 RefPtr<UDPSocketParent> p = new UDPSocketParent(this);
482 return p.forget().take();
485 mozilla::ipc::IPCResult NeckoParent::RecvPUDPSocketConstructor(
486 PUDPSocketParent* aActor, nsIPrincipal* aPrincipal,
487 const nsACString& aFilter) {
488 if (!static_cast<UDPSocketParent*>(aActor)->Init(aPrincipal, aFilter)) {
489 return IPC_FAIL_NO_REASON(this);
491 return IPC_OK();
494 bool NeckoParent::DeallocPUDPSocketParent(PUDPSocketParent* actor) {
495 UDPSocketParent* p = static_cast<UDPSocketParent*>(actor);
496 p->Release();
497 return true;
500 already_AddRefed<PDNSRequestParent> NeckoParent::AllocPDNSRequestParent(
501 const nsACString& aHost, const nsACString& aTrrServer, const int32_t& aPort,
502 const uint16_t& aType, const OriginAttributes& aOriginAttributes,
503 const nsIDNSService::DNSFlags& aFlags) {
504 RefPtr<DNSRequestHandler> handler = new DNSRequestHandler();
505 RefPtr<DNSRequestParent> actor = new DNSRequestParent(handler);
506 return actor.forget();
509 mozilla::ipc::IPCResult NeckoParent::RecvPDNSRequestConstructor(
510 PDNSRequestParent* aActor, const nsACString& aHost,
511 const nsACString& aTrrServer, const int32_t& aPort, const uint16_t& aType,
512 const OriginAttributes& aOriginAttributes,
513 const nsIDNSService::DNSFlags& aFlags) {
514 RefPtr<DNSRequestParent> actor = static_cast<DNSRequestParent*>(aActor);
515 RefPtr<DNSRequestHandler> handler =
516 actor->GetDNSRequest()->AsDNSRequestHandler();
517 handler->DoAsyncResolve(aHost, aTrrServer, aPort, aType, aOriginAttributes,
518 aFlags);
519 return IPC_OK();
522 mozilla::ipc::IPCResult NeckoParent::RecvSpeculativeConnect(
523 nsIURI* aURI, nsIPrincipal* aPrincipal,
524 Maybe<OriginAttributes>&& aOriginAttributes, const bool& aAnonymous) {
525 nsCOMPtr<nsISpeculativeConnect> speculator(gIOService);
526 nsCOMPtr<nsIPrincipal> principal(aPrincipal);
527 if (!aURI) {
528 return IPC_FAIL(this, "aURI must not be null");
530 if (aURI && speculator) {
531 if (aOriginAttributes) {
532 speculator->SpeculativeConnectWithOriginAttributesNative(
533 aURI, std::move(aOriginAttributes.ref()), nullptr, aAnonymous);
534 } else {
535 speculator->SpeculativeConnect(aURI, principal, nullptr, aAnonymous);
538 return IPC_OK();
541 mozilla::ipc::IPCResult NeckoParent::RecvHTMLDNSPrefetch(
542 const nsAString& hostname, const bool& isHttps,
543 const OriginAttributes& aOriginAttributes,
544 const nsIDNSService::DNSFlags& flags) {
545 dom::HTMLDNSPrefetch::Prefetch(hostname, isHttps, aOriginAttributes, flags);
546 return IPC_OK();
549 mozilla::ipc::IPCResult NeckoParent::RecvCancelHTMLDNSPrefetch(
550 const nsAString& hostname, const bool& isHttps,
551 const OriginAttributes& aOriginAttributes,
552 const nsIDNSService::DNSFlags& flags, const nsresult& reason) {
553 dom::HTMLDNSPrefetch::CancelPrefetch(hostname, isHttps, aOriginAttributes,
554 flags, reason);
555 return IPC_OK();
558 PTransportProviderParent* NeckoParent::AllocPTransportProviderParent() {
559 RefPtr<TransportProviderParent> res = new TransportProviderParent();
560 return res.forget().take();
563 bool NeckoParent::DeallocPTransportProviderParent(
564 PTransportProviderParent* aActor) {
565 RefPtr<TransportProviderParent> provider =
566 dont_AddRef(static_cast<TransportProviderParent*>(aActor));
567 return true;
570 /* Predictor Messages */
571 mozilla::ipc::IPCResult NeckoParent::RecvPredPredict(
572 nsIURI* aTargetURI, nsIURI* aSourceURI, const uint32_t& aReason,
573 const OriginAttributes& aOriginAttributes, const bool& hasVerifier) {
574 // Get the current predictor
575 nsresult rv = NS_OK;
576 nsCOMPtr<nsINetworkPredictor> predictor;
577 predictor = mozilla::components::Predictor::Service(&rv);
578 NS_ENSURE_SUCCESS(rv, IPC_OK());
580 nsCOMPtr<nsINetworkPredictorVerifier> verifier;
581 if (hasVerifier) {
582 verifier = do_QueryInterface(predictor);
584 predictor->PredictNative(aTargetURI, aSourceURI, aReason, aOriginAttributes,
585 verifier);
586 return IPC_OK();
589 mozilla::ipc::IPCResult NeckoParent::RecvPredLearn(
590 nsIURI* aTargetURI, nsIURI* aSourceURI, const uint32_t& aReason,
591 const OriginAttributes& aOriginAttributes) {
592 // Get the current predictor
593 nsresult rv = NS_OK;
594 nsCOMPtr<nsINetworkPredictor> predictor;
595 predictor = mozilla::components::Predictor::Service(&rv);
596 NS_ENSURE_SUCCESS(rv, IPC_OK());
598 predictor->LearnNative(aTargetURI, aSourceURI, aReason, aOriginAttributes);
599 return IPC_OK();
602 mozilla::ipc::IPCResult NeckoParent::RecvPredReset() {
603 // Get the current predictor
604 nsresult rv = NS_OK;
605 nsCOMPtr<nsINetworkPredictor> predictor;
606 predictor = mozilla::components::Predictor::Service(&rv);
607 NS_ENSURE_SUCCESS(rv, IPC_OK());
609 predictor->Reset();
610 return IPC_OK();
613 mozilla::ipc::IPCResult NeckoParent::RecvRequestContextLoadBegin(
614 const uint64_t& rcid) {
615 nsCOMPtr<nsIRequestContextService> rcsvc =
616 RequestContextService::GetOrCreate();
617 if (!rcsvc) {
618 return IPC_OK();
620 nsCOMPtr<nsIRequestContext> rc;
621 rcsvc->GetRequestContext(rcid, getter_AddRefs(rc));
622 if (rc) {
623 rc->BeginLoad();
626 return IPC_OK();
629 mozilla::ipc::IPCResult NeckoParent::RecvRequestContextAfterDOMContentLoaded(
630 const uint64_t& rcid) {
631 nsCOMPtr<nsIRequestContextService> rcsvc =
632 RequestContextService::GetOrCreate();
633 if (!rcsvc) {
634 return IPC_OK();
636 nsCOMPtr<nsIRequestContext> rc;
637 rcsvc->GetRequestContext(rcid, getter_AddRefs(rc));
638 if (rc) {
639 rc->DOMContentLoaded();
642 return IPC_OK();
645 mozilla::ipc::IPCResult NeckoParent::RecvRemoveRequestContext(
646 const uint64_t& rcid) {
647 nsCOMPtr<nsIRequestContextService> rcsvc =
648 RequestContextService::GetOrCreate();
649 if (!rcsvc) {
650 return IPC_OK();
653 rcsvc->RemoveRequestContext(rcid);
655 return IPC_OK();
658 mozilla::ipc::IPCResult NeckoParent::RecvGetExtensionStream(
659 nsIURI* aURI, GetExtensionStreamResolver&& aResolve) {
660 if (!aURI) {
661 return IPC_FAIL(this, "aURI must not be null");
664 RefPtr<ExtensionProtocolHandler> ph(ExtensionProtocolHandler::GetSingleton());
665 MOZ_ASSERT(ph);
667 // Ask the ExtensionProtocolHandler to give us a new input stream for
668 // this URI. The request comes from an ExtensionProtocolHandler in the
669 // child process, but is not guaranteed to be a valid moz-extension URI,
670 // and not guaranteed to represent a resource that the child should be
671 // allowed to access. The ExtensionProtocolHandler is responsible for
672 // validating the request. Specifically, only URI's for local files that
673 // an extension is allowed to access via moz-extension URI's should be
674 // accepted.
675 nsCOMPtr<nsIInputStream> inputStream;
676 bool terminateSender = true;
677 auto inputStreamOrReason = ph->NewStream(aURI, &terminateSender);
678 if (inputStreamOrReason.isOk()) {
679 inputStream = inputStreamOrReason.unwrap();
682 // If NewStream failed, we send back an invalid stream to the child so
683 // it can handle the error. MozPromise rejection is reserved for channel
684 // errors/disconnects.
685 aResolve(inputStream);
687 if (terminateSender) {
688 return IPC_FAIL_NO_REASON(this);
690 return IPC_OK();
693 mozilla::ipc::IPCResult NeckoParent::RecvGetExtensionFD(
694 nsIURI* aURI, GetExtensionFDResolver&& aResolve) {
695 if (!aURI) {
696 return IPC_FAIL(this, "aURI must not be null");
699 RefPtr<ExtensionProtocolHandler> ph(ExtensionProtocolHandler::GetSingleton());
700 MOZ_ASSERT(ph);
702 // Ask the ExtensionProtocolHandler to give us a new input stream for
703 // this URI. The request comes from an ExtensionProtocolHandler in the
704 // child process, but is not guaranteed to be a valid moz-extension URI,
705 // and not guaranteed to represent a resource that the child should be
706 // allowed to access. The ExtensionProtocolHandler is responsible for
707 // validating the request. Specifically, only URI's for local files that
708 // an extension is allowed to access via moz-extension URI's should be
709 // accepted.
710 bool terminateSender = true;
711 auto result = ph->NewFD(aURI, &terminateSender, aResolve);
713 if (result.isErr() && terminateSender) {
714 return IPC_FAIL_NO_REASON(this);
717 if (result.isErr()) {
718 FileDescriptor invalidFD;
719 aResolve(invalidFD);
722 return IPC_OK();
725 mozilla::ipc::IPCResult NeckoParent::RecvInitSocketProcessBridge(
726 InitSocketProcessBridgeResolver&& aResolver) {
727 MOZ_ASSERT(NS_IsMainThread());
729 // Initing the socket process bridge must be async here in order to
730 // wait for the socket process launch before executing.
731 auto task = [self = RefPtr{this}, resolver = std::move(aResolver)]() {
732 // The content process might be already destroyed.
733 if (!self->CanSend()) {
734 return;
737 Endpoint<PSocketProcessBridgeChild> invalidEndpoint;
738 if (NS_WARN_IF(self->mSocketProcessBridgeInited)) {
739 resolver(std::move(invalidEndpoint));
740 return;
743 SocketProcessParent* parent = SocketProcessParent::GetSingleton();
744 if (NS_WARN_IF(!parent)) {
745 resolver(std::move(invalidEndpoint));
746 return;
749 Endpoint<PSocketProcessBridgeParent> parentEndpoint;
750 Endpoint<PSocketProcessBridgeChild> childEndpoint;
751 if (NS_WARN_IF(NS_FAILED(PSocketProcessBridge::CreateEndpoints(
752 parent->OtherPid(), self->Manager()->OtherPid(), &parentEndpoint,
753 &childEndpoint)))) {
754 resolver(std::move(invalidEndpoint));
755 return;
758 if (NS_WARN_IF(!parent->SendInitSocketProcessBridgeParent(
759 self->Manager()->OtherPid(), std::move(parentEndpoint)))) {
760 resolver(std::move(invalidEndpoint));
761 return;
764 resolver(std::move(childEndpoint));
765 self->mSocketProcessBridgeInited = true;
767 gIOService->CallOrWaitForSocketProcess(std::move(task));
769 return IPC_OK();
772 mozilla::ipc::IPCResult NeckoParent::RecvResetSocketProcessBridge() {
773 // SendResetSocketProcessBridge is called from
774 // SocketProcessBridgeChild::ActorDestroy if the socket process
775 // crashes. This is necessary in order to properly initialize the
776 // restarted socket process.
777 mSocketProcessBridgeInited = false;
778 return IPC_OK();
781 mozilla::ipc::IPCResult NeckoParent::RecvEnsureHSTSData(
782 EnsureHSTSDataResolver&& aResolver) {
783 auto callback = [aResolver{std::move(aResolver)}](bool aResult) {
784 aResolver(aResult);
786 RefPtr<HSTSDataCallbackWrapper> wrapper =
787 new HSTSDataCallbackWrapper(std::move(callback));
788 gHttpHandler->EnsureHSTSDataReadyNative(wrapper);
789 return IPC_OK();
792 mozilla::ipc::IPCResult NeckoParent::RecvGetPageThumbStream(
793 nsIURI* aURI, const LoadInfoArgs& aLoadInfoArgs,
794 GetPageThumbStreamResolver&& aResolver) {
795 // Only the privileged about content process is allowed to access
796 // things over the moz-page-thumb protocol. Any other content process
797 // that tries to send this should have been blocked via the
798 // ScriptSecurityManager, but if somehow the process has been tricked into
799 // sending this message, we send IPC_FAIL in order to crash that
800 // likely-compromised content process.
801 if (static_cast<ContentParent*>(Manager())->GetRemoteType() !=
802 PRIVILEGEDABOUT_REMOTE_TYPE) {
803 return IPC_FAIL(this, "Wrong process type");
806 RefPtr<PageThumbProtocolHandler> ph(PageThumbProtocolHandler::GetSingleton());
807 MOZ_ASSERT(ph);
809 // Ask the PageThumbProtocolHandler to give us a new input stream for
810 // this URI. The request comes from a PageThumbProtocolHandler in the
811 // child process, but is not guaranteed to be a valid moz-page-thumb URI,
812 // and not guaranteed to represent a resource that the child should be
813 // allowed to access. The PageThumbProtocolHandler is responsible for
814 // validating the request.
815 nsCOMPtr<nsIInputStream> inputStream;
816 bool terminateSender = true;
817 auto inputStreamPromise = ph->NewStream(aURI, &terminateSender);
819 if (terminateSender) {
820 return IPC_FAIL(this, "Malformed moz-page-thumb request");
823 inputStreamPromise->Then(
824 GetMainThreadSerialEventTarget(), __func__,
825 [aResolver](const RemoteStreamInfo& aInfo) { aResolver(Some(aInfo)); },
826 [aResolver](nsresult aRv) {
827 // If NewStream failed, we send back an invalid stream to the child so
828 // it can handle the error. MozPromise rejection is reserved for channel
829 // errors/disconnects.
830 Unused << NS_WARN_IF(NS_FAILED(aRv));
831 aResolver(Nothing());
834 return IPC_OK();
837 mozilla::ipc::IPCResult NeckoParent::RecvGetPageIconStream(
838 nsIURI* aURI, const LoadInfoArgs& aLoadInfoArgs,
839 GetPageIconStreamResolver&& aResolver) {
840 #ifdef MOZ_PLACES
841 const nsACString& remoteType =
842 ContentParent::Cast(Manager())->GetRemoteType();
844 // Only the privileged about content process is allowed to access
845 // things over the page-icon protocol. Any other content process
846 // that tries to send this should have been blocked via the
847 // ScriptSecurityManager, but if somehow the process has been tricked into
848 // sending this message, we send IPC_FAIL in order to crash that
849 // likely-compromised content process.
850 if (remoteType != PRIVILEGEDABOUT_REMOTE_TYPE) {
851 return IPC_FAIL(this, "Wrong process type");
854 nsCOMPtr<nsILoadInfo> loadInfo;
855 nsresult rv = mozilla::ipc::LoadInfoArgsToLoadInfo(aLoadInfoArgs, remoteType,
856 getter_AddRefs(loadInfo));
857 if (NS_FAILED(rv)) {
858 return IPC_FAIL(this, "Page-icon request must include loadInfo");
861 RefPtr<PageIconProtocolHandler> ph(PageIconProtocolHandler::GetSingleton());
862 MOZ_ASSERT(ph);
864 nsCOMPtr<nsIInputStream> inputStream;
865 bool terminateSender = true;
866 auto inputStreamPromise = ph->NewStream(aURI, loadInfo, &terminateSender);
868 if (terminateSender) {
869 return IPC_FAIL(this, "Malformed page-icon request");
872 inputStreamPromise->Then(
873 GetMainThreadSerialEventTarget(), __func__,
874 [aResolver](const RemoteStreamInfo& aInfo) { aResolver(Some(aInfo)); },
875 [aResolver](nsresult aRv) {
876 // If NewStream failed, we send back an invalid stream to the child so
877 // it can handle the error. MozPromise rejection is reserved for channel
878 // errors/disconnects.
879 Unused << NS_WARN_IF(NS_FAILED(aRv));
880 aResolver(Nothing());
883 return IPC_OK();
884 #else
885 return IPC_FAIL(this, "page-icon: protocol unavailable");
886 #endif
889 } // namespace net
890 } // namespace mozilla